How to host a Rails app with Phusion Passenger for Nginx Sep 03
I believe Phusion Passenger for Nginx will do for Rails Deployment what jQuery did for JavaScript Development. So it should come as no surprise that this will be an opinionated Rails deployment tutorial. Simply put, I couldn't phantom deploying Rails without Passenger for Nginx.
Today I'm going to run you through getting your Rails app running on Ubuntu, Ruby Enterprise Edition (REE), Rails, Nginx and Phusion Passenger for Nginx. Lastly, I'll quickly show you how to successfully deploy your Rails app to a sub URI without any 403 Forbidden errors.
Here are my notes from one of my client's latest Rails deployment.
Ruby Enterprise Edition (REE):
We're going to start by installing Ruby Enterprise Edition (REE). Download the latest .deb REE package, then install it:
wget http://rubyforge.org/frs/download.php/71100/ruby-enterprise_1.8.7-2010.02_i386_ubuntu10.04.deb
sudo dpkg -i ruby-enterprise_1.8.7-2010.02_i386_ubuntu10.04.deb
ruby -v
You should see something similar to ruby 1.8.7 (2010-04-19 patchlevel 253) ... Ruby Enterprise Edition 2010.02. Now, update your RubyGem package manager and all of your installed gems:
sudo gem update --system
sudo gem update
Ruby on Rails
At this point you should make sure you've installed the Ruby on Rails gem. Don't worry, you've probably already done that. Here's the command to install Rails (just in case):
sudo gem install rails
rails -v
Install, Configure and Manage Nginx
Install Nginx
First, let's install the Open SSL library. You're going to need this later for SSL support and management:
sudo aptitude install libssl-dev
Next, we are going to install the Passenger for Nginx module. This module will install both Nginx and Passenger:
sudo passenger-install-nginx-module
Follow the default options. Soon, you'll be prompted with two options to either select 1 or to select 2.
Choose option 2 if you need to install additional Nginx modules. One module that comes to mind is the Nginx SSL module.
For this tutorial, select option 1. Let the install finish. Congrats, you've just installed a blazing fast Webserver (Nginx) and Rails application server (Passenger)!
You will also need to create a user and group for nginx. Issue the following command to do so:
adduser --system --no-create-home --disabled-login --disabled-password --group nginx
Finally, let's create an init.d script and have it boot at startup. The init.d will allow us to control Nginx:
sudo nano /etc/init.d/nginx
Copy and paste the following Nginx init script into the new file:
#! /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:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/opt/nginx/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
. /lib/lsb/init-functions
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."
;;
status)
status_of_proc -p /opt/nginx/logs/$NAME.pid "$DAEMON" nginx && exit 0 || exit $?
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
exit 1
;;
esac
exit 0
To save the file using nano, press ctrl+o, then enter. Then exit by pressing ctrl+x.
Change permission on the script to make it an executable:
sudo chmod +x /etc/init.d/nginx
Have the new executable run at startup:
sudo /usr/sbin/update-rc.d -f nginx defaults
Now, you have the power to start, stop and restart Nginx. Start your shiny new Nginx Webserver with this command:
sudo /etc/init.d/nginx start
Navigate to your server's IP address using Firefox or your favorite browser. You should see "Welcome to Nginx!" This means Nginx is up-and-running. Now we can focus on configuring Nginx for your Rails web application.
Configure Nginx
Edit your Nginx configuration:
sudo nano /opt/nginx/conf/nginx.conf
Make sure Nginx knows the location of your passenger and ruby installation:
. . .
http {
passenger_root /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.15;
passenger_ruby /usr/local/bin/ruby;
. . .
server {
. . .
}
}
For fun, let's modify our Server section to deploy our Rails app to a Sub URI:
server {
listen 80;
server_name domain.com;
charset utf-8;
root /www/domain.com/public_html;
passenger_enabled on;
passenger_base_uri /blog;
rails_spawn_method smart;
rails_env production;
}
To do this, we have to make a symlink from our Rails app's public directory to the document root of our static website:
ln -s /www/domain.com/railsapp/public /www/domain.com/public_html/blog
This command will create a symlink called blog in the document root /www/domain.com/public_html/.
Remember, if you want to make the sub uri work, do not create a folder called blog in the document root. This will get you a nice Rails sub uri 403 Forbidden error from your passenger Nginx setup.
For a typical Xen VPS setup, you should also think about adding the following tweaks to your Nginx conf:
user nginx nginx;
worker_processes 4;
worker_connections 1024;
passenger_max_pool_size 6;
Read more about the the passengermaxpool_size directive. The maximum value depends on your server's cpu processor and other factors. Do experiment!
When you're finished, save the file and restart Nginx:
sudo /etc/init.d/nginx restart
Manage Nginx
In the future you can restart the entire Nginx server or only restart your application with the following command:
touch /www/domain.com/blog/tmp/restart.txt
The next time you load your Rails app it will restart.
Passenger also has some pretty cool built-in monitoring applications. You can access them using these commands:
sudo passenger-status
sudo passenger-memory-stats
I suggest installing another utility to see what's using memory on your entire server. It's called htop:
sudo apt-get install htop
sudo htop
Well, you're done really! I hope this helps.
For the uninitiated, deploying to Ubuntu (or any Linux distro) can be daunting. But, once you get over having nothing but a black screen to work with, you'll realize how unshackled and productive you feel. Good luck Beloved!






6 comments so far
kaysov 18 Dec 10
Rajinder Yadav 18 Dec 10
TVD 18 Dec 10
adduser --system --no-create-home --disabled-login --disabled-password --group nginxDeclare the user in /opt/nginx/conf/nginx.conf. . . user nginx nginx; worker_processes 4; . . .Restart nginxsudo /etc/init.d/nginx restartGive nginx permission to access your fileschmod -R 774 /www/domain.com/public_html chmod -R 774 /www/domain.com/blog chown -R nginx:nginx /www/domain.com/public_html chown -R nginx:nginx /www/domain.com/blogTVD 18 Dec 10
sudo nano /etc/hostsAdd this line to your hosts file127.0.0.1 localhostClean up any Permission issuesSee above...Make sure your nginx.conf is good. Here's a basic nginx.conf:user nginx nginx; worker_processes 1; events { worker_connections 1024; } http { passenger_root /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.15; passenger_ruby /usr/local/bin/ruby; include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name domain.com; charset utf-8; root /www/domain.com/public_html; passenger_enabled on; passenger_base_uri /blog; rails_spawn_method smart; rails_env development; } }Restart nginxsudo /etc/init.d/nginx restartHope things work out for you. Nginx is a beautiful Web Server and Passenger is the Bugatti of Rails Application Servers.kaysov 21 Dec 10
TVD 21 Dec 10
Comments are closed