Knowledge for the World

Set up a Rails app using Docker and Compose

Learn how to set up a Ruby on Rails/PostgreSQL app using docker and docker compose.

1

The first step is to install the Docker Toolbox.

On this page, find your platform and run the installation. On a Mac, you'll be installing Docker, Docker Compose, and Docker Machine. Docker Machine will use a Linux Virtual Machine to actually run Docker.

2

If you're using a Mac, you'll want to start working on Docker by opening the Docker Quickstart Terminal. This will ensure that your environment is set up properly since Docker is actually running in a VM.

3

I typically put projects like this in my home directory in a directory called Developer. We'll call this test app "rails-docker".

mkdir -p ~/Developer/rails-docker
cd ~/Developer/rails-docker

4

Create a file called Dockerfile and add this:

FROM ruby:2.2.0
RUN apt-get update -qq
RUN apt-get install -y build-essential libpq-dev
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
ADD . /app

These are the instructions for building the base image for your rails app.

5

Create a file called Gemfile and add the following:

source 'https://rubygems.org'
gem 'rails', '4.2.0'

In your Dockerfile, you added a line RUN bundle install. This command will install the packages specified in your Gemfile.

6

The Gemfile.lock file is where the bundler will record the exact versions of the packages that were installed. You must add this file in order for the image to be built properly.

touch Gemfile.lock

7

Create a file called docker-compose.yml and add the following:

db:
  image: postgres
web:
  build: .
  command: bundle exec rails s -p 3000 -b '0.0.0.0'
  volumes:
    - .:/app
  ports:
    - "3000:3000"
  links:
    - db

This compose file contains the instructions for how to build and link the containers required to run your rails app. As you can see there are two services - db and web. There are a few important parts of this file to take note of. First, we are mounting the current directory to /app. This means you can work on the app locally, and the changes will be available from within the container. And the command we specified will start the rails server, and it will be run whenever you run docker-compose up.

8

Now we're ready to actually create the rails app.

docker-compose run web rails new . --force --database=postgresql --skip-bundle

The docker-compose run command will spin up a container to run this single command. Once it finishes you can see the rails app created in your current directory:

ls -lha

At this point you'll want to change the owner of the files.

sudo chown -R $USER:$USER .

9

You'll notice if you examine your Gemfile that it has changed a bit. At this point, you should go ahead a rebuild the image so that you won't have to run bundle install every time you start a new container from your existing image.

First, open the Gemfile and uncomment the following line:

gem 'therubyracer', platforms: :ruby

Then run

docker-compose build

10

Edit the file config/database.yml and replace the contents with the following:

development: &default
  adapter: postgresql
  encoding: unicode
  database: postgres
  pool: 5
  username: postgres
  password:
  host: db

test:
  <<: *default
  database: app_test

Notice the host is db. When we linked the containers in our docker-compose.yml file our web container can access our db container using the hostname db.

11

docker-compose up -d

12

docker-compose run web rake db:create

13

If you're running docker-machine, you can find your machine's IP address by running:

docker-machine ip default

(Assuming you are using the default machine name.)

And open your browser and navigate to {IP}:3000. Mine is http://192.168.99.100:3000.

If you're running Docker locally, you can simply go to http://localhost:3000.