Wednesday, August 19, 2009

Rack Passenger

‹prev | My Chain | next›

As much fun as HAProxy and thin servers are, I think getting things running under nginx and passenger might be even more fun. So, first up is to install the passenger gem:
sh-3.2$ sudo gem install passenger
I then run through the passenger install wizard:
sh-3.2$ sudo /var/lib/gems/1.8/bin/passenger-install-nginx-module 
Welcome to the Phusion Passenger Nginx module installer, v2.2.4.

This installer will guide you through the entire installation process. It
shouldn't take more than 5 minutes in total.

Here's what you can expect from the installation process:

1. This installer will compile and install Nginx with Passenger support.
2. You'll learn how to configure Passenger in Nginx.
3. You'll learn how to deploy a Ruby on Rails application.

Don't worry if anything goes wrong. This installer will advise you on how to
solve any problems.

Press Enter to continue, or Ctrl-C to abort.
<Enter>

--------------------------------------------

Checking for required software...

* GNU C++ compiler... found at /usr/bin/g++
* Ruby development headers... found
* OpenSSL support for Ruby... found
* RubyGems... found
* Rake... found at /usr/bin/rake
* Zlib development headers... not found

Some required software is not installed.
But don't worry, this installer will tell you how to install them.

Press Enter to continue, or Ctrl-C to abort.
<Enter>

--------------------------------------------

Installation instructions for required software

* To install Zlib development headers:
Please run apt-get install zlib1g-dev as root.

If the aforementioned instructions didn't solve your problem, then please take
a look at the Users Guide:

/var/lib/gems/1.8/gems/passenger-2.2.4/doc/Users guide Nginx.html
Wow, that's nice. It would have taken me a little while to track down the exact library name in the Debian package repository, so I much appreciate the help offered here. Following passenger's instructions, I:
sudo apt-get install zlib1g-dev
Then, after re-running the installer, I get past the required software check and onto:
sh-3.2$ sudo /var/lib/gems/1.8/bin/passenger-install-nginx-module
...
--------------------------------------------

Checking for required software...

* GNU C++ compiler... found at /usr/bin/g++
* Ruby development headers... found
* OpenSSL support for Ruby... found
* RubyGems... found
* Rake... found at /usr/bin/rake
* Zlib development headers... found

--------------------------------------------

Automatically download and install Nginx?

Nginx doesn't support loadable modules such as some other web servers do,
so in order to install Nginx with Passenger support, it must be recompiled.

Do you want this installer to download, compile and install Nginx for you?

1. Yes: download, compile and install Nginx for me. (recommended)
The easiest way to get started. A stock Nginx 0.6.37 with Passenger
support, but with no other additional third party modules, will be
installed for you to a directory of your choice.

2. No: I want to customize my Nginx installation. (for advanced users)
Choose this if you want to compile Nginx with more third party modules
besides Passenger, or if you need to pass additional options to Nginx's
'configure' script. This installer will 1) ask you for the location of
the Nginx source code, 2) run the 'configure' script according to your
instructions, and 3) run 'make install'.

Whichever you choose, if you already have an existing Nginx configuration file,
then it will be preserved.

Enter your choice (1 or 2) or press Ctrl-C to abort: 1<Enter>
I am not much a fan of compiling my web server in addition to the passenger module, but hey, it's my personal site and it is the awesomeness of nginx + passenger. Continuing with the installer:
--------------------------------------------

Where do you want to install Nginx to?

Please specify a prefix directory [/opt/nginx]: <Enter>

Compiling Passenger support files...
...

--------------------------------------------

Nginx with Passenger support was successfully installed.

The Nginx configuration file (/opt/nginx/conf/nginx.conf)
must contain the correct configuration options in order for Phusion Passenger
to function correctly.

This installer has already modified the configuration file for you! The
following configuration snippet was inserted:

http {
...
passenger_root /var/lib/gems/1.8/gems/passenger-2.2.4;
passenger_ruby /usr/bin/ruby1.8;
...
}

After you start Nginx, you are ready to deploy any number of Ruby on Rails
applications on Nginx.

Press ENTER to continue.
<Enter>

--------------------------------------------

Deploying a Ruby on Rails application: an example

Suppose you have a Ruby on Rails application in /somewhere. Add a server block
to your Nginx configuration file, set its root to /somewhere/public, and set
'passenger_enabled on', like this:

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

And that's it! You may also want to check the Users Guide for security and
optimization tips and other useful information:

/var/lib/gems/1.8/gems/passenger-2.2.4/doc/Users guide Nginx.html

Enjoy Phusion Passenger, a product of Phusion (www.phusion.nl) :-)
http://www.modrails.com/

Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
Those instructions work just as well for a Sinatra application with a rackup file. I currently have my application located in /var/www/eee-code, so my nginx configuration is (mostly from the default configuration from the passenger / nginx install):
worker_processes  2;


events {
worker_connections 1024;
}


http {
passenger_root /var/lib/gems/1.8/gems/passenger-2.2.4;
passenger_ruby /usr/bin/ruby1.8;

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

sendfile on;

keepalive_timeout 65;

server {
listen 80;
server_name beta.eeecooks.com;
root /var/www/eee-code/public;
passenger_enabled on;

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
I also have to update the default /etc/init.d/nginx script to point to the proper location for the pid file and the executable daemon:
#! /bin/sh

### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the nginx web server
# Description: starts nginx using start-stop-daemon
### END INIT INFO

PATH=/opt/nginx/sbin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/opt/nginx/sbin/nginx
#PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#DAEMON=/usr/sbin/nginx
NAME=nginx
DESC=nginx

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
. /etc/default/nginx
fi

set -e

case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --pidfile /opt/nginx/logs/$NAME.pid \
--exec $DAEMON -- $DAEMON_OPTS || true
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /opt/nginx/logs/$NAME.pid \
--exec $DAEMON || true
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile \
/opt/nginx/logs/$NAME.pid --exec $DAEMON || true
sleep 1
start-stop-daemon --start --quiet --pidfile \
/opt/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
start-stop-daemon --stop --signal HUP --quiet --pidfile /opt/nginx/logs/$NAME.pid \
--exec $DAEMON || true
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
exit 1
;;
esac

exit 0
After stopping my HAProxy frontend to thin servers, I start the nginx server. To make sure that all is well, I check out the HTTP headers via telnet:
cstrom@jaynestown:~/repos/eee-code$ telnet beta.eeecooks.com 80
Trying 97.107.136.191...
Connected to beta.eeecooks.com.
Escape character is '^]'.
HEAD / HTTP/1.0

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Connection: close
Status: 200
X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.4
Content-Length: 10167
Server: nginx/0.6.37 + Phusion Passenger 2.2.4 (mod_rails/mod_rack)

Connection closed by foreign host.
Nice. I think tomorrow I will start back with code to move the application out of beta. For now, I have gotten my Sinatra / CouchDB application running under nginx passenger, which is a fine place to be.

2 comments: