lucatironi.net Code snippets, tutorials and stuff

(Updated) Use docker-compose to develop a Ruby on Rails application

Using docker-compose to develop a Rails application


You can find the code for this tutorial on my Github repository.

In order to kickstart the application we need to install the rails gem and run the rails new <appname> command. We will do this inside the same Docker container that will be used to run the application itself. To do so we need to create a Dockerfile to create the Docker image with the necessary dependencies, a docker-compose.yml file to provision the other services needed (a postgres database and a volume store) and a Gemfile (with an empty Gemfile.lock) to install the rails gem and bundle install its dependencies.

Create a new directory and some empty files:

mkdir rails-docker-compose
cd rails-docker-compose
touch Dockerfile docker-compose.yml Gemfile Gemfile.lock

Copy and paste the following content in the respective files:

File Dockerfile

FROM ruby:2.4.2

ENV APP_ROOT /app
ENV BUNDLE_PATH /usr/local/bundle

RUN apt-get update -qq && \
    apt-get install -y build-essential libpq-dev nodejs

WORKDIR $APP_ROOT
ADD . $APP_ROOT

File docker-compose.yml

version: '3'

volumes:
  store:
    driver: local
  bundle:
    driver: local

services:
  web:
    build: .
    ports:
      - 3000:3000
    volumes:
      - .:/app
      - bundle:/usr/local/bundle
    links:
      - db
    # Keep the stdin open, so we can attach to our app container's process and do things such as
    # byebug, etc:
    stdin_open: true
    # Enable sending signals (CTRL+C, CTRL+P + CTRL+Q) into the container:
    tty: true
    command: ./bin/start.sh
    environment: &app_env
      PORT: 3000
      DB_HOST: db
      DB_PORT: 5432
      DB_USER: postgres
      DB_PSWD: postgres
      DB_NAME: development_database
  db:
    image: postgres:latest
    ports:
      - 5432:5432
    volumes:
      - store:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: development_database

File Gemfile

source 'https://rubygems.org'

gem 'rails', '~> 5'

Build the project

First we need to bundle the rails 5 dependencies:

docker-compose run --rm web bundle --jobs=10 --retry=5

And then use the rails new command to create the new application:

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

Configure the database

We need to change slightly the database configuration to use the environment variables set in the docker-compose file:

File: config/database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  username: <%= ENV['DB_USER'] %>
  password: <%= ENV['DB_PSWD'] %>
  host: <%= ENV['DB_HOST'] %>
  # For details on connection pooling, see rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: <%= ENV['DB_NAME'] %>

test:
  <<: *default
  database: test_database

Setup the app

docker-compose run --rm web bin/setup

Create a start.sh file in the bin dir:

File: bin/start.sh

#!/bin/bash

bundle check || bundle install

if [ -f tmp/pids/server.pid ]; then
  rm -f tmp/pids/server.pid
fi

bundle exec rails s -p $PORT -b 0.0.0.0

It automatically removes the server.pid that will create problems when you stop and restart the app. Make the file executable with the chmod command:

chmod +x bin/start.sh

Finally start your newly created Rails application and visit localhost:3000:

docker-compose up
^Back to top