I recently stopped ignoring those "We know you’re working on migrating from CircleCI 1.0 to 2.0..." emails and spent some time getting our Rails app at Cognoa using the latest docker-based version of CircleCI. Of course these things never go as smoothly as you'd expect, so there was a fair bit of frustration along the way. However, there is a certain satisfaction of cutting down build time from about 12.5 minutes to 4.5 minutes.

The 2.0 documentation is pretty comprehensive. Not only does it include a Ruby language guide, there's even a sample configuration that uses Ruby and Postgres. My configuration is essentially a modified version of that.

Configuration

.circleci/config.yml

In this example, our build is using 2 CPUs. If you're on the free tier, which doesn't support parallelism, you'll either want set that to 1 or remove the key altogether.

I'll go through each section.

Docker

One of the great things about CircleCI 2.0 is that it is docker-based, so we can specify a container and run whatever pre-built docker images we'd like. There is a list of official CircleCI pre-built docker images, but you can still use anything off DockerHub.

This containerization makes configuration super easy and starting up our builds really fast. In the docker section of our config.yml, we specify 4 images and a few environment variables.

  1. circleci/ruby:2.5.0
  2. circleci/mysql:5.7
  3. redis:4.0.9
  4. elasticsearch:2.3

Our specs will run in our Ruby container, so we'll specify RAILS_ENV=test there. For MySQL, we need to set both MYSQL_ROOT_HOST=% (doc), which allows root login from other hosts and MYSQL_ROOT_PASSWORD=circleci (doc) which (gasp!) sets the root password to the string circleci.

Checkout + Rails Config

Starting from the steps key, everything happens sequentially. The first step is to check out the latest code from our repository. Next, we'll copy over two CI-specific config files to account for our secrets.yml and database.yml not being present in the reposity.

config/secrets.ci.yml

config/database.ci.yml

There is a major caveat here: you MUST specify the MySQL host as an IP address. Ruby will NOT be able to connect using localhost.

Bundler

Caching our Gemfile keeps our builds speedy as well. The sample configuration caching setup didn't work right off the bat, but it was simple enough to fix by specifying the path for both bundle check and bundle install commands.

Load Schema and Run Specs

From here we make sure MySQL is running and subsequently load the schema. The rspec command used here is directly from the sample configuration, which employs rspec_junit_formatter to output the specs in a format CircleCI can read and also saves test results for timing analysis on later runs.

Cheers!

You're all done and it's time for a beer!

Please leave any questions or comments below.