How to Upgrade Any Rails Application Using Docker

How to Upgrade Any Rails Application Using Docker

Every time we start a new Rails upgrade project opens a new window , we need to setup a whole new environment in our local machines. Sometimes that leads us down the rabbit hole which ends up breaking our environment for other client projects.

After years upgrading Rails applications opens a new window , we learned that the best way to isolate our client projects’ environments is using Docker opens a new window .

That’s why we decided to use Docker and docker-compose opens a new window for all of our client projects. This year I had the opportunity to share our process in a series of workshops: Upgrade Rails 101: The Roadmap to Smooth Upgrades opens a new window

A couple of weeks ago I ran the latest iteration of our workshop at Southeast Ruby ‘19 opens a new window . I showed what it would look like if we were to upgrade the e-petitions opens a new window application.

In order to set up all the services I used this docker-compose configuration:

version: "2"

services:
  cache:
    image: memcached:1.4-alpine
    ports:
      - "11211:11211"
    restart: always

  db:
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD:
    image: postgres:9.6
    expose:
      - "5432"

  app:
    stdin_open: true
    tty: true
    restart: always
    env_file: .env.test
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - db
      - cache
    volumes:
      - .:/usr/src/app:consistent

This application uses Memcached opens a new window ; Postgres 9.6 opens a new window ; Ruby 2.3.8; and Rails 4.2. That’s why you will find these services in its docker-compose.yml opens a new window :

  • db (Postgres)
  • cache (Memcached)
  • app (Rails 4.2)

In order to setup the app service, I defined a Dockerfile opens a new window like this:

FROM ruby:2.3.8-jessie

RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ jessie-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list

RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -

RUN apt-get update -yqq \
  && apt-get install -yqq --no-install-recommends \
    build-essential \
    postgresql-client-9.6 \
    nodejs \
    vim \
    libpq-dev \
    qt5-default \
    libqt5webkit5-dev \
  && apt-get -q clean
RUN apt-get update

WORKDIR /usr/src/app

COPY Gemfile Gemfile.lock ./

RUN gem install bundler -v=1.17.3

RUN bundle install

COPY . .

As every other Rails application, it is not 100% standard. For instance, to setup the database you need to load the structure.sql file. So I decided to write a quick script (bin/docker-setup) to setup the test database:

#!/usr/bin/env ruby
require 'pathname'

# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../',  __FILE__)

Dir.chdir APP_ROOT do
  puts "== Creating databases =="
  system "rake db:create"
  system "psql -q -h db -U postgres -f db/structure.sql epets_test"
end

That way, if you want to build the services you can just do this:

docker-compose up -d
docker-compose exec app ./bin/docker-setup

Taking this approach makes everything easier to reproduce. Any developer can use this configuration to spin up a few virtual machines. It doesn’t matter if their machines are running Windows; Linux; or Mac.

During the workshop, the biggest blocker we had was download speed. It took between 10 and 20 minutes to get everything set up. The two steps that took the most time were:

  • Downloading and installing Docker
  • Building the images for the first time

Once that was done, the process went smoothly. We got to calculate test coverage; setup dual booting; run our test suite with two different versions of Rails; and fix a bunch of problems related to the jump from Rails 4 to 5.

If you are interested in applying these steps to your own application, you can check out the companion page for the Upgrade Rails 101 workshop opens a new window .

The slides for my presentation are over here: Upgrade Rails 101 Workshop at Southeast Ruby ‘19 opens a new window


Are you using Docker to simplify your Rails upgrades opens a new window ? If not, what are you using to normalize environments in your team? I hope you found this article useful and I look forward to reading your comments below!

If you’re not on Rails 6.0 yet, we can help! Download our free eBook: The Complete Guide to Upgrade Rails opens a new window .

Get the book