public
Description: Rails deployment and configuration management done right. ShadowPuppet + Capistrano == crazy delicious
Home | Edit | New

Step by Step Instructions

Here is step by step directions to deploying your Rails app to a fresh Ubuntu server.

Step 1. Initial server setup

You’ll need an Ubuntu box to get started. After the basic install you’ll need to run a few commands to get the box ready.

Log into your server via ssh & change your root password

ssh root@123.123.123.123
passwd

Change 123.123.123.123 with the IP of your server everywhere you see it.

Add a new user called rails and give it a password

adduser rails

Give it sudo permissions

visudo

And add this below “root ALL=(ALL) ALL

rails   ALL=(ALL) ALL

On your local machine:

  ls ~/.ssh/

If it shows you id_rsa.pub, skip this next step (which generates the ssh):

ssh-keygen

Next, we’re going to copy your public key to your server so you can securely connect to it without having to enter your password. Again on your local machine, run:

scp ~/.ssh/id_rsa.pub rails@123.123.123.123:/home/rails/

Now on your server, run this:

mkdir /home/rails/.ssh
mv /home/rails/id_rsa.pub /home/rails/.ssh/authorized_keys
chown -R rails:rails /home/rails/.ssh
chmod 700 /home/rails/.ssh
chmod 600 /home/rails/.ssh/authorized_keys

Let’s make it easy to connect with your server. On your local machine, open ~/.ssh/config file with textmate or your fav text editor:

mate ~/.ssh/config

and add your info using the template below:

Host blackbox
  Hostname 123.123.123.123
  User rails

Don’t forget to change your IP as well as pick a name for your server that makes sense.

Save & close that file. Now you should be able to connect to your server by just typing:

ssh blackbox

Okay, we’ve got one final thing we need to get your initial server setup- give your server access to your github account (which you don’t need but most people have it so you should probably get one, even if it’s just to contribute to open source stuff.)

Once you’ve ssh’d into your server as the rails user, generate your ssh key similar to how to you did it on your local machine:

ssh-keygen

It will ask you if you want to give it a password. For ease of use, you should just leave the password blank here. When you’re done, you want to output the public key it generates by running this:

cat /home/rails/.ssh/id_rsa.pub

Copy the key that is outputted and enter it into your github account which you can usually do at: https://github.com/account

Alright, you’ve now completed step 1, which was getting the initial server ready.

Step 2 – Adding moonshine to your project & configuring it.

In this step, you’ll add the moonshine plugin to your project & configure it properly so it knows what you want it to do on your server.

On your local machine, go to your rails project directory and add the plugin:

ruby script/plugin install git://github.com/railsmachine/moonshine.git

Add all the gems your project needs to your environment.rb file.

Next, run the moonshine generator to create the necessary files:

ruby script/generate moonshine

This should make an output like this:

  After the Moonshine generator finishes don't forget to:

  - Edit config/moonshine.yml
  Use this file to manage configuration related to deploying and running the app: 
  domain name, git repos, package dependencies for gems, and more.

  - Edit app/manifests/application_manifest.rb
  Use this to manage the configuration of everything else on the server:
  define the server 'stack', cron jobs, mail aliases, configuration files 

        create  app/manifests
        create  app/manifests/templates
        create  app/manifests/application_manifest.rb
        exists  app/manifests/templates
        create  app/manifests/templates/README
        exists  config
        create  config/moonshine.yml
        create  config/gems.yml

As the output suggests, the next thing you should do is edit config/moonshine.yml

Edit config/moonshine.yml

First give your app a name (such as your_app_name), pick where the files of your app will reside (by setting deploy_to) & tell moonshine where to grab your application from (by setting repository)


:application: your_app_name
:deploy_to: /srv/your_app_name
:repository: git@github.com:username/your_app_name.git

Note: if you are using subversion you will want to add the following:


:scm: subversion
:scm_username: svnuser
:scm_password: svnpass

Next, if your app has directories in the public directory that need to stay persistent, uncomment this:

:app_symlinks:
  - uploads

If you don’t, the files will be removed every time you deploy since it gets the files from your git repo and it won’t be there.

You’ll also probably want to uncomment the local_config section, which will upload your local copy of /config/database.yml to the server, while bypassing your git repo.

:local_config:
  - config/database.yml

See the moonshine.yml examples for information on setting up SSL, changing the timezone, configuring Apache, Passenger, MySQL, and more.

Now save your file and from your terminal/command-line, run rake moonshine:gems to generate a config/gems.yml file, which will contain a list of gems that your app needs based on what you specified in config/environment.rb.

Edit app/manifests/application_manifest.rb

The application manifest is where all of the real customization of your server happens. Here you can define packages and gems to install, cron jobs, log rotation, mail aliases, configuration files, and more.

Recipes

The file that is generated uses the default_stack recipe. What this means is it will install Apache, Passenger, Rails, NTP, Cron, Postfix and whichever database you specified in database.yml: MySQL, Postgres, or sqlite. For most applications, the default will work fine. Checkout vendor/plugins/moonshine/lib/moonshine/manifest/rails.rb to see the actual method if you’d prefer to customize your base stack.

Plugins

Moonshine plugins allow you to easily add on to capabilities of your manifest. Here’s an example of setting up SSH on an alternate port and locking the system down with iptables. First, install the plugins:

script/plugin install git://github.com/railsmachine/moonshine_iptables.git
script/plugin install git://github.com/railsmachine/moonshine_ssh.git

Now add these lines to your application manifest:


configure({
:ssh => { :port => 2222, :allow_users => [‘rails’] },
:iptables => { :rules => [
‘-A INPUT -m state —state RELATED,ESTABLISHED -j ACCEPT’,
‘-A INPUT -p icmp -j ACCEPT’,
‘-A INPUT -p tcp -m tcp —dport 25 -j ACCEPT’,
‘-A INPUT -p tcp -m tcp —dport 2222 -j ACCEPT’,
‘-A INPUT -p tcp -m tcp —dport 80 -j ACCEPT’,
‘-A INPUT -p tcp -m tcp —dport 443 -j ACCEPT’,
‘-A INPUT -s 127.0.0.1 -j ACCEPT’,
‘-A INPUT -p tcp -m tcp —dport 8000:10000 -j ACCEPT’,
‘-A INPUT -p udp -m udp —dport 8000:10000 -j ACCEPT
]}
})
plugin :iptables
plugin :ssh
recipe :iptables
recipe :ssh

N.B. After you deploy your application with the above settings, SSH will be listening on port 2222. If you do this, be sure to update your ~/.ssh/config to specify the new port:

Host blackbox
  Hostname 123.123.123.123
  User rails
  Port 2222

You don’t need to update this until after your first deployment since it’s still listening on the default SSH port until then.

Additional configuration

The application_packages method is a good place to define the custom components for your server. There are tons of examples in the comments, and more on the Shadow Puppet overview page.

Bootstrap rake tasks

Moonshine allows you to define a rake task called moonshine:app:bootstrap that will be run after the first deployment. Create a rake file- lib/tasks/bootstrap.rake, for example- and add the task there:


namespace :moonshine do
namespace :app do
task :bootstrap do

  1. define your bootstrap task here
    end
    end
    end

Bootstrap data

If you need to load initial data into your application, add fixture files for this data into db/bootstrap

Capify your project

Once you’ve got your app configured, capify your app by running the following code while inside your rails app directory:

capify .

Now open config/deploy.rb and replace its content with this:

server "blackbox", :app, :web, :db, :primary => true

Replace blackbox with the name you give your server in your ~/.ssh/config file.

Next, store the files to your repo and push it to your git repo:

git add . && git commit -am "added moonshine" && git push

Step 3 – Deploy

Once all the configuration is done, you’ll see all your hard work pay off.

First thing you’ll do is setup the server. From your rails app root, run this:

cap deploy:setup

Once that is done, run this:

cap deploy

At this point, you should be done and your app should be live.

That’s it! You should be good to go now. And if you’re in the market for managed hosting, particularly for your Rails apps, definitely check out RailsMachine, creators of moonshine!

Questions

  • Is there a way I can get detailed outputs for errors?
  • What about gems that I’ve got in the vendor/gems folder? Right now, my spree app fails to deploy because it requires the HAML gem 2.1.0 which is in the /vendor/gems folder but not available over the internet.
    • One approach that works is to manually go into the config/gems.yml file and remove the gems that are in /vendors/gems/
Last edited by andrewroth, Wed Aug 19 18:15:16 -0700 2009
Home | Edit | New
Versions: