On the Rails: Bootstrap a Rackspace Cloud Server
I’m going to assume you already have a Rackspace Cloud account. (If you don’t, I’ll leave it to you to rectify the situation.)
Create a Server
Follow these steps to create a Rackspace Cloud Server:
- Log in to the control panel at manage.rackspacecloud.com.
- Click on Hosting in the left nav bar, then Cloud Servers.
- Click Add New Server.
- Now, it’s time to pick how much RAM and storage space you want (and how much you want to pay per hour). The default, 256 MB RAM and 10 MB storage at $0.015 an hour, is fine for our purposes.
- Scroll down and give your server a name, like, oh, I don’t know, “Fred” or “Rails-Test” or something.
- Next, choose your favorite flavor of ice cream operating system. I like Ubuntu 8.04.2 LTS (hardy). Yum. No, wait, I mean apt-get.
- Finally, click Add Cloud Server.
While it is building your server according to your specifications, the control panel will give you an IP address and a root password. This information will also be emailed to the primary contact email address associated with your account. Be sure to keep it in a safe place.
Once your server is ready, you can SSH into it. In a Terminal, issue the following command:
ssh root@<your_server_IP_address>
Enter your root password when prompted.
Bootstrap That Baby
Marc Chung (formerly of OpenRain, now of redPear) has published, as a GitHub repo, a collection of handy-dandy shell scripts to aid us in bootstrapping a Rails server. I have forked his repo and made a few updates to a few of the scripts. Go here and start to follow the instructions in the README. Update and upgrade Ubuntu, install Git, and clone the Git repo to get the scripts.
Set Up Password-less Authentication
Before we start running scripts, we ought to make it so that we can connect to our remote server from our local Mac without having to type in a password, while at the same time ensuring that no one besides us can connect in this way. (This is necessary for the deployment process to work, as we’ll see in our next episode.) We’ll achieve this by adding the public key we generated earlier on our Mac to an “authorized_keys” file on the remote server. (reference)
- On the Mac, run “cat ~/.ssh/id_rsa.pub” and copy the result to the clipboard.
- On the server, run “pico bootstrap/config/root_authorized_keys”. Paste the key into this file and save it (Ctrl-O).
- On the server, run “pico bootstrap/config/default_authorized_keys”. Paste the key into this file and save it (Ctrl-O).
Edit/Run Scripts
We are going to be running these scripts in order:
00-core.sh 05-ruby.sh 10-misc.sh 15-postgresql.sh 25-apache.sh 36-passenger.sh 40-rails-apps.sh
You can run the core, ruby, and misc scripts out of the box with no command-line arguments.
You should edit the postgresql script before running it, to customize one of the config options. Namely, edit the “add addresses” block in that file. Change the IP addresses to match the machines from which you’ll be remotely connecting to your PostgreSQL database server, if any. If there are none, you can delete this block.
When running the postgresql script, you have to provide four arguments:
- your admin database user’s password
- your normal database user’s username (in our case, railstest)
- your normal database user’s password (we’ll have to add this to our app in railstest/config/database.yml too)
- the name of the database you want to create for your app (in our case, railstest_production)
Note: This script will install PostgreSQL 8.3 instead of 8.4, as there’s no Ubuntu hardy package for 8.4.
The apache script can be run with no arguments.
The passenger script takes one argument:
- the public hostname of your server
After running the passenger script, let’s edit one of our Apache config files:
pico /etc/apache2/sites-available/default
Along with the addition and modification of a couple other options, we’re going to change the DocumentRoot to the directory where our app is going to live. Edit the VirtualHost block of the file to look like this:
<VirtualHost *>
ServerAdmin youremail@yourdomain.com
ServerName rails.example.com
DocumentRoot /var/local/railstest/current/public
RailsBaseURI /
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/local/railstest/current/public>
Options Indexes FollowSymLinks -MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
...
Save the file with Ctrl-O. Exit with Ctrl-X, and then run:
apache2ctl -k graceful
to restart Apache.
Finally, let’s run the rails-apps script with no arguments.
Post-Scripts
After we’ve finished running the scripts, we want to make it so that the server can connect to GitHub and access our app’s code repo during the deployment process.
Let’s generate an SSH keypair on the remote server, but as the “app” user instead of root, since that’s the one that we’ll be running the deployment process as:
sudo su app -c "ssh-keygen -t rsa"
As we did earlier with the keys generated on our Mac, we’ll paste the public key into our GitHub config:
- Run “cat /home/app/.ssh/id_rsa.pub” on the server and copy the result to the clipboard.
- On GitHub, go to your repo’s home page and click the “Admin” button.
- Under the “Deploy Keys” section, click “Add another deploy key”.
- Give the deploy key a title, like “Production App Server” or something.
- Paste the contents of the clipboard into the “Key” textarea.
- Click “Add Key”.
We’re done bootstrapping! Our Rackspace Cloud Server is now prepped and ready to run our app upon its arrival. Be sure to type “exit” to log out and close your SSH connection.
One More Thing
Before we call it quits for this episode, let’s go back to our Mac for a second and make sure we add the normal database user’s password to our config file. In Terminal, from our home directory, do the following:
cd workspace/railstest pico config/database.yml
Go down to the empty “password:” line in the “production” section at the end of the file and add the password you specified above as the third argument to the postgresql install script. Type Ctrl-O to save the file.
Next Time
In our next episode, we’ll install Capistrano and deploy our app to this baby! See you then!