Update: This is a more up-to-date guide here: Passenger with nginx on Mac OS X (2nd edition)
Setting up nginx with Passenger support turns out to be fairly easy.
Start by making sure you have the most recent version of Passenger, then install the nginx module. This will actually install and compile nginx with the Passenger module enabled, which is handy. Choose the recommended/default options when the installer prompts you.
sudo gem update passenger
sudo passenger-install-nginx-module
Then, open up the nginx config file:
mate /opt/nginx/conf/nginx.conf
Add the following line to the top of the file:
daemon off;
This will prevent the “502 Bad Gateway” error you may see otherwise. I’m not sure why this is necessary, but I read about it here, and it seems to do the trick. nginx specifies that this should only be used for development, though.
Next, find the http { block, which should start around line 15 or so. You’ll want to add a server { block within the http { block for each of your Rails/Rack applications, like so:
server {
listen 80;
server_name eldorado.local;
root /Users/trevorturk/Code/eldorado/public;
passenger_enabled on;
rails_env development;
}
You’ll need an entry in your hosts file if you don’t already have one. Simply open up the file:
mate /etc/hosts
…and add lines for each of the apps you plan to run, like so:
127.0.0.1 eldorado.local
Now, we can set up a launchd item, so that nginx will start up automatically after a system reboot. Create a new plist file by opening it up in TextMate:
mate /System/Library/LaunchDaemons/nginx.plist
…and paste the following code in, which was kindly provided for us by this helpful person:
http://gist.github.com/188167
Then, run the following command to load it:
launchctl load /System/Library/LaunchDaemons/nginx.plist
Now, you can reboot your system and make sure it’s all working as expected by visiting http://eldorado.local, or whatever address you’ve configured your application to be on.
I believe this nginx installation will override the existing Apache installation you may have running. This doesn’t bother me, so I opened up my System Preferences -> Sharing prefpane and unchecked the Web Sharing box, so Apache is no longer running. If you have any ideas about how to keep both services running cooperatively, please do let me know.
Update: Here are some additionally configuration options I’m using, which I cobbled together from various sources after Googling for things like “nginx, rails, gzip, expires” and such. Their powers combined, and I seem to have a YSlow-approved setup.
Just above your server { block, around line 40, add the following:
gzip on;
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6].";
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
That should cover gzip well enough.
Then, amend the aforementioned server { block to include some far future expires goodness that takes advantage of the Rails asset_tag helpers:
server {
listen 80;
server_name eldorado.local;
root /Users/trevorturk/Code/eldorado/public;
passenger_enabled on;
rails_env development;
location ~* .(ico|css|js|gif|jp?g|png)(?[0-9]+)?$ {
expires max;
break;
}
}
These two configuartion tweeks are, I believe, the rough equivalent of the technique previously discussed on this blog for Apache.
Of course, any additional suggestions, comments, or insights you may have would be most welcome. I’m new to this whole nginx thing, but I’m enjoying it so far.
Update: Here’s an easy way to reload nginx, if you need to make a change to your conf. Make sure to have the following in your /opt/nginx/conf/nginx.conf file:
pid /var/run/nginx.pid;
Then, you can make an alias for the reload task in your ~/.bash_profile:
alias nr='sudo kill -HUP `cat /var/run/nginx.pid`'
In case you’re interested, you can check out my full nginx.conf file for local development here:
http://gist.github.com/191331