Rails: Is Passenger Standalone Suitable for Production Deployment

Rails: is Passenger Standalone suitable for production deployment?

Standalone is built on top of Nginx. You can directly attach it to port 80 and it'll behave pretty much like Phusion Passenger + Nginx: it can serve static files very quickly, it'll automatically start and stop processes based on traffic, it'll auto-restart processes when they crash, it'll take care of fairly load balancing traffic between processes, etc. Performance-wise, it's exactly the same as Phusion Passenger for Nginx. So yes you can use it in production.

Nginx does not support .htaccess. It's an Apache thing.

If you run multiple Standalones it's a little bit more memory-heavy than running a single Phusion Passenger for Nginx but the overhead is relatively small.

Passenger Standalone, no need of HTTP Server?

The short answer is "yes" that is indeed how it works. Basically passenger standalone allows you to run your application via passenger start, and it uses nginx behind the scenes to actually serve rails requests.

There is one big problem with running passenger standalone as your only webserver, however. If you want to run more than one ruby-based website, you'll have to run them each on separate ports, since there's no way to proxy requests to individual applications with passenger standalone by itself.

In my environment, I needed to run multiple sites using multiple different versions of ruby (not just different versions of rails). For example I have one site running Rails 2.3.x with Ruby Enterprise Edition, and another site running Rails 3.0.x running Ruby 1.9.2. I used passenger standalone with a separate Nginx proxy to solve this problem:

  • Each website runs passenger standalone, which I have configured to listen on a local UNIX socket. I use RVM to take care of loading my ruby version for me, so my passenger start command is a bit lengthy, but it looks like this:

    • cd /path/to/my/app; rvm use ree-1.8.7-2011.03@gemset; export GEM_HOME=/usr/local/rvm/gems/ree-1.8.7-2011.03@gemset; /usr/local/rvm/gems/ree-1.8.7-2011.03@gemset/bin/passenger start -d -S /tmp/mysite.com.sock -e production --pid-file /path/to/my/app/shared/pids/passenger.pid
  • Now that my app is running and listening at /tmp/mysite.com.sock, I have another Nginx instance that runs on port 80 that just uses simple proxy_pass rules to send requests to each site individually.

Sorry for the long post, and maybe it's a bit too much information... but I've found that this combo works really well, and I've written some nice init.d style scripts to launch my individual passenger standalone apps. Nginx memory usage is so amazingly low that it doesn't really cost anything to run 3 instances of it (1 for each site, and 1 on port 80).

Hope this helps!

How can I keep a Passenger Standalone up even after a restart?

Here is what I got working. Using Upstart (Ubuntu 10.04) to start the passenger daemon

My environment uses rvm with ruby 1.9.2 and apache and my rails app is deployed via capistrano

# Upstart: /etc/init/service_name.conf
description "start passenger stand-alone"
author "Me <me@myself.am>"

# Stanzas
#
# Stanzas control when and how a process is started and stopped
# See a list of stanzas here: http://upstart.ubuntu.com/wiki/Stanzas#respawn

# When to start the service
start on started mysql

# When to stop the service
stop on runlevel [016]

# Automatically restart process if crashed
respawn

# Essentially lets upstart know the process will detach itself to the background
expect fork

# Run before process
pre-start script
end script

# Start the process
script
cd /var/path/to/app/staging/current
sh HOME=/home/deploy /usr/local/rvm/gems/ruby-1.9.2-p136@appname/gems/passenger-3.0.7/bin/passenger start --user 'deploy' -p '5000' -a '127.0.0.1' -e 'production'
end script

and the apache config:

<VirtualHost *:80>
ServerName myapp.com

PassengerEnabled off

<Proxy *>
Order deny,allow
Allow from all
</Proxy>

ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/

</VirtualHost>

Upstart doesn't set ENV['HOME'] which passenger relies on, so we have to pass that when executing the passenger command. Other than that its pretty straight forward.

A note for debugging: https://serverfault.com/questions/114052/logging-a-daemons-output-with-upstart (append something like >> /tmp/upstart.log 2>&1 to the second line in the script block)

Hope this helps.

Unicorn vs Passenger Standalone behind nginx

If you already have nginx set up, use Unicorn. If not, use Passenger Standalone, which comes with its own builtin nginx. Perhaps this also shapes your approach to the docs. There's not much point to separately documenting what is essentially two very well documented products, bundled together.

You'll hear good things about both. If you're in a rush, pick one and go. Otherwise, try both and decide based on your own experience of them.



Related Topics



Leave a reply



Submit