code - lucatironi Code snippets and tutorials

(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