Setup Guide: Rails Stack with Passenger, RVM, Bundler, Apache, and MySQL on Ubuntu
Here’s how I like to setup a Rails stack on Ubuntu 10.4. This recipe makes use of Apache as the webserver with Passenger to serve Rails, MySQL as the database, RVM (installed system-wide) to manage Ruby (I select Ruby 1.9.2 as the default these days), and the latest Rails, which is 3.0.3 as of this morning, and Bundler for installing gems. It also makes a system user for you to use, and a deploy user for deployments with Capistrano.
This isn’t a script, so don’t try a cut-n-paste here. You’ll want to enter the commands one by one. It won’t take long, but things seem to go better if you have a caffeinated beverage on hand when you start out.
This also isn’t a comprehensive guide as much as it is a quick-start recipe for people who are already competent on the command line. There’s more you can and should do afterwards regarding security, backups, log rotation, and more, but those things are outside the scope of this article.
And as usual, follow these steps at your own risk. I accept no liability if you break your server, website, or anything else.
echo -e "\n111.222.333.444 server.example.com server\n" >> /etc/hosts echo "servername" > /etc/hostname
Replace 111.222.333.444 with your IP, and servername.example.com and servername with the name of your server in the lines above.
hostname -F /etc/hostname dpkg-reconfigure tzdata apt-get -y update apt-get -y upgrade apt-get -y install apache2 apache2-prefork-dev autoconf bison build-essential curl git-core imagemagick libapr1-dev libaprutil1-dev libcurl4-openssl-dev libid3-3.8.3-dev libmysqlclient16 libmysqlclient16-dev libreadline6 libreadline6-dev libsqlite3-0 libsqlite3-dev libssl-dev libxml2-dev libxslt-dev libyaml-dev mysql-client mysql-common mysql-server openssl sqlite3 zlib1g zlib1g-dev bash < <( curl -L http://bit.ly/rvm-install-system-wide ) source /usr/local/lib/rvm rvm install ruby-1.9.2 rvm --default use 1.9.2
If you want to use a different ruby, you’d just replace your version in the lines above where you see ruby-1.9.2 and 1.9.2.
echo "[[ -s \"/usr/local/lib/rvm\" ]] && source \"/usr/local/lib/rvm\"" > /etc/profile.d/rvm.sh chmod +x /etc/profile.d/rvm.sh gem install fastthread bundler capistrano sqlite3-ruby mysql rails passenger passenger-install-apache2-module echo "LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p136/gems/passenger-3.0.2/ext/apache2/mod_passenger.so" > /etc/apache2/mods-available/passenger.load echo -e "PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p136/gems/passenger-3.0.2\nPassengerRuby /usr/local/rvm/wrappers/ruby-1.9.2-p136/ruby" > /etc/apache2/mods-available/passenger.conf a2enmod rewrite a2enmod passenger mysql -u root -p create database mydatabase; grant all privileges on mydatabase.* to 'myusername'@'localhost' identified by 'myprecious' with grant option; flush privileges; exit
Replace mydatabase with the name of the database, myusername with the name of an app-specific username, and pick a password other than myprecious.
adduser somebody adduser deploy adduser somebody sudo adduser somebody rvm adduser deploy rvm
These lines create two users, one for you with sudo access privs (change somebody in the lines above to your own name), and a deploy user. It also adds them to the necessary groups.
su - somebody ssh-keygen -t rsa exit su - deploy ssh-keygen -t rsa exit
This makes the ssh keys you’ll want to add to your Git repository (or GitHub) as account and deploy keys, respectively. Again, replace somebody with your username.
Then, on your local machine (if you’re running a *NIX-style OS) you’ll want to scp your local ssh keys to the new accounts on the server.
scp -p ~/.ssh/id_rsa.pub somebody@111.222.333.444:.ssh/authorized_keys scp -p ~/.ssh/id_rsa.pub deploy@111.222.333.444:.ssh/authorized_keys scp deploy@111.222.333.444:.ssh/id_rsa.pub ./deploy-key
Be sure to replace 111.222.333.444 with the IP address of the server.
Test your ability to ssh to the server with the following line:
ssh 111.222.333.444
You should be logged in without having to enter a password.
If it worked, back on the server, secure things up by editing /etc/ssh/sshd_config.
sudo vi /etc/ssh/sshd_config
Find the following two lines (they’re not adjacent to each other) and change them as follows:
PermitRootLogin no PasswordAuthentication no
Save the file and quit vi, then restart the SSH server:
sudo /etc/init.d/ssh restart
Now, setup a basic Rails site with Apache and Passenger, changing example.com to your domain.
sudo mkdir -p /var/www/sites/example.com
sudo chown deploy.deploy /var/www/sites/example.com
sudo cat > /etc/apache2/sites-available/example.com <<EOF
<VirtualHost *:80>
ServerName example.com
DocumentRoot "/var/www/sites/example.com/current/public"
ErrorLog "/var/log/apache2/example.com-error_log"
CustomLog "/var/log/apache2/example.com-access_log" common
<Directory "/var/www/sites/example.com/current/public">
Options All
AllowOverride All
Order allow,deny
Allow from all
</Directory>
RewriteEngine On
# Remove the www
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
</VirtualHost>
EOF
sudo a2ensite example.com
sudo a2dissite default
su - deploy
mkdir -p /var/www/sites/example.com/shared/config/
cat > /var/www/sites/example.com/shared/config/database.yml <<EOF
production:
adapter: mysql2
encoding: utf8
reconnect: false
database: mydatabase
pool: 5
username: myusername
password: myprecious
socket: /var/run/mysqld/mysqld.sock
EOF
exit
sudo /etc/init.d/apache2 restart
Be sure to replace mydatabase with the name of the database you created earlier, myusername with the username you setup, and myprecious for the password you used.
Then, back on your local machine (assuming you’ve added the ssh keys to your Git repository correctly), you should be able to deploy your app.
If you want to have Capistrano automatically install your app’s gems for you, add these lines at the top of your app’s config/deploy.rb:
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require 'rvm/capistrano'
require 'bundler/capistrano'
Then, when you deploy, your gems will be setup for you.
A first-time deploy like this:
cap deploy:setup cap deploy
If you don’t want to auto-run bundler on deploy, you’ll need to do it manually on the server (as the deploy user) like this:
su - deploy cd /var/www/sites/example.com/current bundle install
Enjoy your new server and app.
