【问题标题】:Rails/Passenger/Node.js: ExecJS "Could not find a JavaScript runtime"Rails/Passenger/Node.js:ExecJS“找不到 JavaScript 运行时”
【发布时间】:2014-06-01 05:32:45
【问题描述】:

我正在尝试使用 Node.js 作为我的 Rails 应用程序的 JavaScript 运行时。我在 Ubuntu 12.0.4 上使用 Phusion Passenger 模块和 Nginx 作为我的 Web 服务器。每次访问我的 Rails 应用程序时,我都会收到一个错误页面,该页面似乎是从 Passenger 生成的,指出 ExecJS 找不到 JavaScript 运行时。我在这里看到很多帖子,要么建议你安装 Node——我通过sudo apt-get install node 完成了——要么建议在你的 Gemfile 中使用 therubyracer + execjs。后一种解决方案确实有效,但我真的更喜欢使用 Node,特别是因为 Heroku has stated 他们不鼓励使用 therubyracer,因为它使用“非常大量的内存”。

我遇到了tutorial,这表明运行我的 Web 服务器的用户可能在其路径中没有 Node。我通过运行sudo -u www-data which node 进行了检查,它返回/usr/bin/node。用户 www-data 是运行 nginx 的用户,也是拥有我的 Rails 应用程序中所有文件的用户。我还查看了/etc/environment,我可以看到/usr/bin 在系统范围的路径中。运行sudo -u www-data node -v 也会按预期返回Node 版本,因此它是可执行的。

当我运行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>'

【问题讨论】:

  • 你能解决这个问题吗?我在我的 Amazon EC2 实例上遇到了同样的情况 - 当我从控制台(在服务器上)运行 ExecJS::Runtimes.autodetect 时一切正常,但从乘客内部中断
  • 不。我想不通。我决定只使用 therubyracer 和 execjs gems 并称之为好。
  • 可以确认这是一个持续的、显示停止的错误。我能够让 Rails 4.1、Ruby 2.0 与默认的 Amazon Linux AMI 一起工作,但是一旦我重新启动服务器,这个错误就莫名其妙地出现了,即使没有任何改变。
  • 很高兴即使我正在使用 RoR 应用程序,我仍然需要 nodejs。 fsck 它,我宁愿一路去节点。

标签: ruby-on-rails node.js nginx passenger


【解决方案1】:

我也有这个问题。这就是为我解决的问题。我将此添加到我的 nginx.conf 的顶部

env PATH;

http://wiki.nginx.org/CoreModule#env

当我专注于这个解决方案时,我还发现这篇文章帮助我开始寻找正确的树:https://forums.freebsd.org/viewtopic.php?&t=35539——他编辑了 execjs 代码以提供节点的绝对路径。这很有效,并帮助我了解了如何为乘客提供路径。

【讨论】:

  • 确实有效,谢谢。但是我不知道为什么乘客找不到nodejs的路径?
【解决方案2】:

所以,我发现了问题。

首先,我安装的 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;
...

其次,您还需要使 Node 的路径可用于非登录 shell,即将其添加到 /etc/bashrc 并导出。

您的环境可能不同,但这是要点。

【讨论】:

  • 我刚试过这个,不幸的是它不适用于我的服务器。
  • 将passenger_nodejs 添加到服务器配置块或nginx.conf 解决了我的问题。谢谢。
【解决方案3】:

在我上面的评论中说得太早了。 在我的 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,一切正常。

【讨论】:

  • 不幸的是,这对我不起作用。 Node 安装在我的服务器上的 /usr/bin 中,默认情况下位于 secure_path 中。无论如何,为什么编辑 /etc/sudoers 会解决问题?
猜你喜欢
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
  • 2013-10-29
相关资源
最近更新 更多