If you follow our company blog you’ll know that we’re working on Harmonia, our virtual office manager. I thought I’d explain how we use recap to deploy harmonia, to show how easy and fast recap makes application deployment.
Harmonia is a fairly standard rails application. As well as a web front-end, it has two other processes. A queue
worker is used to send outgoing emails, whilst the core of the application is the
ticker; a process which ‘ticks’ every minute, assigning tasks to team members. We use foreman to declare these processes in the following
web: bundle exec unicorn -p $PORT -c unicorn.conf.rb ticker: bundle exec rails runner script/ticker.rb worker: bundle exec rake environment resque:work QUEUE=assignments VVERBOSE=1
All of these processes touch application code, so whenever we deploy a new version of the app (which we do frequently) they need to be restarted. Our app also has a database with associated migrations, uses environment variables like
DATABASE_URL for configuration, and has a number of gem dependencies managed by bundler.
This is all handled by recap.
Getting started - adding recap to the project
Using recap with a rails project is simple. First add
gem 'recap' to the
Gemfile and run
bundle install. Next run
bundle exec recap setup, which will generate a
Capfile, guessing values for the git repository and app name. You should check these values and change the server to point to your app server. As an example, the complete
Capfile for harmonia is shown below:
require 'recap/recipes/rails' set :application, 'harmonia' set :repository, 'email@example.com:freerange/harmonia.git' server 'bison.harmonia.io', :app
Applications deployed with recap need their own user, owning all files and processes. Assuming we can
ssh into our server and are listed as a
sudoer, we can create this user automatically running
cap bootstrap. This will also add our own
ssh user to the application group, allowing it to deploy the application.
Next we can set any environment variables we need for configuration. These are loaded in the application user’s
.profile, so are available to all processes started by recap. In harmonia we set our smtp credentials, the server port, some api keys and more, using commands like
cap env:set PORT=7000 and
cap env:set SMTP_PASSWORD=secret.
The app is now almost ready to deploy. We can prepare it for deployment with
cap deploy:setup, which clones the code repository, installs our gem bundle, sets up the database and precompiles our assets.
cap deploy will start the app for the first time, launching each process defined in the
Procfile with the environment variables we previously set.
Really fast deployments
While recap makes it very easy to get apps up and running the first time, it comes into its doing subsequent deployments. At Go Free Range we like to deploy apps we’re working on very frequently. One thing that helps ensure we do this is making each deployment as fast as it can be.
git as recap does is already a very quick way to get code changes onto servers, but recap takes things a step further. By testing to see which files have changed it knows which tasks can be skipped. For example, database migrations won’t be run if
db/schema.rb has not changed; the gem bundle won’t be re-installed unless
Gemfile.lock has been updated, and foreman process scripts won’t be exported if the
Procfile is unchanged. In fact, if these files don’t exist, these tasks will never run at all.
Using recap with Harmonia has made our deployment process very fast and simple. When the main harmonia server became over-burdened and we decided to commission a new machine dedicated to harmonia, recap made that process quick and painless. As well as harmonia, recap is also used to deploy the Go Free Range website, this blog, and a number of other small sites and projects where it has proven itself well. For larger projects, there are some features (such as more control as to what processes run where) that are missing, but I plan to add these in the next release. For all other sites, recap has proven itself a lightweight and capable alternative to the standard Capistrano deployment recipes.