Rails 3 on AWS micro: CentOS Nginx Passenger
Note: This was tested on AWS using a micro instance and ami-6b608c02 which seemed to be the most barebones community CentOS i386 EBS AMI I could find. It works as a Micro instance out of the box without issues.
Prepare the Server
Update the system and install required libraries
yum update -y
yum groupinstall “Development Tools” -y
yum install zlib-devel wget openssl-devel pcre pcre-devel readline-devel sudo nano -y
Configure Time Settings
yum install tzdata system-config-date -y
yum install ntp -y
# Contact NTP server and update current time
ntpdate ntp.ubuntu.com
Configure the hostname
hostname my.specialhost.name
Write loopback IP and your hostname in your /etc/hosts file:
bash
nano /etc/hosts
127.0.0.1 my.specialhost.name
Write your hostname to /etc/hostname
nano /etc/hostname
my.specialhost.name
## Installing the Application Stack
Install MySQL
yum install mysql mysql-devel
Secure your MySQL install:
mysql_secure_installation
Install Ruby
Ignore ri and rdoc for this server
nano ~/.gemrc
Add these two lines:
install: —no-ri —no-rdoc
update: —no-ri —no-rdoc
Download Ruby from source and install:
wget ftp://ftp.ruby-lang.org:21//pub/ruby/1.9/ruby-1.9.2-p0.tar.gz
tar xvfz ruby*
cd ruby*
./configure && make && make install
Check that Ruby and RubyGems all were installed correctly:
ruby -v
gems -v
Clean up the Ruby source files:
cd ..
rm -R ruby*
Install Git (Good idea for Capistrano deployments)
yum install gettext-devel expat-devel curl-devel zlib-devel openssl-devel
wget http://kernel.org/pub/software/scm/git/git-1.7.1.tar.gz
tar xzvf git-1.7.1.tar.gz
cd git-1.7.1
make prefix=/usr/local all
make prefix=/usr/local install
Install Rails and Passenger gems
gem install rails
If you need a specific version of Rails:
gem install rails -v=2.3.8
gem install passenger
Install modified Nginx with Passenger built-in
passenger-install-nginx-module
Option 1
Create init scripts for Nginx
git clone git://github.com/xdite/rails-nginx-passenger-centos.git
sudo mv rails-nginx-passenger-centos/nginx/nginx /etc/init.d/nginx
sudo chown root:root /etc/init.d/nginx
Verify the script can start and stop Nginx:
sudo /etc/init.d/nginx start
* Starting Nginx Server…
…done.
sudo /etc/init.d/nginx status
nginx found running with processes: 11511 11510
sudo /etc/init.d/nginx stop
* Stopping Nginx Server…
…done.
Add Nginx to startup:
sudo /sbin/chkconfig nginx on
Check that it starts and stops with the server by:
reboot
Install ImageMagick and RMagick (Optional)
yum remove imagemagick
yum install tcl-devel libpng-devel libjpeg-devel ghostscript-devel bzip2-devel freetype-devel libtiff-devel
yum install libjpeg-devel libpng-devel glib2-devel fontconfig-devel zlib-devel libwmf-devel freetype-devel
Download the ImageMagick Source
wget ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick.tar.gz
tar xvfz ImageMagick.tar.gz
cd ImageMagick-6*
./configure —prefix=/usr —with-bzlib=yes —with-fontconfig=yes —with-freetype=yes —with-gslib=yes —with-gvc=yes —with-jpeg=yes —with-jp2=yes —with-png=yes —with-tiff=yes
make && make install
Install RMagick
gem install rmagick
Create a ‘deployer’ user (Recommended)
### Add the user
bash
useradd deployer
passwd deployer
Give deployer sudo permission
nano /etc/sudoers
Add this near the bottom of the file:
deployer ALL=(ALL) ALL
End your SSH session
exit
ssh [email protected]
Lock the root account
sudo passwd root -l
Test a Rails 3 app
Create the testapp
rails new testapp -d mysql
cd testapp
bundle install
Enter your database password in your database.yml real quick
nano config/database.yml
rake db:create:all
rails generate scaffold post title:string body:text
rake db:migrate
Check really quick that WeBrick can start the rails app before we involve Passenger/Nginx
rails server
Change the user Nginx runs as
sudo nano /opt/nginx/conf/nginx.conf
At the top of the config file, uncomment or change “user nobody;” to:
user deployer;
Add a virtual host to Nginx
sudo nano /opt/nginx/conf/nginx.conf
Find the server { } block in the default file and remove it. Add this:
server {
listen 80;
# server_name www.mycook.com;
root /home/deployer/testapp/public;
passenger_enabled on;
}
Restart Nginx:
sudo /etc/init.d/nginx restart
Try accessing your testapp
In your web browser:
http://my.specialhost.name/posts
Tweaking Nginx/Passenger
Enable gzip
sudo nano /opt/nginx/conf/nginx.conf
Find the existing commented “ #gzip on; ” and remove it and replace it with the following:
gzip on;
gzip_buffers 16 8k;
gzip_disable “MSIE [1-6].”;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
Longer expiration tags on content served by Nginx
Place the following in your virtual host’s server { } block:
location ~* .(ico|css|js|gif|jp?g|png)(\?[0-9]+)?$ {
expires max;
break;
}
Reduce Passenger spin-up time
Place the following in your virtual host’s server { } block:
#Passenger options
rails_spawn_method smart-lv2; # This can cause problems with some apps
rails_app_spawner_idle_time 0;
rails_framework_spawner_idle_time 0;