我正在尝试将Node.js用作我的Rails应用程序的JavaScript运行时。我在Ubuntu 12.0.4上使用带有Nginx的Phusion Passenger模块作为我的Web服务器。每次我访问我的Rails应用程序时,我都会看到一个错误页面,该页面似乎是从Passenger生成的,表明ExecJS无法找到JavaScript运行时。我在这里看过很多帖子,或者建议您安装Node - 我已经通过sudo apt-get install node
完成了 - 或者建议在你的Gemfile中使用therubyracer + execjs。后一个解决方案实际上确实有效,但我更愿意使用Node,特别是因为Heroku has stated他们不鼓励使用therubyracer,因为它使用了“非常大量的内存”。
我遇到了tutorial,这表明我的网络服务器运行的用户可能没有Node的路径。我通过运行sudo -u www-data which node
检查了这一点,然后返回/usr/bin/node
。用户www-data是nginx运行的用户,以及拥有我的Rails应用程序中所有文件的用户。我还查看了/etc/environment
,我可以看到/usr/bin
处于系统范围的路径中。运行sudo -u www-data node -v
也会按预期返回节点版本,因此它是可执行的。
当我运行RAILS_ENV=production bundle exec rake assets:precompile
时,我没有收到任何错误。当我将ExecJS加载到与IRB的交互式会话中时,我能够让它返回一个有效的运行时。我也试过明确地添加EXECJS_RUNTIME=Node
作为环境变量,但它只是说“Node.js(V8)运行时不可用”。我尝试了很多东西,但我无法让它发挥作用!
这是我访问Rails应用程序时遇到的错误。当我查看Nginx日志文件时,我看到了几乎相同的东西。
Web application could not be started
Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
/usr/lib/ruby/gems/2.1.0/gems/execjs-2.0.2/lib/execjs/runtimes.rb:51:in `autodetect'
/usr/lib/ruby/gems/2.1.0/gems/execjs-2.0.2/lib/execjs.rb:5:in `<module:ExecJS>'
/usr/lib/ruby/gems/2.1.0/gems/execjs-2.0.2/lib/execjs.rb:4:in `<top (required)>'
/usr/lib/ruby/gems/2.1.0/gems/uglifier-2.5.0/lib/uglifier.rb:3:in `require'
/usr/lib/ruby/gems/2.1.0/gems/uglifier-2.5.0/lib/uglifier.rb:3:in `<top (required)>'
/usr/lib/ruby/gems/2.1.0/gems/bundler-1.6.1/lib/bundler/runtime.rb:76:in `require'
/usr/lib/ruby/gems/2.1.0/gems/bundler-1.6.1/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
/usr/lib/ruby/gems/2.1.0/gems/bundler-1.6.1/lib/bundler/runtime.rb:72:in `each'
/usr/lib/ruby/gems/2.1.0/gems/bundler-1.6.1/lib/bundler/runtime.rb:72:in `block in require'
/usr/lib/ruby/gems/2.1.0/gems/bundler-1.6.1/lib/bundler/runtime.rb:61:in `each'
/usr/lib/ruby/gems/2.1.0/gems/bundler-1.6.1/lib/bundler/runtime.rb:61:in `require'
/usr/lib/ruby/gems/2.1.0/gems/bundler-1.6.1/lib/bundler.rb:132:in `require'
/srv/www/app/config/application.rb:7:in `<top (required)>'
/srv/www/app/config/environment.rb:2:in `require'
/srv/www/app/config/environment.rb:2:in `<top (required)>'
config.ru:3:in `require'
config.ru:3:in `block in <main>'
/usr/lib/ruby/gems/2.1.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `instance_eval'
/usr/lib/ruby/gems/2.1.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `initialize'
config.ru:1:in `new'
config.ru:1:in `<main>'
/usr/share/passenger/helper-scripts/rack-preloader.rb:112:in `eval'
/usr/share/passenger/helper-scripts/rack-preloader.rb:112:in `preload_app'
/usr/share/passenger/helper-scripts/rack-preloader.rb:158:in `<module:App>'
/usr/share/passenger/helper-scripts/rack-preloader.rb:29:in `<module:PhusionPassenger>'
/usr/share/passenger/helper-scripts/rack-preloader.rb:28:in `<main>'
答案 0 :(得分:25)
我也有这个问题。这就是为我解决的问题。我把它添加到我的nginx.conf
的顶部env PATH;
http://wiki.nginx.org/CoreModule#env
当我关注这个解决方案时,我也发现这篇文章帮助我开始咆哮正确的树:https://forums.freebsd.org/viewtopic.php?&t=35539 - 他编辑execjs代码以给出节点的绝对路径。这有效并帮助我找到了如何为乘客提供路径。
答案 1 :(得分:4)
所以,我发现了这个问题。
首先,我的Node安装并非适用于所有用户。也就是说,它已安装并可供Nginx应该运行的用户使用。不过,您需要记住在nginx.conf
:
user ec2-user;
...
http {
passenger_root /usr/local/rvm/gems/ruby-2.1.0/gems/passenger-4.0.42;
passenger_ruby /usr/local/rvm/gems/ruby-2.1.0/wrappers/ruby;
passenger_nodejs /usr/local/bin/node;
passenger_default_user ec2-user;
...
其次,您还需要为非登录shell提供Node的路径,即将其添加到/etc/bashrc
并导出。
您的环境可能不同,但这是要点。
答案 2 :(得分:1)
在上面的评论中说得太快了。 在我的Hello World Rails应用程序(4.1,使用默认的Gemfile和配置)上工作正常,我停止了EC2实例对其进行快照,然后在重新启动时,我遇到了Exec.js错误尽管节点(~0.11)安装在/ usr / local / bin
但是,我从
编辑了我的`/ etc / sudoers /文件 Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
为:
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
我重新启动了服务器和Apache,事情按预期工作。