Been having to do quite a bit of this kind of thing at work lately, and in order to make it as painless as possible for myself, I've had to write it down. So here are my notes on building a Ubuntu, Nginx, Passenger & Rails stack from a clean Ubuntu 12.04 server image.
First things first, note that I do not use RVM like every other guide on the internet suggests, because frankly I've wasted so many hours on it, and it's so easy to install Ruby from source or use the package manager that I just can't see the point in using it in production at all (unless you need multiple rubies for whatever reason).
I recommend creating a 'deploy' user to use for ... deployment. Here are my notes in their raw form, I'll probably come back and tart this up when I get the time:
- Alias the server for SSH:
- Set up SSH keys:
- Get the server libraries up-to-date:
- Install dependencies:
- Install ruby. You can either install it from source, install using RVM (if you're a sadist), or just use the package manager:
- If the above command didn't install RubyGems (check with: gem -v), then see the RubyGems docs.
- Now that RubyGems is installed, install Bundler:
- Install Nginx with Passenger:
- Set up Nginx init script to start, stop and restart Nginx:
- Set up your Nginx config file (/opt/nginx/conf/nginx.conf), you should point to your Rails app's public folder. Passenger will have created a shell set up for you to edit.
- Deploy your app to the server. (We use Capistrano, but this short guide isn't about that aspect, so deploy as you wish.)
- Solve any complications that might have arisen in the above step, then set up the config/database.yml to connect to your database server.
- Start Nginx:
on your local machine:
then create a file in this folder called config with the following contents (replace values as appropriate):
Host rs Hostname <server_ip> User deploy
ssh-keygen -t dsa
Accept defaults for all options. Now copy your public key to the remote server.
scp ~/.ssh/id_dsa.pub deploy@rs:~/.ssh/authorized_keys
For further keys, you must add them to the bottom of a file on their own line.
sudo apt-get -y update
sudo apt-get install build-essential zlib1g-dev libssl-dev libreadline-dev libyaml-dev libcurl4-openssl-dev curl git-core libxslt-dev mysql-server mysql-client libmysqlclient-dev
sudo apt-get install ruby1.9.1
Yes, this does install ruby 1.9.3, if you were wondering.
sudo gem install bundler
sudo gem install passenger sudo passenger-install-nginx-module
Choose "download, compile and install nginx for me" and then accept default options for all.
wget -O init-deb.sh http://library.linode.com/assets/660-init-deb.sh sudo mv init-deb.sh /etc/init.d/nginx sudo chmod +x /etc/init.d/nginx sudo /usr/sbin/update-rc.d -f nginx defaults
You can now control Nginx with this script and the commands:
sudo /etc/init.d/nginx start sudo /etc/init.d/nginx stop sudo /etc/init.d/nginx restart
sudo /etc/init.d/nginx start
You might have to install some other stuff that your app depends on, such as Redis and wkhtmltopdf in our case, but other than that you should be up and running. It's a pretty simple process if you do things right, but having spent plenty of hours with bundler errors on deployment, etc, I know where some of the nastier pitfalls can be.