Set up Docker for Rails development
by Giang, last updated 04 Feb 2019
Docker is a great tool to synchronize dev envinronment on different machine. This resolves the excuse "not work on my machine". This also helps new devs to quickly set up the project without scratching their head with all the missing libs, mismatch versions, etc.
This article will describe how to setup Docker and Docker Compose for a Rails app that uses Postgresql/MySQL as database, Sidekiq and Redis.
Software versions use in this article
Docker version 18.03.1-ce, build 9ee9f40 docker-compose version 1.21.2, build a133471 Ruby 2.6.1 Rails 5 Postgres 10.6 MySQL 5.7.22 Redis 4.0.9
Table of Contents:
- Install Docker and Docker Compose
- Docker Compose file
- Build and run
Install Docker and Docker Compose
Installation guides for Docker and Docker Compose are well written in Docker docs.
FROM ruby:2.6.1 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs RUN mkdir /demoapp WORKDIR /demoapp COPY Gemfile /demoapp/Gemfile COPY Gemfile.lock /demoapp/Gemfile.lock RUN bundle install COPY . /demoapp
Docker Compose file
version: '3' services: db: image: mysql:5.7.22 volumes: - ./tmp/db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=123456 redis: image: redis:4.0.9 volumes: - ./tmp/redis:/data web: depends_on: - db - redis build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/demoapp ports: - 3000:3000 environment: - REDIS_URL=redis://redis:6379/ sidekiq: depends_on: - db - redis build: . command: sidekiq -C config/sidekiq.yml volumes: - .:/demoapp environment: - REDIS_URL=redis://redis:6379/
If the app uses PostgreSQL instead of MySQL, the DB image will be like follow:
db: image: postgres:10.6 volumes: - ./tmp/db:/var/lib/postgresql/data
If the app uses MongoDB:
version: '3' services: mongodb: image: mongo ports: - "27017:27017" web: ... depends_on: - mongodb
Then we'll need to update
config/database.yml to point to the DB image:
default: &default adapter: mysql2 encoding: utf8 pool: 5 username: root password: 123456 host: db development: <<: *default database: demoapp_development test: <<: *default database: demoapp_test
default: &default adapter: postgresql encoding: unicode username: postgres password: host: db pool: 5 development: <<: *default database: demoapp_development test: <<: *default database: demoapp_test
For MongoDB we'll need to update
development: clients: default: database: development hosts: - mongodb
See more for MongoDB setup and troubleshooting notes here
We could also add
.dockerignore to the root directory of Rails app, this file is optional and it works similarly to
.gitignore. This file is useful to declare list of files/directories that should be excluded from Docker build.
For example, since we use
./tmp/ to store database and redis data we should ignore it from Docker build.
Build and run
For the first time run
to build neccessary images. Then run
to start the whole stack.
Since the app is now running in Docker containers instead of your host OS, the regular commands, rake tasks need to be run inside the container as well. For example to create and migrate database for the first time
docker-compose run web rake db:create db:migrate db:seed
Another thing to note is that when
Gemfile changed, we need to rebuild
docker-compose run web bundle docker-compose run sidekiq bundle docker-compose up --build