12.11.2013

Deploying a Rails App Remotely With Capistrano

Modify Apache Config

1. Capistrano inserts a directory named "current" so change the DocumentRoot of the .conf file:
$ sudo vi /etc/httpd/sites-available/depot.conf
DocumentRoot /home/samdc/prod/depot/current/public
<Directory /home/samdc/prod/depot/current/public>

Setup Git Server

2. Create an empty repository on the git server
$ mkdir -p ~/git/depot.git
$ cd ~/git/depot.git
$ git --bare init
3. Generate a public key and use it to give ourselves permission to access our own server
$ test -e ~/.ssh/id_dsa.pub || ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/samdc/.ssh/id_dsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/samdc/.ssh/id_dsa.
Your public key has been saved in /home/samdc/.ssh/id_dsa.pub.

$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
4. Make sure that proper permissions are set for ssh. I got another post related to this..
$ chmod g-w /home/samdc
$ chmod 700 /home/samdc/.ssh
$ chmod 600 /home/samdc/.ssh/authorized_keys

Prepare Application

5. Update Gemfile to indicate that we are using capistrano
$ vi Gemfile
gem 'rvm-capistrano', group: :development
6. Install capistrano using bundle install
$ bundle install
7. If you havent done so, put project under git
$ cd app_directory
$ git init
$ git add .
Ignore files
$ vi .gitignore
.ruby-gemset
.ruby-version
$ git commit -m "initial commit"
8. Copy all the gems required by your application into the vendor/cache folder. This also includes dependencies required by the gems. This helps because at the time of deployment you can just run bundle install --local to avoid dependency on the gems repository (rubygems.org) and install all the gems from the cached folder
$ bundle package
$ git add Gemfile.lock vendor/cache
$ git commit -m "bundle gems"
9. Push our code to the Git server
$ git remote add origin ssh://samdc@host/~/git/depot.git
$ git push origin master

Remote Deployment

1. Add necessary capistrano files to the project
$ capify .
[add] writing './Capfile'
[add] writing './config/deploy.rb'
[done] capified!
2. Modify Capfile and uncomment one line
load 'deploy/assets'
3. Modify deploy.rb, this is the recipe that we will use for deployment
require 'bundler/capistrano'

# be sure to change these
set :user, 'samdc'
set :domain, 'depot.com'
set :application, 'depot'

# adjust if you are using RVM, remove if you are not
set :rvm_type, :user
set :rvm_ruby_string, 'ruby-2.0.0-p353'
require 'rvm/capistrano'

# file paths
set :repository,  "#{user}@#{domain}:git/#{application}.git" 

# stages
set :stages, ["staging", "production"]
set :default_stage, "staging"

# distribute your applications across servers (the instructions below put them
# all on the same server, defined above as 'domain', adjust as necessary)
role :app, domain
role :web, domain
role :db, domain, :primary => true

# you might need to set this if you aren't seeing password prompts
# default_run_options[:pty] = true

# As Capistrano executes in a non-interactive mode and therefore doesn't cause
# any of your shell profile scripts to be run, the following might be needed
# if (for example) you have locally installed gems or applications.  Note:
# this needs to contain the full values for the variables set, not simply
# the deltas.
# default_environment['PATH']=':/usr/local/bin:/usr/bin:/bin'
# default_environment['GEM_PATH']=':/usr/lib/ruby/gems/1.8'

# miscellaneous options
set :deploy_via, :remote_cache
set :scm, 'git'
set :branch, 'master'
set :scm_verbose, true
set :use_sudo, false
set :normalize_asset_timestamps, false

namespace :deploy do
  desc "cause Passenger to initiate a restart"
  task :restart do
    run "touch #{current_path}/tmp/restart.txt" 
  end

  desc "reload the database with seed data"
  task :seed do
    deploy.migrations
    run "cd #{current_path}; rake db:seed RAILS_ENV=#{rails_env}"
  end
end
4. Create staging and production deployment files
$ cd config
$ mkdir deploy
$ vi production.rb
require "rvm/capistrano"                  # Load RVM's capistrano plugin.
set :rvm_ruby_string, 'ruby-2.0.0-p353'   # Or whatever env you want it to run in.
set :rvm_bin_path, '/home/samdc/.rvm/bin'
server "deployment_server_name", :app, :web, :db, :primary => true
set :deploy_to, "/home/samdc/apps/depot"
$ vi staging.rb
require "rvm/capistrano"                  # Load RVM's capistrano plugin.
set :rvm_ruby_string, 'ruby-2.0.0-p353'   # Or whatever env you want it to run in.
set :rvm_bin_path, '/home/samdc/.rvm/bin'
server "deployment_server_name", :app, :web, :db, :primary => true
set :deploy_to, "/home/samdc/apps/depot_staging"
5. First time deployment, setup basic dir structure on deployment server
$ cap deploy:setup
Uncomment default_run_options line in deploy.rb if there is any failure.

6. Check the config.
$ cap deploy:check
7. We can load seed data.
$ cap deploy:seed
8. Deploy
$ git add .
$ git commit -m "add cap files"
$ git push
$ cap deploy
Remember this deploys to the default "staging" server. To deploy to production...
$ cap production deploy
9. Rollback deployment
$ cap deploy:rollback

Further reading:
http://guides.beanstalkapp.com/deployments/deploy-with-capistrano.html
https://github.com/capistrano/capistrano/wiki/2.x-From-The-Beginning

No comments:

Post a Comment