One of the challenges we face when we are developing an application, is having a uniform development stack among team members. In this tutorial, I’ll show you how to use Docker and docker- compose to manage your rails application and simplify the project setup for new team members.
Preliminary Concepts
Before to start setting-up the application, let’s define some basic concepts:
Docker
Docker is a tool that can package an application and its dependencies in a virtual container that can run on any Linux server. This helps enable flexibility and portability on where the application can run, whether on premises, public cloud, private cloud, bare metal, etc.
Docker Compose
Compose is a tool for defining and running multi-container Docker applications. It uses YAML files to configure the application's services and performs the creation and start-up process of all the containers with a single command.
This tutorial assumes that you have installed docker in you machine and you have notions about how to use docker. If you don’t have the docker engine yet, you can follow the Docker CE install instructions from the official website.
Creating a new application
First we need to create a new rails application that uses PostgreSQL as a database engine.
rails new docker-demo-app --database=postgresql
Configuring the database
The next step is to update the config/database.yml to use a basic configuration that allow to run the application without docker using the system PostgreSQL engine or use the docker configuration with a database container.
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch('DB_USERNAME') { 'user' } %>
password: <%= ENV.fetch('DB_PASSWORD') { 'password' } %>
host: <%= ENV.fetch('DB_HOST') { 'localhost' } %>
port: 5432
development:
<<: *default
database: docker-demo-app-development
test:
<<: *default
database: docker-demo-app-test
production:
<<: *default
database: docker-demo-app-production
Adding Docker files
After setting the database with our Rails application, we can add the Docker configuration files required to create the container and manage the application.
Dockerfile
The first file we need to add in the project root is the Dockerfile, this file represents the basic configuration that your application needs to run properly. If you need some compiled dependencies like graphviz, imagemagick, ffmpeg, etc. you can add the required steps to install or compile them here.
FROM ruby:2.3.3
RUN apt-get update && apt-get install -qq -y build-essential libpq-dev postgresql-client-9.4 apt-transport-https
# Using Debian, as root
RUN curl -sL https://deb.nodesource.com/setup_9.x | bash -
RUN apt-get install -y nodejs
ENV APP_HOME /usr/src/app
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
ADD Gemfile* $APP_HOME/
ADD package.json* $APP_HOME/
RUN bundle install --jobs 20 --retry 5
RUN npm install
.dockerignore
This file is similar to the .gitignore file. The .dockerignore file helps us to avoid sending unnecessary or sensitive files inside the docker image.
.git
.dockerignore
.byebug_history
log/*
tmp/*
docker-compose.yml
We need to add the following docker-compose.yml file to our project. This file includes the environment variables required to connect it to the Postgres database container, it also uses the working directory as a volume, in this way we can edit our project in our local and all the changes will be reflected inside the container.
version: '3'
services:
webapp:
build: .
depends_on:
- postgres
environment:
- RAILS_PORT=3000
- DB_USERNAME=user
- DB_PASSWORD=password
- DB_HOST=postgres
volumes:
- '.:/usr/src/app'
ports:
- '3000:3000'
networks:
- demo
stdin_open: true
tty: true
working_dir: '/usr/src/app'
command:
- /bin/bash
- -c
- bundle install --jobs 20 --retry 5; npm install; rm ./tmp/pids/server.pid; rails db:setup db:seed; rails s
postgres:
image: postgres:9.4
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
networks:
- demo
ports:
- '5432:5432'
volumes:
- '../postgres:/var/lib/postgresql/data'
networks:
demo:
driver: bridge
Start the application
Once we have added the necessary files to the project, we can start the containers using the following command:
docker-compose up
If you want to start the containers without showing the container logs, you can use the -d flag.
docker-compose up -d
Note: sometimes in the first docker-compose up, the Rails application could show a database connection error like the following:
This error is shown because the Rails container started before the Postgres container. To fix this you should restart the Rails container using:
docker-compose restart webapp
At this point you can verify the application is working in your browser at http://localhost:3000
Watch the Docker containers
Now the containers have started because of the docker-compose. You can see them using the following command in the project directory:
docker-compose ps
Interacting with the Rails application
The aim is to use docker-compose to manage the application. In the docker-compose.yml we named the rails application webapp. Now you can use the following structure to run rails commands inside the container.
docker-compose exec
Rails scaffold
docker-compose exec webapp rails generate scaffold User name:string email:string
Database migration
docker-compose exec webapp rails db:migrate
Note: In Linux systems it’s possible you need to add the --user flag
docker-compose exec --user "$(id -u):$(id -g)" webapp rails db:migrate
Database Resetting
docker-compose exec webapp rails db:reset
Rails console
docker-compose exec webapp rails console
Interacting with containers
You can use the following docker-compose commands to manage the containers. You can see the full list in the official documentation
Watching container logs
docker-compose logs
Stopping containers
docker-compose stop
Destroying containers
docker-compose down
Docker is a useful tool you should consider to include in your application workflow. In this tutorial we only added two containers, but it’s quite simple to add other services like Redis or to run multiple applications simultaneously; and with a few changes to your docker-compose configuration you can deploy your project to production.
If you want to learn more, please contact us!
Error: Contact form not found.