/ RAILS

Docker + Rails 6 Application setup

This tutorial will help Dockerify Rails 6 application using Postgres as database. We will see how to write Dockerfile and docker-compose file in order to create a docker image of Rails application and run it for development.

This tutorial assumes that you have basic understanding of what Docker is. Go ahead and get started with Docker to know more about Docker.

Setup Rails 6 Application

We will use Ruby 2.6.2 stable release for creating a Rails 6.0.0.beta3 application.

To install Ruby 2.6.2 using RVM,

rvm install 2.6.2

To install Rails 6.0.0.beta3,

gem install rails -v 6.0.0.beta3

Create a Ruby on Rails application with,

rails new docker-rails-6-application

This will setup a new Rails 6.0.0.beta3 application. Once that is done, change directory to newly created directory.

cd docker-rails-6-application

Create a Dockerfile

Create a Dockerfile to build a Docker image of the Rails application. For the configuration discussed above, we can use Dockerfile listed below.

FROM ruby:2.6.2

# replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh

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

RUN mkdir -p /app
RUN mkdir -p /usr/local/nvm
WORKDIR /app

RUN curl -sL https://deb.nodesource.com/setup_11.x | bash -
RUN apt-get install -y nodejs

RUN node -v
RUN npm -v

# Copy the Gemfile as well as the Gemfile.lock and install
# the RubyGems. This is a separate step so the dependencies
# will be cached unless changes to one of those two files
# are made.
COPY Gemfile Gemfile.lock package.json yarn.lock ./
RUN gem install bundler -v 1.17.2
RUN gem install foreman -v 0.85.0
RUN bundle install --verbose --jobs 20 --retry 5

RUN npm install -g yarn
RUN yarn install --check-files

# Copy the main application.
COPY . ./

# Expose port 3000 to the Docker host, so we can access it
# from the outside.
EXPOSE 3000

# The main command to run when the container starts. Also
# tell the Rails dev server to bind to all interfaces by
# default.
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]

Listing down details of the Dockerfile.

  • It will use ruby image of version 2.6.2
  • Install node and npm to be able to install node based dependencies of the project
  • Install bundler and foreman
  • Copy Gemfile and Gemfile.lock and bundle install the project
  • Install yarn globally and yarn install dependencies
  • Expose port 3000 to be able to access rails application from outside

Create .dockerignore file

Create a .dockerignore file. This is same as .gitignore file but used to list files which need to be ignored when docker image is build for the project.

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
/public/packs/*
!/log/.keep
!/tmp/.keep
.DS_Store
.idea
.env.development
.env.staging

# Ignore node_modules
/node_modules/*

# Ignore bundler config.
/.bundle

# Ignore the tags file used by VIM
tags

# Ignore Byebug command history file.
.byebug_history

# Ignore .git as it's not needed with the docker built.
.git
.cache

Create Docker Compose

Docker compose is a tool to build multi container application. As, we will be using Ruby on Rails application with postgres, we will use two services in docker compose as listed below.

version: '3'
services:
  db:
    image: postgres
    ports:
      - "5432:5432"
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bash -c "foreman start -f Procfile.dev-server"
    volumes:
      - '.:/app'
    ports:
      - '3000:3000'
    environment:
      DATABASE_URL: postgres://postgres@db
    depends_on:
      - db
db
  • db is a service that use postgres as image from docker hub.
  • It runs on the port 5432.

web

  • This build . current directory for the container.
  • This use /app volume for the container
  • Expose port 3000 from container
  • Depends on db container. db container starts before web container.
  • environment option can be used to define environment variables

Typical database.yml file can be as given below, that uses correct database url in the docker image.

# config/database.yml
default: &default
  adapter: postgresql
  encoding: utf8
  pool: 5
  url: <%= ENV['DATABASE_URL'] %>

development:
  <<: *default
  database: dockerify_rails_development
  host: localhost

test:
  <<: *default
  database: dockerify_rails_test
  host: localhost
Rails DB Setup

We can run rake / rails tasks in docker container for Rails application with command given below.

docker-compose run web rake db:setup

This will setup create database and seed data.

Start Rails application with Docker

Now, we can run the project in development mode with the command given below.

docker-compose up