Firstly ensure you have docker installed.

Then create a Dockerfile:

FROM ruby:2.6.3

RUN apt-get update -qq && apt-get install -y build-essential

# for postgres
RUN apt-get install -y libpq-dev

# for nokogiri
RUN apt-get install -y libxml2-dev libxslt1-dev

# for capybara-webkit - only if you go for Monolithic Rails
# RUN apt-get install -y libqt4-webkit libqt4-dev xvfb

# for a JS runtime - not sure is needd for API based Rails
RUN apt-get install -y nodejs

ENV APP_HOME /minerva
RUN mkdir $APP_HOME
WORKDIR $APP_HOME

ADD Gemfile* $APP_HOME/
RUN bundle install

# Copy the current directory contents into the container at /minerva
COPY . /minerva

ADD . $APP_HOME

Note the following:

  1. FROM: This describes the image we’ll be basing our container off of; in this case, we’re using the Ruby 2.6.3 image.
  2. RUN: This is how we run commands; in this example, RUN is used primarily to install various pieces of software with Apt.
  3. WORKDIR: This defines the base directory from which all our commands are executed.
  4. ADD: This copies files from the host machine (in our case, relative to Dockerfile on OS X) to the container.

To build the Docker image, from your Rails root run:

docker build .

This will build an image with the appropriately installed software - but we’re not done.

Configure Docker

Even though we’re able to successfully build a Docker image to house our Rails app, we have other dependencies. In this case, we’ll also need to configure a database like Postgres, and ensure that the database container and the application container can talk to one another.

This is where Docker Compose really shines.

Here’s an example docker-compose.yml file:

version: '2'
services:
  db:
    image: postgres:9.4.1
    ports:
      - "5432:5432"

  web:
    build: .
    command: bin/rails server --port 3000 --binding 0.0.0.0
    ports:
      - "3000:3000"
    links:
      - db
    volumes:
      - .:/minerva

In docker-compose.yml, we’re describing two containers. The first is db, which is based on another image (postgres:9.4.1) and exposes port 5432 on port 5432 to the outside world.