Skip to content

Instantly share code, notes, and snippets.

@supairish
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save supairish/c9dd3234717a35234d44 to your computer and use it in GitHub Desktop.
Save supairish/c9dd3234717a35234d44 to your computer and use it in GitHub Desktop.

Goals of this tutorial:

  • deploy a new Rails app with capistrano
  • make it fast (total process takes less than 5 minutes)
  • make it simple (no unecessary config)
  • manual ssh to the server not required

Rails application stack:

  • nginx
  • unicorn
  • postgresql

This tutorial presumes:

  • you already bought a server or a VPS
  • the server is provisioned for Rails (all required packages installed)

If you still need to provision the server, there's a easy-chef-rails project that should help you with that.

Step 1: install required gems

In Gemfile:

group :development do
  gem 'capistrano', '>= 3.2.1'
  gem 'capistrano-rbenv', '~> 2.0'           # idiomatic rbenv support
  gem 'capistrano-rbenv-install'             # ensures the right ruby version is installed
  gem 'capistrano-bundler', '~> 1.1.2'       # support for bundler
  gem 'capistrano-rails', '~> 1.0'           # automatic migrations and asset compilation
  gem 'capistrano-unicorn-nginx', '~> 2.0'   # plug-n-play nginx and unicorn
  gem 'capistrano-postgresql', '~> 3.0'      # plug-n-play postgresql
  gem 'capistrano-safe-deploy-to', '~> 1.1'  # ensures deploy path for the app exists
  gem 'capistrano-ssh-doctor'                # helps with debugging ssh-agent forwarding
end

and now install gems:

$ bundle install

Step 2: set up Capistrano

The following command will create required capistrano files in your project:

$ bundle exec cap install

By adding the following to the Capfile, we'll include all the gems installed in the previous step:

require 'capistrano/rbenv'
require 'capistrano/rbenv_install'
require 'capistrano/bundler'
require 'capistrano/rails'
require 'capistrano/unicorn_nginx'
require 'capistrano/postgresql'
require 'capistrano/safe_deploy_to'
require 'capistrano/ssh_doctor'

Capistrano itself requires some configuration love. In config/deploy.rb (file created by capistrano installer):

lock '3.2.1'

# application name
set :application, 'myapp'

# deploy directory on the server. Will be ie: '/var/www/myapp_production'
set :deploy_to, -> { "/var/www/#{fetch(:application)}_#{fetch(:stage)}" }

# capistrano will download an app from "master" branch of this repository:
set :repo_url, 'git@github.com:you/your_repo.git'

# change to ruby version you need
set :rbenv_ruby, '2.0.0-p353'

and lastly, capistrano has a stage-related files since version 3.0. We'll deploy to production, so edit config/deploy/production.rb (you can delete other content from that file):

# ssh configuration options. Make sure the following works: $ ssh <deploy_user>@<server_ip>
server '<server_ip>', user: '<deploy_user>', roles: %w{web app db}

# only if your app already has a domain, then add:
# set :nginx_server_name, 'mydomain.com'

Step 3: ensure ssh-agent forwarding

To debug you ssh-agent setup run:

$ bundle exec cap production ssh:doctor

If you get any errors in the report at the end, fix them by following the instructions. Important: order matters so start by solving the first error you get. It is very probable that "solving" one or two initial errors will actually make everything work. A lot of the checks are inter-dependent. So don't be discouraged if you see a lot of the errors in the beginning.

Once ssh:doctor report is successful, you're ok with proceeding to the next step.

Step 4: setup and deployment

This is the easiest step. To setup the server:

$ bundle exec cap production setup

and finally, your server is ready for deployment:

$ bundle exec cap production deploy

sit back and relax!

The following has been done on the server during the setup phase:

  • if not present, required ruby (defined with rbenv_ruby) will be installed
  • the application database is created on the server
  • nginx and unicorn are properly configured

And these are roughly the deploy steps:

  • app itself will be cloned from the repo
  • migrations will run
  • assets will precompile

... along with a bunch of smaller tasks.

When it's all done, hit <server_ip> (or enter domain) in the browser and confirm your app is live!

Capistrano workflow

Now that the app is live, how do you deploy new application updates? Luckily, capistrano makes that trivial.

  • make changes to the app and commit them: $ git commit "changes"
  • push changes to online repo: $ git push origin master
  • deploy: $ bundle exec cap production deploy

Deploying the same app to a different environment

Capistrano has a built in support for multiple environments.

Deploying an app to a new environment is really easy. We'll presume a new environment is staging, so edit config/deploy/staging.rb to look like this:

server '<staging_server_ip>', user: '<deploy_user>', roles: %w{web app db}
# only if your app already has a domain, then add:
# set :nginx_server_name, 'staging.mydomain.com'

You'll notice the above is very similar to config/deploy/production.rb.

All you have to do now is:

$ bundle exec cap staging deploy

and soon your app's staging environment will be live!

Conclusion

This tutorial has hopefully shown you how quick and easy rails application deployment could be. Even though it's tempting, hopefully you'll never again do $ git push heroku master :)

Happy deploying!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment