Ruby on Rails
RailsOnCentos5_mongrel (Version #66)

Synopsis

Many guides fall short of giving an enterprise-viable solution to using Ruby on Rails. Here I will show you how to set up a Ruby application server suitable for deploying your Rails applications to and using Best Practices from Rails and Ruby developers and server administrators.

I will walk you through installing a secure and fast installation of CentOS 5 that would be a suitable foundation for any CentOS 5 server. Then I will install ruby and only the gems necessary to run a mongrel cluster and prepare the server to run applications. Finally, I will help you create a small application from a workstation and deploy it to the server.

Please put Questions, Comments, Praises, Rants, Suggestions, etc at the end. If you link to this article, you might also leave a note about it at the end.

Part 1: CentOS 5 Install

First of all, know that I have had rubygems problems on systems with less than 128MB of RAM. This may be fixed in rubygems version 0.9.5 or later, though.

Pop on the CentOS 5 CD1 (you will need CDs 1-3 if you follow my suggestions) and boot up the machine. Most things are pretty obvious and self-explanatory, but I do have a few suggestions during the install configuration.

For partitioning, I would suggest using a 102-ish MB boot partition and the rest as LVM. Your / (root) partition can be a minimum of 1.7 GB, which is what I use. Your /var partition can be a minimum of 1.3 GB, which is what I use.

Your swap partition is up to you, I do 512 MB, but really I keep enough RAM in my systems that they never hit swap more than a few megs. Plus, the linux kernel does have the capability to use free space on any partition as dynamic swap space if your swap partition would ever fill up, but if you are filling up 512 MB, your system is probably unusably slow. I could probably even go down to 256 MB.

The rest of your drive space will be a partition for your actual rails application files. I put this at /var/www. You can put it wherever makes sense to you, but it should at least go somewhere under /var to conform to linux folder location rules. You might even put this partition on a separate harddrive or raid array, but it will be very easy to move it in the future should the need arise. Also bear in mind that for this guide, I will be using /var/www as the location for your rails applications.

My other suggestion during installation is to customize what packages are installed at the end of the CD installation. I remove EVERYTHING except for the “Base” group. And I mean EVERYTHING. If you have anything other than the Base group checked than you are wasting resources and my minimum space requirements above will not apply. This guide assumes you have complied with this.

Some good post-install tasks would be to yum update the system, create a user and give him sudo access (this guide assumes using such a user, hence the "sudo"s when necessary), install and configure ntp, and install webmin (use ‘system-config-securitylevel-tui’ to add 1000:tcp to the firewall). Webmin makes managing the server easy ( I use it for all firewall and network setting configuration, but for services I edit the text config files directly, just FYI).

I would love to go into more detail, because I think a strong foundation to your production server is crucial, but this is not a CentOS site. I will also say it is a great idea to use this server for running rails applications ONLY. Use virtual machines (ie. VMWare Server) to put multiple services on one physical machine if you have extra power.

Now, off my soapbox and on to what you all came here for…

Part 2: Ruby Setup

This is incredibly easy to explain because every step can be done at the command line. I will give a brief explanation of each step, though. From here on out, I do all server configuration via ssh using Putty and WinSCP.

Make sure you are in your home folder:

cd ~/

Install Ruby. “ruby-devel,” “mysql-devel,” and “gcc” are needed for the “mysql” gem. “ruby-rdoc” is reguired for the rubygems install.

sudo yum -y install ruby ruby-rdoc ruby-devel mysql-devel gcc

Download rubygems. I strongly suggest going to http://rubyforge.org/projects/rubygems/ and make sure you are getting the latest version.

wget http://rubyforge.rubyuser.de/rubygems/rubygems-0.9.5.tgz

Extract the rubygems archive:

tar xzf rubygems-0.9.5.tgz

Change into the extracted folder:

cd rubygems-0.9.5

Run the rubygems setup:

sudo ruby setup.rb

This updates rubygems itself:

sudo gem update --system

This updates any installed gems (shouldn’t be any right now), the no-ri and no-rdoc prevents ri and rdoc information from being installed (rdoc and ri are useless on a server):

sudo gem update --no-rdoc --no-ri

This installs the “mysql” gem which is written in C++ and much faster than Rail’s built-in MySQL adapter:

sudo gem install mysql --no-rdoc --no-ri -- --with-mysql-config=/usr/bin/mysql_config

Install mongrel_cluster which also pulls in Mongrel:

sudo gem install mongrel_cluster --no-rdoc --no-ri

Create a system user to run the Mongrel daemons:

sudo /usr/sbin/adduser -r mongrel

This is where mongrel_cluster’s config will be stored:

sudo mkdir /etc/mongrel_cluster

Copy the init script so mongrel_cluster can be run on startup:

sudo cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-1.0.2/resources/mongrel_cluster /etc/init.d/

Make the init script executable:

sudo chmod +x /etc/init.d/mongrel_cluster

Go ahead and start up mongrel_cluster and set it to be started at boot:

sudo /etc/init.d/mongrel_cluster start && sudo /sbin/chkconfig mongrel_cluster on

Create the folder where your applications will live:

sudo mkdir /var/www/apps

That’s it as far as system setup goes! It is now ready to accept rails applications such as Redmine, Typo, or your own application. Notice I do NOT install Rails or anything else on this server. Part 3 will show you everything you need to deploy your rails application to run on this server.

Part 3: Application Deployment

These steps will be done on your development workstation.

This will embed rails into the vendor folder in your project. You should do this with all the gems required by your application (I’m not sure but I think this command does all gems automatically). Run this from the command line in the root folder of your application, or from within RadRails (I do this in RadRails (0.7.2)):

rake rails:freeze:gems

Install mongrel_cluster on your workstation so you can create the mongrel_cluster config file (and check it into your source control, ie SVN, if you want):

gem install mongrel_cluster

Run this in your application’s root folder:

mongrel_rails cluster::configure -e production -p 8000 -N 3 -c /var/www/apps/testapp/current --user mongrel --group mongrel --prefix=/test

The “current” directory will be a directory ON THE SERVER that will be symlinked to the latest deployed version of your app. The “8000” is the first port mongrel will be listening on, and the “3” is how many mongrels to start. Since I have 3 mongrels starting on port 8000, that means ports 8000, 8001, and 8002 will be used by this application. “/test” is the prefix that you will be proxying your frontend webserver to.

Edit config/database.yml and configure the “production:” section for a database and user information you set up on your production SQL database. Your production SQL server should be a completely different server. I strongly suggest using phpMyAdmin to manage your MySQL databases. Setting up a database server is beyond the scope of this guide, but I will try and make an addendum in the future with a quick rundown.

Copy the application to the server. On my own applications, I check the above files into SVN and then “export” the application to a separate folder. This gets rid of all the unnecessary “.svn” folders. I then copy the exported folder to the server via WinSCP. I usually just dump it into my home directory and then copy it to the right place with:

sudo mkdir /var/www/apps/testapp
sudo cp -r testapp /var/www/apps/testapp/testapp_v0.0.1


This is assuming your applications name is “testapp,” the folder copied to your home directory was named “testapp,” and the version is “0.0.1.”

These steps (in addition to the previous two commands) will be done on the server:

Symlink a “current” directory to the deployed version of your application with:

sudo ln -s testapp_v0.0.1 current

Change into the “current” directory:

cd /var/www/apps/testapp/current/

And run your migrations against the production database:

sudo rake db:migrate RAILS_ENV="production"


My development box is Ubuntu, but my production is CentoOS 5 so I had to modify the database.yml file, specificy the location of my socket files. —Chris Kobayashi

This will symlink your application’s mongrel_cluster config so that this application will be started by the mongrel_cluster at boot:

sudo ln -s /var/www/apps/testapp/current/config/mongrel_cluster.yml /etc/mongrel_cluster/testapp.yml

You also need to change the tmp/ and logs/ directories to be writable by mongrel:

sudo chown -R mongrel.mongrel /var/www/apps/testapp/current/log


sudo chown -R mongrel.mongrel /var/www/apps/testapp/current/tmp

Now you have a few options for starting your app. The most violent is just reboot the server. Second most violent is sudo /etc/init.d/mongrel_cluster restart which restarts all your mongrel_clusters for all your apps (no big deal if this is the first app on the server, but could be a very big deal otherwise). The most curteous way would be to change to the app’s root directory and do this: sudo mongrel_rails cluster::start. This will start the mongrel’s and from here on out it can be controlled from the init script.

Go ahead and open up those tcp ports now (8000, 8001, and 8002 in my example). Use either method mentioned towards the end of Part 1, if you don’t already know how to do this.

You can now connect to your application on the configured ports on this server. You will probably want to proxy requests to these ports from your web server using Apache’s ProxyBalancer. It would be best to put this on a separate Apache server dedicated to reverse proxying (this is what I have in my datacenter) or at least on a separate Apache web server. For added security on this mongrel server, use the firewall to restrict those mongrel ports (8000 to 8002) to be allowed only from your proxy server.

Addendum 1: Front-end proxy – Apache

If you have selinux enabled, be sure you do this to enable proxying to remote servers:

sudo /usr/sbin/setsebool -P httpd_can_network_connect=1

Here is my config, put in /etc/httpd/conf.d/vhosts.conf:

  1. a note about the “SetEnv proxy-nokeepalive 1” junk:
  2. This is to take care of the seemingly random 502 proxy
  3. errors we were getting with the proxy requests.
  4. This is a known Apache bug #37770 found here:
  5. http://issues.apache.org/bugzilla/show_bug.cgi?id=37770

<VirtualHost *>
SetEnv proxy-nokeepalive 1
ServerName server.domain.com:80

<Proxy balancer://testapp> BalancerMember http:
//192.168.99.99:8000/test BalancerMember http://192.168.99.99:8001/test BalancerMember http://192.168.99.99:8002/test ProxyPass /test balancer://testapp ProxyPassReverse /test balancer://testapp
  1. ProxyPreserveHost on


Todo

Make an addendum for a MySQL server.

Use monit to monitor the mongrel processes.

Get Capistrano to work correctly with this.




Comments


As of 12/4/07
I had to compile Ruby with these instructions
http://hivelogic.com/narrative/articles/ruby_rails_lighttpd_mysql_tiger
Things like irb was missing!

After that everything was working fine thus far for the first simple app running ! Sweet, thank you! :D

Now to figure out how to make it see my mysql :(

—Tripdragon

From what I understand in talking to Tripdragon over email, his hangup was with rubygems-0.9.5 (rubygems0.9.4 was the latest when I first published this guide), and that is why he chose to compile ruby from source. The issue with the new rubygems was that it fails if rdoc is not installed. I have now added “ruby-rdoc” to the installation instructions, so it should work fine now. I would strongly urge anyone to stick with yum as much as possible for software installs as it greatly simplifies keeping up to date and maintaining compatibility and, therefore, reliability.

—Brazen


As of 01/28/08
This is a great guide. I’m currently setting up 2 servers for my company, one production nginx/mongrel cluster with master mysql db, and a second backup nginx/mongrel cluster w/slave mysql db. I’ll post my info and config for this soon.

— Jason

Here’s my nginx setup/config.

Nginx install and config
————————————
(This install works with the above configuration)

If you want to install via yum/rpms, see this page:

http://www.centos.org/modules/newbb/viewtopic.php?topic_id=11821

For a manual compile, see this page:

http://wiki.codemongers.com/NginxGettingStarted

I’m assuming for the rest of these instructions that that you’ve installed via yum/rpms, which puts the nginx config under /etc/nginx.

The config is actually super easy. First edit the /etc/nginx.conf file. On line 33 (right after #gzip on), I added these lines for the mongrel cluster:


    upstream mongrel {
      server 127.0.0.1:8000;
      server 127.0.0.1:8001;
      server 127.0.0.1:8002;
    }

In the server config, do the following:

Change the
server_name localhost;
line to whatever your server host name is. In the


location / { }

block you’ll need to configure a few things; the root file location, what the index page is, proxy settings, and any static content nginx should serve up. Here’s what my location config looks like:

location / {
            root   /var/www/apps/testapp/current;
		# This assumes you have a controller
		# named 'index'. If not, use index.html
		# or whatever your index page is.
            index  index;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
proxy_max_temp_file_size 0;

if (-f $request_filename) {
break;
}
if (-f $request_filename.html) {
rewrite (.) $1.html break;
}
if (-f $request_filename.gif) {
rewrite (.
) $1.gif break;
}
if (-f $request_filename.jpg) {
rewrite (.) $1.jpg break;
}
if (-f $request_filename.js) {
rewrite (.
) $1.js break;
}
if (-f $request_filename.swf) {
rewrite (.) $1.swf break;
}
if (-f $request_filename.png) {
rewrite (.
) $1.png break;
}
if (-f $request_filename.txt) {
rewrite (.) $1.txt break;
}
if (-f $request_filename.css) {
rewrite (.
) $1.css break;
}
if (-f $request_filename.pdf) {
rewrite (.*) $1.pdf break;
}

# Only proxy thru rails calls
if (!-f $request_filename) {
proxy_pass http : // mongrel;
break;
}

}

(Take out the spaces in the above proxy_pass line)

The above will serve up all static assets and only proxy through to the various mongrel instances if the request type cannot be matched. There are also some good settings via Ezra’s conf file:

http://brainspl.at/nginx.conf.txt

That’s it, the nginx config file is fairly simple.


As of 29/1/08
For CentOS5 64 bit if I used yum to install initial ruby packages I had things going into the /usr/lib64 directory which kinda felt wrong, this manifested itself later in the install in problems getting RMagick to work.

As a general guide (and everytime I’ve broken it I’ve wished I hadn’t) try and compile everything natively first into /usr/local…

So how I got my first CentOS5 up and working was doing the aforementioned yum install, ended up rm -rf /usr/lib64/ruby path, then compiling ruby 1.8.6 from scratch, followed on with the rubygems compile and install (as per instructions above), updating the gems, then mongrel/mongrel cluster etc.

Go here to compile and install RMagick on CentOS5. Verified working.

— Rowan Hick


Yeah sorry I have not done any testing using 64-bit CentOS and hadn’t even thought about it having differences that could affect Ruby.

I’m wondering though if you could get a workable system just by symlinking the ruby files from /usr/lib64/ into /usr/lib/. Just an idea.

—Brazen


I had to put trailing slashes on:

ProxyPass /test balancer://testapp*/*
ProxyPassReverse /test balancer://testapp*/*

Or else I would get this error in Apache:

proxy: No protocol handler was valid for the URL /rails/info/properties. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.

—Felix Khazin

Synopsis

Many guides fall short of giving an enterprise-viable solution to using Ruby on Rails. Here I will show you how to set up a Ruby application server suitable for deploying your Rails applications to and using Best Practices from Rails and Ruby developers and server administrators.

I will walk you through installing a secure and fast installation of CentOS 5 that would be a suitable foundation for any CentOS 5 server. Then I will install ruby and only the gems necessary to run a mongrel cluster and prepare the server to run applications. Finally, I will help you create a small application from a workstation and deploy it to the server.

Please put Questions, Comments, Praises, Rants, Suggestions, etc at the end. If you link to this article, you might also leave a note about it at the end.

Part 1: CentOS 5 Install

First of all, know that I have had rubygems problems on systems with less than 128MB of RAM. This may be fixed in rubygems version 0.9.5 or later, though.

Pop on the CentOS 5 CD1 (you will need CDs 1-3 if you follow my suggestions) and boot up the machine. Most things are pretty obvious and self-explanatory, but I do have a few suggestions during the install configuration.

For partitioning, I would suggest using a 102-ish MB boot partition and the rest as LVM. Your / (root) partition can be a minimum of 1.7 GB, which is what I use. Your /var partition can be a minimum of 1.3 GB, which is what I use.

Your swap partition is up to you, I do 512 MB, but really I keep enough RAM in my systems that they never hit swap more than a few megs. Plus, the linux kernel does have the capability to use free space on any partition as dynamic swap space if your swap partition would ever fill up, but if you are filling up 512 MB, your system is probably unusably slow. I could probably even go down to 256 MB.

The rest of your drive space will be a partition for your actual rails application files. I put this at /var/www. You can put it wherever makes sense to you, but it should at least go somewhere under /var to conform to linux folder location rules. You might even put this partition on a separate harddrive or raid array, but it will be very easy to move it in the future should the need arise. Also bear in mind that for this guide, I will be using /var/www as the location for your rails applications.

My other suggestion during installation is to customize what packages are installed at the end of the CD installation. I remove EVERYTHING except for the “Base” group. And I mean EVERYTHING. If you have anything other than the Base group checked than you are wasting resources and my minimum space requirements above will not apply. This guide assumes you have complied with this.

Some good post-install tasks would be to yum update the system, create a user and give him sudo access (this guide assumes using such a user, hence the "sudo"s when necessary), install and configure ntp, and install webmin (use ‘system-config-securitylevel-tui’ to add 1000:tcp to the firewall). Webmin makes managing the server easy ( I use it for all firewall and network setting configuration, but for services I edit the text config files directly, just FYI).

I would love to go into more detail, because I think a strong foundation to your production server is crucial, but this is not a CentOS site. I will also say it is a great idea to use this server for running rails applications ONLY. Use virtual machines (ie. VMWare Server) to put multiple services on one physical machine if you have extra power.

Now, off my soapbox and on to what you all came here for…

Part 2: Ruby Setup

This is incredibly easy to explain because every step can be done at the command line. I will give a brief explanation of each step, though. From here on out, I do all server configuration via ssh using Putty and WinSCP.

Make sure you are in your home folder:

cd ~/

Install Ruby. “ruby-devel,” “mysql-devel,” and “gcc” are needed for the “mysql” gem. “ruby-rdoc” is reguired for the rubygems install.

sudo yum -y install ruby ruby-rdoc ruby-devel mysql-devel gcc

Download rubygems. I strongly suggest going to http://rubyforge.org/projects/rubygems/ and make sure you are getting the latest version.

wget http://rubyforge.rubyuser.de/rubygems/rubygems-0.9.5.tgz

Extract the rubygems archive:

tar xzf rubygems-0.9.5.tgz

Change into the extracted folder:

cd rubygems-0.9.5

Run the rubygems setup:

sudo ruby setup.rb

This updates rubygems itself:

sudo gem update --system

This updates any installed gems (shouldn’t be any right now), the no-ri and no-rdoc prevents ri and rdoc information from being installed (rdoc and ri are useless on a server):

sudo gem update --no-rdoc --no-ri

This installs the “mysql” gem which is written in C++ and much faster than Rail’s built-in MySQL adapter:

sudo gem install mysql --no-rdoc --no-ri -- --with-mysql-config=/usr/bin/mysql_config

Install mongrel_cluster which also pulls in Mongrel:

sudo gem install mongrel_cluster --no-rdoc --no-ri

Create a system user to run the Mongrel daemons:

sudo /usr/sbin/adduser -r mongrel

This is where mongrel_cluster’s config will be stored:

sudo mkdir /etc/mongrel_cluster

Copy the init script so mongrel_cluster can be run on startup:

sudo cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-1.0.2/resources/mongrel_cluster /etc/init.d/

Make the init script executable:

sudo chmod +x /etc/init.d/mongrel_cluster

Go ahead and start up mongrel_cluster and set it to be started at boot:

sudo /etc/init.d/mongrel_cluster start && sudo /sbin/chkconfig mongrel_cluster on

Create the folder where your applications will live:

sudo mkdir /var/www/apps

That’s it as far as system setup goes! It is now ready to accept rails applications such as Redmine, Typo, or your own application. Notice I do NOT install Rails or anything else on this server. Part 3 will show you everything you need to deploy your rails application to run on this server.

Part 3: Application Deployment

These steps will be done on your development workstation.

This will embed rails into the vendor folder in your project. You should do this with all the gems required by your application (I’m not sure but I think this command does all gems automatically). Run this from the command line in the root folder of your application, or from within RadRails (I do this in RadRails (0.7.2)):

rake rails:freeze:gems

Install mongrel_cluster on your workstation so you can create the mongrel_cluster config file (and check it into your source control, ie SVN, if you want):

gem install mongrel_cluster

Run this in your application’s root folder:

mongrel_rails cluster::configure -e production -p 8000 -N 3 -c /var/www/apps/testapp/current --user mongrel --group mongrel --prefix=/test

The “current” directory will be a directory ON THE SERVER that will be symlinked to the latest deployed version of your app. The “8000” is the first port mongrel will be listening on, and the “3” is how many mongrels to start. Since I have 3 mongrels starting on port 8000, that means ports 8000, 8001, and 8002 will be used by this application. “/test” is the prefix that you will be proxying your frontend webserver to.

Edit config/database.yml and configure the “production:” section for a database and user information you set up on your production SQL database. Your production SQL server should be a completely different server. I strongly suggest using phpMyAdmin to manage your MySQL databases. Setting up a database server is beyond the scope of this guide, but I will try and make an addendum in the future with a quick rundown.

Copy the application to the server. On my own applications, I check the above files into SVN and then “export” the application to a separate folder. This gets rid of all the unnecessary “.svn” folders. I then copy the exported folder to the server via WinSCP. I usually just dump it into my home directory and then copy it to the right place with:

sudo mkdir /var/www/apps/testapp
sudo cp -r testapp /var/www/apps/testapp/testapp_v0.0.1


This is assuming your applications name is “testapp,” the folder copied to your home directory was named “testapp,” and the version is “0.0.1.”

These steps (in addition to the previous two commands) will be done on the server:

Symlink a “current” directory to the deployed version of your application with:

sudo ln -s testapp_v0.0.1 current

Change into the “current” directory:

cd /var/www/apps/testapp/current/

And run your migrations against the production database:

sudo rake db:migrate RAILS_ENV="production"


My development box is Ubuntu, but my production is CentoOS 5 so I had to modify the database.yml file, specificy the location of my socket files. —Chris Kobayashi

This will symlink your application’s mongrel_cluster config so that this application will be started by the mongrel_cluster at boot:

sudo ln -s /var/www/apps/testapp/current/config/mongrel_cluster.yml /etc/mongrel_cluster/testapp.yml

You also need to change the tmp/ and logs/ directories to be writable by mongrel:

sudo chown -R mongrel.mongrel /var/www/apps/testapp/current/log


sudo chown -R mongrel.mongrel /var/www/apps/testapp/current/tmp

Now you have a few options for starting your app. The most violent is just reboot the server. Second most violent is sudo /etc/init.d/mongrel_cluster restart which restarts all your mongrel_clusters for all your apps (no big deal if this is the first app on the server, but could be a very big deal otherwise). The most curteous way would be to change to the app’s root directory and do this: sudo mongrel_rails cluster::start. This will start the mongrel’s and from here on out it can be controlled from the init script.

Go ahead and open up those tcp ports now (8000, 8001, and 8002 in my example). Use either method mentioned towards the end of Part 1, if you don’t already know how to do this.

You can now connect to your application on the configured ports on this server. You will probably want to proxy requests to these ports from your web server using Apache’s ProxyBalancer. It would be best to put this on a separate Apache server dedicated to reverse proxying (this is what I have in my datacenter) or at least on a separate Apache web server. For added security on this mongrel server, use the firewall to restrict those mongrel ports (8000 to 8002) to be allowed only from your proxy server.

Addendum 1: Front-end proxy – Apache

If you have selinux enabled, be sure you do this to enable proxying to remote servers:

sudo /usr/sbin/setsebool -P httpd_can_network_connect=1

Here is my config, put in /etc/httpd/conf.d/vhosts.conf:

  1. a note about the “SetEnv proxy-nokeepalive 1” junk:
  2. This is to take care of the seemingly random 502 proxy
  3. errors we were getting with the proxy requests.
  4. This is a known Apache bug #37770 found here:
  5. http://issues.apache.org/bugzilla/show_bug.cgi?id=37770

<VirtualHost *>
SetEnv proxy-nokeepalive 1
ServerName server.domain.com:80

<Proxy balancer://testapp> BalancerMember http:
//192.168.99.99:8000/test BalancerMember http://192.168.99.99:8001/test BalancerMember http://192.168.99.99:8002/test ProxyPass /test balancer://testapp ProxyPassReverse /test balancer://testapp
  1. ProxyPreserveHost on


Todo

Make an addendum for a MySQL server.

Use monit to monitor the mongrel processes.

Get Capistrano to work correctly with this.




Comments


As of 12/4/07
I had to compile Ruby with these instructions
http://hivelogic.com/narrative/articles/ruby_rails_lighttpd_mysql_tiger
Things like irb was missing!

After that everything was working fine thus far for the first simple app running ! Sweet, thank you! :D

Now to figure out how to make it see my mysql :(

—Tripdragon

From what I understand in talking to Tripdragon over email, his hangup was with rubygems-0.9.5 (rubygems0.9.4 was the latest when I first published this guide), and that is why he chose to compile ruby from source. The issue with the new rubygems was that it fails if rdoc is not installed. I have now added “ruby-rdoc” to the installation instructions, so it should work fine now. I would strongly urge anyone to stick with yum as much as possible for software installs as it greatly simplifies keeping up to date and maintaining compatibility and, therefore, reliability.

—Brazen


As of 01/28/08
This is a great guide. I’m currently setting up 2 servers for my company, one production nginx/mongrel cluster with master mysql db, and a second backup nginx/mongrel cluster w/slave mysql db. I’ll post my info and config for this soon.

— Jason

Here’s my nginx setup/config.

Nginx install and config
————————————
(This install works with the above configuration)

If you want to install via yum/rpms, see this page:

http://www.centos.org/modules/newbb/viewtopic.php?topic_id=11821

For a manual compile, see this page:

http://wiki.codemongers.com/NginxGettingStarted

I’m assuming for the rest of these instructions that that you’ve installed via yum/rpms, which puts the nginx config under /etc/nginx.

The config is actually super easy. First edit the /etc/nginx.conf file. On line 33 (right after #gzip on), I added these lines for the mongrel cluster:


    upstream mongrel {
      server 127.0.0.1:8000;
      server 127.0.0.1:8001;
      server 127.0.0.1:8002;
    }

In the server config, do the following:

Change the
server_name localhost;
line to whatever your server host name is. In the


location / { }

block you’ll need to configure a few things; the root file location, what the index page is, proxy settings, and any static content nginx should serve up. Here’s what my location config looks like:

location / {
            root   /var/www/apps/testapp/current;
		# This assumes you have a controller
		# named 'index'. If not, use index.html
		# or whatever your index page is.
            index  index;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
proxy_max_temp_file_size 0;

if (-f $request_filename) {
break;
}
if (-f $request_filename.html) {
rewrite (.) $1.html break;
}
if (-f $request_filename.gif) {
rewrite (.
) $1.gif break;
}
if (-f $request_filename.jpg) {
rewrite (.) $1.jpg break;
}
if (-f $request_filename.js) {
rewrite (.
) $1.js break;
}
if (-f $request_filename.swf) {
rewrite (.) $1.swf break;
}
if (-f $request_filename.png) {
rewrite (.
) $1.png break;
}
if (-f $request_filename.txt) {
rewrite (.) $1.txt break;
}
if (-f $request_filename.css) {
rewrite (.
) $1.css break;
}
if (-f $request_filename.pdf) {
rewrite (.*) $1.pdf break;
}

# Only proxy thru rails calls
if (!-f $request_filename) {
proxy_pass http : // mongrel;
break;
}

}

(Take out the spaces in the above proxy_pass line)

The above will serve up all static assets and only proxy through to the various mongrel instances if the request type cannot be matched. There are also some good settings via Ezra’s conf file:

http://brainspl.at/nginx.conf.txt

That’s it, the nginx config file is fairly simple.


As of 29/1/08
For CentOS5 64 bit if I used yum to install initial ruby packages I had things going into the /usr/lib64 directory which kinda felt wrong, this manifested itself later in the install in problems getting RMagick to work.

As a general guide (and everytime I’ve broken it I’ve wished I hadn’t) try and compile everything natively first into /usr/local…

So how I got my first CentOS5 up and working was doing the aforementioned yum install, ended up rm -rf /usr/lib64/ruby path, then compiling ruby 1.8.6 from scratch, followed on with the rubygems compile and install (as per instructions above), updating the gems, then mongrel/mongrel cluster etc.

Go here to compile and install RMagick on CentOS5. Verified working.

— Rowan Hick


Yeah sorry I have not done any testing using 64-bit CentOS and hadn’t even thought about it having differences that could affect Ruby.

I’m wondering though if you could get a workable system just by symlinking the ruby files from /usr/lib64/ into /usr/lib/. Just an idea.

—Brazen


I had to put trailing slashes on:

ProxyPass /test balancer://testapp*/*
ProxyPassReverse /test balancer://testapp*/*

Or else I would get this error in Apache:

proxy: No protocol handler was valid for the URL /rails/info/properties. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.

—Felix Khazin