Wednesday, July 1, 2009

Home made nginx + phusion passenger OS X port

The instructions to do this are similar to those in my previous article.

Install passenger gem
The first step is to install the Phusion Passenger gem:
$ sudo gem install -V -r passenger
[...]
Installing RDoc documentation for passenger-2.2.4...

Take note of where the passenger gem installed the nginx module code (ext/nginx/*) that will be required further down. In this case the install directory will be /opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.4/ext/.

Compile nginx passenger module
You also need to compile the passenger nginx module if it was not already compiled:

$ cd /opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.4/ext/
$ sudo rake nginx
[...]
g++ ext/nginx/HelperServer.cpp -o ext/nginx/HelperServer -Iext -Iext/common -D_REENTRANT -I/usr/local/include -Wall -g -DPASSENGER_DEBUG -DBOOST_DISABLE_ASSERTS ext/nginx/libpassenger_common.a ext/nginx/libboost_oxt.a -lpthread


Modify the nginx Portfile
Ensure you have nginx port installed. Your Portfile will most likely be in /opt/local/var/macports/sources/rsync.macports.org/release/ports/www/nginx/Portfile.

Add the following variant block to the end of the file:

variant passenger description {Enable Phusion Passenger (mod_rails) support} {
configure.args-append --add-module=/opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.4/ext/nginx
}


Rebuild/install nginx
When you try and reinstall nginx now it will use the updated Portfile and add the passenger module to the mix:

$ sudo port uninstall nginx && sudo port clean nginx
$ sudo port -vvvvv install nginx +passenger


Nginx passenger configuration
To enable and take advantage of the passenger nginx module you need to edit the /opt/local/etc/nginx/nginx.conf config. Here's an example:

#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 {
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;

# Enable Phusion Passenger nginx module
passenger_root /opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.4;
passenger_ruby /opt/local/bin/ruby;

server {
listen 80;
server_name foo.example.com;
root /var/www/foo/public; # <--- be sure to point to 'public'!
passenger_enabled on;
}
}

Ensure that the port, server_name and root variables have valid values for your environment.

If you want to use a non-production rails environment you can add the following to the block after passenger_enabled:

rails_env development;

Once done you can restart nginx and you should see the following processes that confirm things are running:

$ ps axw | egrep "nginx|passenger"
55935 ?? Ss 0:00.00 nginx: master process nginx
55936 ?? S 0:00.00 nginx: worker process
55925 s001 S 0:00.01 PassengerNginxHelperServer /opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.4 /opt/local/bin/ruby 3 4 0 6 0 300 1 nobody 4294967294 4294967294 /tmp/passenger.55923
55938 s001 R+ 0:00.00 egrep nginx|passenger

The final test to see if everything is working is to open a browser and to browse to the server_name and port defined above. Errors will be reported in /opt/local/var/log/nginx/error.log as well as the development/production logs of the rails project you're running.


No comments:

About Me

My photo
I love solving real-world problems with code and systems (web apps, distributed systems and all the bits and pieces in-between).