UPDATE February 27 2013: this article has been obsolete. Phusion Passenger supports multiple Ruby interpreters as of version 4.0.0. The PassengerRuby config option has been made a per-virtual host option, so you can customize your Ruby interpreter on a per-application basis.

One of the questions we’ve been getting a lot lately is whether it’s possible to run multiple Ruby versions with Phusion Passenger, e.g. have app A and B run on Ruby 1.8.7 while having app C run on Ruby 1.9.2. In previous versions of Phusion Passenger there were ways to get around that, e.g. by mixing in Mongrels. As of Phusion Passenger 3 you can run all components as Phusion Passenger.

The setup that we currently recommend is to combine Phusion Passenger for Apache or Phusion Passenger for Nginx, with Phusion Passenger Standalone. One must first identify the Ruby version that you use most. One then proceeds with setting up Phusion Passenger for Apache or Phusion Passenger for Nginx to use that Ruby version. All applications that are to use a different Ruby version can be served separately through Phusion Passenger Standalone and hook into the main web server via a reverse proxy configuration.

Example

Suppose that you have four websites:

foo.com, to run on Ruby 1.8.7.

bar.com, to run on Ruby 1.8.7.

fries.com, to run on Ruby 1.9.1.

hamburgers.com, to run on Ruby 1.9.2.

And suppose that you’re using RVM to manage these Rubies.

Setting up foo.com and bar.com (Ruby 1.8.7)

The Ruby version that you use most is Ruby 1.8.7, so you setup Apache or Nginx to use Ruby 1.8.7 and to serve foo.com and bar.com.

It should be noted that Phusion Passenger for Apache and Phusion Passenger for Nginx already use Unix domain sockets internally for optimal performance. In fact we’ve done this since version 1.0. We plan on elaborating more about our internal technologies in a future blog post.

Conclusion

Those of you who are familiar with Mongrel and Thin will see the similarity. Indeed, Phusion Passenger Standalone was designed to be able to used in a reverse proxy environment such as the one demonstrated in this article. Unlike Mongrel and Thin clusters however you only need a single Phusion Passenger Standalone instance per web application and thus only a single address to proxy to. Phusion Passenger Standalone will take care of starting and stopping application processes for you and will make sure processes are restarted when they crash.

Good blog post, but still not a great solution. I use Passenger largely so I don’t have to mess around with things like reverse proxy configuration; this essentially nullifies Passenger’s big advantage. Out of curiosity, what’s the technical obstacle to giving each Passenger application its own Ruby interpreter?

I wouldn’t say it nullifies Passenger’s big advantage; you still don’t have to manage a whole cluster for each application but just a single standalone instance for starters. In addition, crashing apps are being restarted automatically for you as well etc..

As for your other question, from a technical point of view there shouldn’t be an obstacle I think, so start coding and I’ll gladly take a look at your patch 😉

I think the one of advantages of Passenger is ease of starting processes, writing vhost settings, reload apache or nginx and done. Passenger Standalone seems to need to start by hand or writing custom init scripts. Is it possible in the near future to start Passenger Standalone processes like embedded ones?

One of the problems I see here is I need to manage many standalone Passengers (one per application). And Apache/Nginx with built in Passenger can serve many application. So I still would rather expect for having RubyVersion per vhost, not only once.

Can you please share any examples of init script for standalone passenger applications? I’ve googled but didn’t find anything.
Thanks.

dgm

I ran into this problem, when I wanted to update my own app but then found out redmine didn’t run on 1.9.2 yet. I ended up installing nginx with passenger for my 1.8.7 apps, and appache/passenger for my 1.9.2 apps. then I proxypass all apps from apache to nginx that need it.

/Users/george/.rvm/gems/ree-1.8.7-2010.02@istink/gems/passenger-3.0.0.pre4/lib/phusion_passenger/standalone/command.rb:213:in `initialize’: No such file or directory – /tmp/istink.local.socket (Errno::ENOENT)
from /Users/george/.rvm/gems/ree-1.8.7-2010.02@istink/gems/passenger-3.0.0.pre4/lib/phusion_passenger/standalone/command.rb:213:in `new’

Dave

Got me out of a rut, thanks.

For anyone implementing this on Ubuntu and apache, I had to remove the proxy.conf link in mods-enabled. Otherwise I was getting a 403 error when trying to access the site.

Xavier

Dave, I believe that this will expose you to become a mailing zombie if you bypass any proxy configuration.
I found out that you need to allow 120.0.0.1 in your configuration but that doesn’t seem to be enough.
My configuration is set like this http://pastie.org/1237032

I’ve tried a lot over the last two days but I keep having the same 403 error…

I also changed the permission to my rails-app dir to 777. But result is only a warning while starting the passenger standalone server, which points me to some security risks…

What am i missing at all?

By the way: I started the passenger standalone server as root with following:
passenger start -a 127.0.0.1 -p 3000 -d

Peco Danajlovski

Nice one, but the main problem with this is that all off the requests to the ‘proxied’ standalone application are coming from 127.0.0.1 and it is impossible to track the IP of the users. Is there a workaround for this?

Manuel Meurer

I ran into problems in my Rails app when using Unix domain sockets.
The Rails 3 redirect(‘…’) in my routes.rb didn’t work (an error saying that my_app_upstream is not a valid URL) and the URL helpers use my_app_upstream as the default host, so that for example root_url resolves to http://my_app_upstream/
Switching back to TCP sockets for now.
Anybody else had those or similar problems?

I followed directions, and tried the solutions posted for the 403 errors,
on ubuntu
I am getting a 403 from the proxy,
I did
a2enmod proxy
a2enmod proxy_connect
a2enmod proxy_http
and edited the proxy.conf to allow the localhost,

what else can be wrong?

andres

self correction,

I looked at the apache logs,
it said that by configuration my remote (client) ip wasn’t allowed to pass requests to the proxy,

seems the proxy works in a transparent mode so I had to enable Allow form all in the proxy.conf

At least on my setup (Ubuntu 10.10, Apache 2.2.16, rvm 1.2.6 with ruby 1.9.2, Passenger 3.0.2), I need a trailing slash on the second argument to the ProxyPass/ProxyPassReverse to make the routing run smoothly.

Otherwise, it would just give me a 502 with an error that resembled the following:

Hi – I would like to build this setup on a Mac Box with Snow Leopard Server (10.6.6), being able to run several applications with different ruby Versions. Following the instructions on this site, I am running in some troubles starting passenger-standalone. Using the following setup –
– rvm 1.2.6
– rails 3.0.3
– ruby 1.9.2
– passenger-standalone 3.0.2

I am having the same problem as that of Walter. There is no socket file in /tmp/myapp.socket or anywhere in the system that I could use. Kindly help me out here. This solution is very good and I need this to work. I deployed phusion passenger and nginx and ROR 1.8.7 and 1.9.2 according to the above tutorial/instructions but I am stuck with this only problem that I don’t have any socket file that I could use. I did a system wide search for such file, after starting passenger standalone but no success. Kindly help me out here as soon as possible. Thanks

Tobias

The example Apache proxy configuration seems to have two problems:

First, the ProxyPass and ProxyPassReverse directives need a trailing slash:

I’m using Apache, which is running 1.8.7. I’m attempting to put 1.9.2 in the proxy.

I followed the instructions, but I get nginx’s standard 404 error page. In the log I have:

“GET /help.html HTTP/1.1” 404 131

I’ve double checked everything. Is there a module that I need to include, or perhaps a hole I need to poke in the firewall?

What I find odd is that the passenger standalone is running nginx (in fact, installed it for me.) Is there a way to get it to run Apache? And, I’ve done no configuration of nginx at all. Do I need to, and how would I do that?

pduey

On both OS X and Linux, the first time I started Passenger Standalone it failed with (truncated):
** Execute (dry run) nginx
/usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7/lib/phusion_passenger/standalone/runtime_installer.rb:224:in `*’: negative argument (ArgumentError)
from /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7/lib/phusion_passenger/standalone/runtime_installer.rb:224:in `show_progress’
from /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7/lib/phusion_passenger/standalone/runtime_installer.rb:147:in `block in install!’
from /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7/lib/phusion_passenger/standalone/runtime_installer.rb:423:in `block (2 levels) in install_passenger_support_files’
…

Starting it again went through the install process again, but with success. Subsequently restarting Passenger Standalone worked with no issues.

As commented by Jack Morrill the apache config doesn’t work unless you append a trailing / to the proxy addresses. Only the homepage will work, when you try to access e.g. /refinery it will give a proxy dns error. Adding the trailing / fixes it.

Nice writeup, but having to run additional daemons partly defeats the purpose of Passenger to offer ease of use. The feature request hasn’t moved an inch, so if you’d like to see multiple Rubies in Passenger, cosider voting up (aka: starring) the bug:

Hi there, i was trying this but got the unix socket error on nginx.
I followed the config with: passenger start –socket /tmp/redmine.socket1 -d –nginx-version 0.8.55 but gives me this error command.rb:213:in `initialize’: No such file or directory – /tmp/redmine.socket2 (Errno::ENOENT)

“Phusion” and “Phusion Passenger” are registered trademarks of Phusion. “Rails”, “Ruby on Rails” and the Rails logo are registered trademarks of David Heinemeier Hansson. All other trademarks are property of their respective owners.