Running a Rails 3.1 app in production on CentOS 6 / MySQL
Here is a blow-by-blow list of commands I issued and errors I encountered/made while deploying a Rails 3.1 app to CentOS 6. I’ve found CentOS much easier to work with than Ubuntu for Ruby environments. Hope this is helpful for someone.
$root useradd USER
# add USER to sudoer's file. I used this line: USER ALL=(ALL) ALL
$root visudo
$root su - USER
Install and start ssh server at login for ssh access:
$ sudo yum install openssh-server
$ sudo echo "/sbin/service sshd start" >> /etc/rc.d/rc.local
Important libraries required by RVM, Ruby, and Git:
$ sudo yum install git gcc-c++ make patch zlib-devel openssl-devel readline-devel
Install RVM as single user:
$ bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )
Install VMWare Tools through the CentOS GUI (my server happens to be a VMWare VM):
$ rvm install 1.9.2
Install MySQL. After installation, use the ‘mysql’ and ‘mysqladmin’ commands to set up your MySQL users and databases:
$ sudo yum install mysql-server mysql mysql-devel
$ cd RAILS_PROJECT_DIR
$ rake db:migrate RAILS_ENV=production
#=> Could not find a JavaScript runtime
Oops, I am used to OS X which comes with a JavaScript runtime. I installed Node.js for the V8 JS runtime. Go here for install instructions: http://nodejs.org. It should be as simple as ./configure ; make ; make install. The libraries below were Node dependencies:
$ sudo yum install python libssl-dev
Then:
$ cd RAILS_PROJECT_DIR
$ rake db:migrate RAILS_ENV=production
#=> success!
Install and set up Passenger:
$ sudo yum install curl-devel httpd-devel apr-devel apr-util-devel
$ gem install passenger
$ passenger-install-apache2-module
Passenger will ask you to add 8 or so lines to the Apache config file (I found my config file here: /etc/httpd/conf/httpd.conf). I’ve included lines I used below as an example:
LoadModule passenger_module /home/USER/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9/ext/apache2/mod_passenger.so
PassengerRoot /home/USER/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9
PassengerRuby /home/USER/.rvm/wrappers/ruby-1.9.2-p290/ruby
...
<VirtualHost *:80>
ServerName localhost
DocumentRoot /var/www/html/RAILS_PROJECT_DIR/public
<Directory /var/www/html/RAILS_PROJECT_DIR/public>
AllowOverride all
Options -MultiViews
</Directory>
</VirtualHost>
$ sudo apachectl -k start
#=> httpd: Syntax error on line 202 of /etc/httpd/conf/httpd.conf: Cannot load /home/USER/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9/ext/apache2/mod_passenger.so into server: /home/USER/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9/ext/apache2/mod_passenger.so: cannot open shared object file: Permission denied
After googling a bit, I found that many people blamed this issue on Selinux. Selinux is enabled by default in CentOS 6. Switching Selinux off fixed this problem. I should probably learn Selinux and create my own ruleset, but I wanted to get something running today.
$ sudo emacs /etc/selinux/config
# set: SELINUX=disabled
$ su - USER # create a new login shell to be sure that Selinux options are refreshed
$ sestatus # confirm that Selinux is disabled
#=> SELinux status: disabled
$ sudo apachectl -k start
#=> ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
Oops, need to start MySQL:
$ service mysqld start
$ rake db:migrate RAILS_ENV=production
#=> success
At this point, your server should be serving your app. In my particular environment, I had add a firewall rule to iptables:
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:http
You can check your firewall rules with this command:
$ iptables -L
Depending on how you like to manage your assets in Rails 3.1, you may see this error when hitting your app:
ActionView::Template::Error (application.css isn't precompiled)
I chose to precompile my assets:
$ rake assets:precompile
$ emacs RAILS_PROJECT_DIR/config/environments/production.rb #config.assets.compile = true
Feel free to add suggestions or other problems encountered in the comments!