Skip to content

Instantly share code, notes, and snippets.

@akiatoji
Created July 3, 2012 23:06
Show Gist options
  • Save akiatoji/3044056 to your computer and use it in GitHub Desktop.
Save akiatoji/3044056 to your computer and use it in GitHub Desktop.
Nginx + Passenger 3 + RVM for Rack app on OS X using homebrew only

Most examples I found tell you to run rvmsudo or passenger-install-nginx-module. I ran into problems with these because:

  1. rvmsudo leaves root owned directories and files under rvm passenger gem directory. This will give you seemingly odd errors later when you try to remove/upgrade passenger gem, or try to use homebrew to install passenger.

  2. There's no good place to put nginx using passenger-install-nginx-module. Putting it under /usr/local means you have to remember it's there amongst homebrew files. Anywhere else, you still have to remember you put it there. We'd rather manage nginx install via homebrew.

So to install everything with homebrew, this is what it took:

gem install passenger
brew install nginx --with-passenger
rvm wrapper ruby-1.9.2-p290 passenger
cd ~/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.13/
rake nginx

Then in your nginx config file, set passenger_root and passenger_ruby like so:

passenger_root /Users/aki/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.13;
passenger_ruby /Users/aki/.rvm/bin/passenger_ruby;

Issues I ran into:

  1. If brew install nginx --with-passenger fails with permission issues, you probably ran rvmsudo passenger-install-nginx-module before. Be sure to chown -R YOU ~/.rvm/*

  2. If you keep getting 403, you likely set wrong rack/rails app root directory in nginx config. The root directory needs to point to public subdirectory in your app. Yes, it's unintuitive, but this is just how it is.

  3. If you are pointing to public directory correctly but still get 403, go look at nginx errorlog. It'll likely say directory listing is not allowed. This means passenger isn't being invoked. You need to check passenger_root and passenger_ruby entries. You don't get any indication if the path is wrong or directory/binary have wrong permission, so you have to eyeball it closely.

  4. If you access your app via browser and get that buttugly purple error page saying it can't find things like rack, this is because ruby's runtime environment isn't setup right and it's unable to find gems or libraries. This happens if you run rvm installed ruby directly from nginx. To run nginx with rvm, you can't invoke ruby directly. Instead, you need to invoke wrapper (passenger_ruby) that sets up the RVM environment. This wrapper is generated under ~/.rvm/bin when you run rvm wrapper command.

  5. You need to run ```rake nginx`` in passenger gem directory or you will get an error in nginx errors.log saying that it can't find PassengerLoggingAgent.

@FooBarWidget
Copy link

Nowadays (starting from version 4.0.5), Phusion Passenger is available on Homebrew as well. Just run:

brew install passenger
brew install nginx --with-passenger

The last step will tell you how to activate Phusion Passenger in Nginx.

That's it! No other steps are necessary.

@zachmccormick
Copy link

Spent a while trying to figure this out. If you compile a lot of C/C++ on OSX and use ccache, you need to set the environment variable USE_CCACHE to 0 while doing this. I didn't investigate further, but on 10.9 I couldn't get this to work with ccache enabled.

@rvgarim
Copy link

rvgarim commented May 19, 2014

Hi, I have an issue with nginx installed as you said. I can't change the root directory of my rails app that nginx says:
nginx: [emerg] invalid number of arguments in "root" directive in /opt/nginx/conf/nginx.conf:41
I'm on a mavericks with passenger nginx rails and ruby all latest versions.

The nginx.conf file is:

user nobody;

worker_processes 1;

error_log logs/error.log;

error_log logs/error.log notice;

error_log logs/error.log info;

pid logs/nginx.pid;

events {
worker_connections 1024;
}

http {
passenger_root /Users/gabrielmadeira/.rvm/gems/ruby-2.1.0@global/gems/passenger-4.0.42;
passenger_ruby /Users/gabrielmadeira/.rvm/gems/ruby-2.1.0@filx/wrappers/ruby;

include       mime.types;
default_type  application/octet-stream;

#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#                  '$status $body_bytes_sent "$http_referer" '
#                  '"$http_user_agent" "$http_x_forwarded_for"';

#access_log  logs/access.log  main;

sendfile        on;
#tcp_nopush     on;

#keepalive_timeout  0;
keepalive_timeout  65;

#gzip  on;

server {
    listen       80;
    server_name  localhost;
    root   /Users/gabrielmadeira/Google Drive/Apps/Rep/public;
    passenger_enabled on;
    rails_env development;
    #charset koi8-r;

    #access_log  logs/host.access.log  main;

location / {

#root html;

index index.html index.htm;

passenger_enabled on;

rails_env development;

}

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}


# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
#    listen       8000;
#    listen       somename:8080;
#    server_name  somename  alias  another.alias;

#    location / {
#        root   html;
#        index  index.html index.htm;
#    }
#}


# HTTPS server
#
#server {
#    listen       443 ssl;
#    server_name  localhost;

#    ssl_certificate      cert.pem;
#    ssl_certificate_key  cert.key;

#    ssl_session_cache    shared:SSL:1m;
#    ssl_session_timeout  5m;

#    ssl_ciphers  HIGH:!aNULL:!MD5;
#    ssl_prefer_server_ciphers  on;

#    location / {
#        root   html;
#        index  index.html index.htm;
#    }
#}

}

can you help me ?
tks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment