Well, we have a well-developed application built with our laptop, but we want it to be seen by the entire world. Even better, we want to automate this process in order to push our new super-duper features in seconds with only one command on our development machine:
1
|
|
What do we do?
In this article we will cover automated deployment of a Ruby on Rails application to a VPS (Virtual Private Server). We will install a Ubuntu Linux Server (14.04 LTS) and prepare our project for automated deployment with Capistrano 3.
We will use DigitalOcean as a VPS server provider, because they have good technology with competitive prices. There are other alternatives like Amazon EC2, OVH, Linode, Dreamhost …. but the steps would be very similar.
The Automated Deployment Process with Capistrano
For web applications, deployment means a sequence of steps to enable a feature on the production server after having built it locally. It typically involves copying over the source code and optionally, updating system and server configurations, updating the database, restarting the server and services, etc.
Capistrano is a program that allows developers to automate the deployment process using a Ruby based script. It provides core functions to help you to:
- Use a version control system (git, mercurial, svn..) to manage your app code to maintain good development practices
- Run system commands, such as installing new gems using bundler or running database migrations
- Pre-process, compile and obfuscate assets such as CSS/Javascript files
- Rollback the latest deployment if error happens.
In addition to the core functions, Capistrano also supports a wide variety of community provided hooks and extensions that allows you to:
- Manage your app server (unicorn, thin, puma…)
- Manage your ruby version with Rbenv, RVM,…
- Setup your database (Postgres, MySQL, MongoDB…)
- Deploy your crontab for scheduled tasks with ‘whenever’ gem
- Many other features
Let’s now walk through an example of setting up a production server and deploy a Ruby on Rails app with Capistrano:
Step 1. Prepare SSH login on VPS (DigitalOcean)
After creating an account, first we should create our SSH credentials to authenticate with the production server. If you don’t have a pair of ssh keys you can create them following this instructions.
1
|
|
Now copy it to “SSH Keys >> Add SSH Key” with DigitalOcean:
Step 2. Create the server
Now we will create a Droplet, which is a hosted server:
We can choose:
- Name: capistrano
- Size: 1024 MB
- Region: your nearest available one
- Image: Ubuntu 14.04 x64
- Add SSH keys: check the one you created
Your root password will be emailed to you, but you do not need it if you have configured your ssh key properly:
We can access the server console with the IP address from the email (make sure to replace with your own ip)
1
|
|
Step 3. Server Setup
Now you should install git and other packages to setup the server as a Rails production server.
1 2 |
|
Also you need to install ‘rbenv’ as described in the ‘How to Install Ruby on Rails on Ubuntu Linux’ post, in “Step 3. Install Ruby with RBENV”.
You also need to install bundler which will manage gems versions for you.
1
|
|
Step 4. Setting up Capistrano in your Rails project
Go to the directory of your Rails project. We recommend to use rbenv
to manage your ruby versions, so if you haven’t done so, fix your project ruby version. If you want to use version 2.1.2,
1
|
|
You need to add these gems to the Gemfile:
1 2 3 4 |
|
Install and initialize capistrano:
1 2 |
|
The latest Capistrano version right now is 3.2.1, which is very different from version 2. Version 3 is multistage by default with two environments: staging and production. So you will have config/deploy/production.rb and config/deploy/staging.rb added to Capfile and deploy.rb files.
In Capfile uncomment:
1 2 3 |
|
Change this line at config/secrets.yml:
1 2 |
|
The number above may be different from your app. This key validates the integrity of your application cookies and you should generate your own secret by running rake secret
and use the result to replace your secret key above. On a more sophisticated deployment you can set this as an environment variable.
Ensure you have a production database configured in your config/database.yml file – the below example assumes you use Postgres as production database.
1 2 3 4 5 6 7 |
|
Step 5. Preparing your project to deploy
In config/deploy.rb we can configure our app name and repository (:git by default):
1 2 3 |
|
Clear the config/deploy/production.rb file and add the following lines to configure the production environment:
1
|
|
Right now you can check the server availability through the following command:
1
|
|
Step 6. Install Thin on the server
We’ll use Thin, a lightweight Ruby application server as an example here for the production server.
On the production server, install the Thin gem for the global ruby version:
1
|
|
With the following command you will generate the Thin script for Ubuntu (/etc/init.d/thin), and create Thin configurations folder (/etc/thin):
1
|
|
Now you can start|stop|restart all your apps on this server with the following commands:
1 2 3 |
|
But you need to configure how Thin will start your app:
1
|
|
Finally, you can create scripts to restart your app when this is rebooted for any reason:
1
|
|
Step 7. Installing Thin in your project
Add Thin gem to Gemfile:
1
|
|
And do not forget to run: bundle install
Add this line to :restart task in your config/deploy.rb:
1 2 3 4 5 6 |
|
Pay attention to this line below. here you are calling the restart
task after the publishing
process.
1
|
|
To deploy your app, just run:
1
|
|
Now your app is deployed! You should be able to visit it on the production server.
The Deploying Process Under the Hood
The command cap production deploy
seems magical. It connects with server and performs all the deployment tasks automatically. But here is the explanation to the basic process we have seen in this post:
- deploy:starting
- Rbenv ensures that the version we configured on config/deploy.rb is installed and that it can write on disc
- Checks git repository
- Create needed folder tree
- /var/www
- capistrano-first-steps
- shared
- public
- assets
- public
- releases
- shared
- capistrano-first-steps
- /var/www
- deploy:updating
- Clone the whole repo in /var/www/capistrano-first-steps/repo
- Creates a new folder date-time named on /var/www/capistrano-first-steps/releases/20140717180754
- Copies the project there
- deploy:publishing
- Runs
bundle install
in last release folder - Runs
assets:precompile
copying our minimized assets to shared/public/assets - Creates a soft link from last release to /var/www/capistrano-first-steps/current
- Restart thin server. This is due to this line in config/deploy.rb:
after :publishing, :restart
. This hooks the deploy:restart task after :publising task
- Runs
- deploy:finishing – Logs deployment to revisions.log
You can take a look to the official documentation to see how is the Capistrano deployment flow processed.
Conclusions
Capistrano is a great tool to automate application deployment with good out-of-box support for Ruby on Rails applications. It takes some time to learn the ins and outs of the tool and build up your own deploy script, but once it’s built, it’s pretty easy to use it for automated deployment. It has a rich feature set and with its big community, it can grow with your app to meet more complicated deployment requirements.