The Road to Passenger 3: Technology Preview 3 – Closing the gap between development and production & rethinking the word “easy”
Update: “Phusion Passenger Lite” has been renamed to “Phusion Passenger Standalone” nowadays. The mass deployment feature has also been removed but will find its way back in the near future in a commercial version of Phusion Passenger.
Before Phusion Passenger came along, the most widely used Ruby app servers all implemented the same model which we refer to as the reverse proxy model. In this model, the user had to manually setup a bunch of app server processes and had to configure the web server to proxy requests to the app server processes. The technically inclined understand this model, but it is confusing to e.g. newcomers and to people who in general don’t have a lot of system administration skills or a reasonable understanding of HTTP. Most people were and still are much more familiar with PHP’s model, where you tell the web server where your app is and then have the web server take care of the rest for you. It was this confusion that caused all the uproar about sucky Rails deployment back in 2008.
While developing Phusion Passenger for Apache, we decided to follow a PHP-like model because ease of use was one of our main goals. No manual setups of app servers. No manual proxy configuration. Upload and go. For Phusion Passenger for Nginx, we continued to follow this model. Let’s call this the automatic model. As of 2010, Phusion Passenger appears to be the only widely-used Ruby app server that implements this model; the other widely-used Ruby app servers implement the reverse proxy model.
Reverse proxy vs automatic model: which one is better?
Ever since Phusion Passenger was first released, debates popped up about which one is superior. We believe that no model is inherently superior to the other. They are just different, meaning that both models have their own pros and cons. Which one is better for you depends a lot on your server infrastructure and your system administrators’ preferences.
Phusion Passenger’s automatic model:
- Integrated into the web server. Processes are managed along with the web server itself, and configuration happens in the web server config file.
- Easier to comprehend for most people. Appears more “standard stack” to system administrators who are not familiar with Ruby specifically.
- Can spawn and shutdown processes dynamically according to traffic patterns.
- Processes are automatically monitored: if they crash they are automatically restarted.
- Less manual control over individual processes because they can come and go at any time.
Reverse proxy model as implemented by most other Ruby app servers:
- App server is a separate entity. Processes are managed distinctly from the web server itself. Configuration happens outside the web server.
- Many people have a hard time comprehending this and they generally find setups like this cumbersome, but to experts this model can be seen as simple, elegant and sensible.
- Most app servers do not automatically restart crashed processes and one needs to monitor processes separately with things like Monit.
- One needs to specify the number of processes up front: no dynamic process count scaling according to traffic.
- Allows fine-grained manual control over individual processes.
We are not commenting on which points are supposed to be pros and which points are supposed to be cons because they are highly subjective. For us, integration into the web server is a strong plus because we host dozens of apps on our server(s) and we don’t like to spend time managing app server processes for each app, but other people are uncomfortable with having the web server manage things automatically and would prefer to keep a close eye on everything.
The automatic model can also be problematic to people who were on the reverse proxy model because they already had their web servers and infrastructures configured in a certain way. Switching to Phusion Passenger could mean changing a lot of web server configuration.
The hidden but unutilized potential
Reverse proxy model app servers can potentially have an extra advantage, but for some reason this hasn’t been implemented to its full potential so far:
Reverse proxy app servers are just easier to get started with. When you’ve just created a new Rails app, you can start it with
script/server and you’re ready to go.
This works great in development but totally blows up in production. Reverse proxy model app servers must be put behind a reverse proxy e.g. Nginx or HAProxy for a variety of reasons such as security, load balancing between processes, handling of slow clients, etc. In production environments nobody exposes Mongrel or Thin directly to the Internet. Unicorn even explicitly documents that it is designed to be put behind a reverse proxy and that it doesn’t bother with slow clients at all.
In contrast, Phusion Passenger 2.x requires one to configure the web server, meaning the user must first install a web server. This is cumbersome when you’re in development and just want to get started. It is also cumbersome if you’re a newcomer and aren’t familiar with Apache or Nginx, and you just want to get your app running on your server.
Do you type
script/server in development instead of creating a virtual host in the Apache or Nginx? Well you’re not the only one: we also do this until we eventually get sick of it, but there’s always a mental blockade that tells us that editing the web server configuration file is too much work to bother with.
Well, until Phusion Passenger 3 comes along.
Phusion Passenger Lite: fusion between the reverse proxy and the automatic model
In addition to Phusion Passenger for Apache and Phusion Passenger for Nginx, Phusion Passenger 3 introduces a new component to the existing lineup: Phusion Passenger Lite.
When it comes to usage, its interface is almost identical to that of Mongrel and Thin. To run your Ruby web app, just type this in the terminal and you’re ready to go:
Closing the gap between development and production
Phusion Passenger Lite consists of an Nginx core. Nginx is known to be extremely scalable, high-performance and lightweight. You do not need to have Nginx already installed; this is automatically taken care of. You also do not need to have any Nginx experience: Nginx is hidden from the user but its power is automatically utilized.
Unlike Mongrel, Thin and Unicorn, Phusion Passenger Lite can be directly exposed to the Internet. It can serve static files at blazing speeds thanks to the Nginx core. Mongrel and Thin can serve static files but they aren’t very good at it. Unicorn doesn’t even try.
Easy migration from existing reverse proxy app servers
Because the interface is so similar, you can easily swap Mongrel, Thin or Unicorn in your existing reverse proxy setup and replace it with Phusion Passenger Lite. Unlike Mongrel and Thin, Phusion Passenger Lite only has to listen on a single socket instead of multiple, vastly simplifying your reverse proxy configurations. Phusion Passenger Lite can listen on a Unix domain socket instead of a TCP socket, just like Thin and Unicorn. In reverse proxy setups this can yield much higher performance than TCP sockets.
Advantages over existing reverse proxy app servers
Unlike Mongrel, Thin and Unicorn, Phusion Passenger Lite can dynamically spawn and shutdown processes according to traffic. However you can also configure it to use a static number of processes! In fact you can configure a minimum and a maximum and have Phusion Passenger Lite automatically figure out the number of processes to use for the current traffic.
Like Phusion Passenger for Apache/Nginx and Unicorn, worker processes that have crashed are automatically restarted.
That said, bear in mind that this advantage can be a disadvantage to some people. At its heart, Phusion Passenger Lite still manages processes for you, so you don’t have as much fine-grained control over the processes as you do with other reverse proxy app servers.
Advantage over Phusion Passenger for Apache and Phusion Passenger for Nginx
Another unintended advantage of Phusion Passenger Lite is that it runs as the same user as the shell and respects environment variables that are defined for your shell, e.g. things like PATH, LD_LIBRARY_PATH, RUBYOPT, GEM_PATH and GEM_HOME.
- Some people find that their app cannot load a certain library when the app is started in Phusion passenger, but can when the app is started with e.g. Mongrel or Thin. This is almost always caused by some environment variable that’s set in the shell but not in the web server: everything you set in /etc/bashrc and friends don’t have effect on processes started from the web server.
- Some people say that their application does not start on Phusion Passenger, but does under Mongrel/Thin. Very often this turns out to be just a permission issue or some web server configuration issue.
With Phusion Passenger Lite, even confusion like this will be a thing of the past.
Rethinking the word “easy”: automatic mass deployment
Phusion Passenger is considered by many people the easiest Ruby app server out there. But can it be easier? After some heavy thinking outside the box, we believe the answer is yes, it certainly can!
Imagine having a directory full of Ruby web apps, e.g. ~/Sites. To deploy an app, just drop your application’s directory into ~/Sites. To undeploy it, remove the application’s directory. The application directory’s name is used as the domain name. No manually signaling the web server for a restart.
This is exactly what we’ve done with Phusion Passenger Lite. We call this feature automatic mass deployment. Check out this demo.
So from now on, if you have a bunch of Ruby web apps in the same directory, just run this command in that directory
sudo passenger start -p 80 -u (some_unprivileged_username)
and you’ve immediately deployed every single app!
Phusion Passenger Lite does not replace Phusion Passenger for Apache or Phusion Passenger for Nginx. Rather, it is a complement to our existing lineup of Phusion Passenger products, optimized for different use cases. Phusion Passenger Lite closes the gap between development and production and can be used comfortably and easily in both. It can act as a drop-in replacement for your existing reverse proxy based setup. It makes Ruby web app deployment even easier than before: now you don’t even need a separate web server. On the other hand, if you need integration into the web server, then Phusion Passenger for Apache/Nginx is for you.
We hope you’ve enjoyed this Technology Preview. Please stay tuned for the next one because we have more exciting news for you!