Rails/Passenger/Node.js: ExecJS "Could not find a JavaScript runtime"

nginx, node.js, passenger, ruby-on-rails

Solution

I had this problem too. This is what fixed it for me. I added this to the top of my nginx.conf

env PATH;

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

As I zeroed in on this solution I also found this post which helped me start barking up the right tree: https://forums.freebsd.org/viewtopic.php?&t=35539 -- he edits the execjs code to give an absolute path to node. This worked and helped me find out how to give the path to passenger.

Problem

I'm trying to use Node.js as the JavaScript runtime for my Rails application. I'm using the Phusion Passenger module with Nginx as my web server on Ubuntu 12.0.4. Every time I visit my Rails application I get an error page that appears to be generated from Passenger stating that ExecJS can't find a JavaScript runtime. I've seen numerous posts on here that either suggest that you install Node--which I have done via `sudo apt-get install node`--or suggest using therubyracer + execjs in your Gemfile. That latter solution does in fact work, but I would really prefer to use Node, especially since Heroku has stated that they discourage the use of therubyracer do to the fact that it uses a "very large amount of memory". I ran into a tutorial which suggests that the user that my web server runs as may not have Node in it's path. I checked this out by running `sudo -u www-data which node` and it returns `/usr/bin/node`. The user www-data is the user that nginx runs as, and the user that owns all the files in my Rails application. I've also looked at `/etc/environment`, and I can see that `/usr/bin` is in the system-wide path. Running `sudo -u www-data node -v` also returns the Node version as expected, so it is executable. When I run `RAILS_ENV=production bundle exec rake assets:precompile` I don't get any errors. When I load ExecJS into an interactive session with IRB I'm able to get it to return a valid runtime. I've also tried explicitly adding `EXECJS_RUNTIME=Node` as an environment variable, but then it just says "Node.js (V8) runtime is not available" instead. I've tried many things and I just can't get this to work! Here's the error I get when I visit my Rails app. When I look at the Nginx log file I see pretty much the same thing. ``` 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>' ```

Original source