Creating a web server to host Ruby on Rails and PHP using Phusion Passenger, Nginx, and Apache
In this article I’ll explain how I recently setup a web server to host both 1. Ruby on Rails via Phusion Passenger (mod_rails), and 2. PHP via Apache (mod_php). Nginx will sit in front and proxy requests (by hostname) to Apache, or serve them directly via Phusion. Here’s a rough diagram:
I started with a fresh (minimal) installation of Ubuntu 10.04 LTS. Here we go:
Part 1, Apache/PHP
Install PHP & Apache
Set Apache to listen on port 8000.
Note: nginx will listen on 80 and proxy requests to Apache.
For sake of this tutorial, I created a simple PHP script.
And created an Apache vhost for the above script. New/example file: /etc/apache2/sites-available/php.eric.vm
Enabled the new conf file by adding a symlink:
At this point I was able to reach my php script by browsing to http://php.eric.vm:8000
Part 2, RVM/Ruby/Passenger
Here all the steps I executed on the shell
Part 3, Test Rails App
For this tutorial I created a (very) simple Rails app.
(as usual) if I had made changes to my models, I would have run:
To test my rails development environment:
At this point, I was able to browse to my rails app at: http://rails.eric.vm:3000
The generic controller message was shown:
Find me in app/views/home/index.html.erb
To run the rails app in production mode, I edited the file: config/environments/production.rb, and made this change:
And as necessary, migrate production database:
At this point the rails app should be able to run in production mode using:
(if not, check log/production.log for errors)
Part 4, Nginx
Although nginx is now installed, you’ll need a init script. I simply copied the one listed here: http://techoctave.com/c7/posts/16-how-to-host-a-rails-app-with-phusion-passenger-for-nginx, and pasted it here: /etc/init.d/nginx
The last part of this tutorial involves making changes to the nginx conf file: /opt/nginx/conf/nginx.conf
For my server I set nginx to run as the same user/group as Apache, and increased the number of worker processes (per # of CPU):
Within the http directive, I added a server directive for my rails app:
And an upstream and server directive for Apache:
The above configuration changes allow nginx to listen on port 80, and based on hostname: 1. server the rails app (nginx > passenger > rails); or 2. proxy pass the request to Apache (nginx > apache > php).