Learn how to install and use Docker to run a Rails 5, Postgres, Redis, Sidekiq and Action Cable app in development with Docker Compose.

After this tutorial, you’ll understand what the benefits of using Docker are and will be able to:

Install Docker on all major platforms in 5 minutes or less

Run an example Rails 5+ app that uses a bunch of best practices

Know how to write a Dockerfile

Run multiple Docker containers with Docker Compose

Also, there’s a free email course to learn a bit about Docker at the bottom of this post.

What Is Docker and Why Is It Useful?

Docker allows you to package up an application or service with all of its dependencies into a standardized unit. This unit is typically labeled as a Docker image.

Everything the application needs to run is included. The Docker image contains the code, runtime, system libraries and anything else you would install on a server to make it run if you weren’t using Docker.

Installing Docker

The code base we’ll be working with is compatible with Docker 17.06 and Docker Compose 1.14, and I’m sure it will continue to work with future versions of Docker, so feel free to install the latest versions of both.

This guide expects you to have Docker already installed. If you’re at ground 0 then you may want to sign up for the free Docker email course at the bottom of this post, because it covers a myriad of ways to install Docker on Mac, Windows and Linux.

Creating the Rails Application

The focus of this blog post is on Dockerizing a Rails application that has a number of moving parts. We could use rails new to create a new project and build it up, but it would be faster just to use a pre-made application instead.

Dockerize the Rails Application

There’s a few things we need to do to Dockerize the application.

Logging

In order for logs to function properly, Docker expects your application or process to log to STDOUT. This is a very good idea because the concept of managing log files will now be de-coupled from your Rails application.

You can choose to have Docker write those log entries to syslog or another local service running on your server, or you can ferry the log output over to a third party service such as Loggly.

In either case, you need to make a small adjustment to your Rails app:

Dive Into Docker covers everything in great detail if you want to see how all of this ties together. Often times knowing the “why” is more important than seeing how it’s done. That is what enables you to apply things on your own.

.env

This file isn’t technically part of Docker, but it’s partly used by Docker Compose and the Rails application.

By default Docker Compose will look for an .env file in the same directory as your docker-compose.yml file.

We can set various environment variables here, and you can even add your custom environment variables here too if your application uses ENV variables.

COMPOSE_PROJECT_NAME=my_dockerized_app

By setting the COMPOSE_PROJECT_NAME to my_dockerized_app, Docker Compose will automatically prefix our Docker images, containers, volumes and networks with mydockerizedapp.

It just so happens that Docker Compose will strip underscores from the name.

There’s plenty of other values in this .env file but most of them are custom to the Rails application. We’ll go over a few Docker related values in a bit.

Run the Ruby on Rails Application

You can run everything by typing: docker-compose up --build. Docker Compose has many different sub-commands and flags. You’ll definitely want to check them out on your own.

After the up command finishes, open up a new terminal tab and check out what was created on your behalf.

Docker Compose automatically pulled down Redis and Ruby for you, and then built the website, sidekiq and cable images for you.

Docker containers

Run docker-compose ps:

Name State Ports
-------------------------------------------------------------------
mydockerizedapp_cable_1 ... Up 0.0.0.0:28080->28080/tcp
mydockerizedapp_postgres_1 ... Up 0.0.0.0:5432->5432/tcp
mydockerizedapp_redis_1 ... Up 0.0.0.0:6379->6379/tcp
mydockerizedapp_sidekiq_1 ... Up
mydockerizedapp_website_1 ... Up 0.0.0.0:3000->3000/tcp

Docker Compose automatically named the containers for you, and it appended a _1 because it’s running 1 instance of the Docker image. Docker Compose supports scaling but that goes beyond the scope of this tutorial.

We can also see which ports the services are using.

There’s a lot more to go over but the above is enough to get rolling.

Viewing the Site

If you installed Docker through the Docker Toolbox then you’ll need to make 3 quick changes to the .env file. If you’re running Docker natively then you can access http://localhost:3000 right now.

Toolbox users need to change a few instances of localhost to 192.168.99.100 or whatever your Docker Machine IP address is. You can determine your IP by running docker-machine ip from a Docker-enabled terminal.

This is because you don’t have Docker running natively on your system. It also means you’ll need to access http://192.168.99.100:3000 in your browser.

At this point you’ll notice that it throws an error saying the database does not exist. No worries, that’s expected right? We haven’t reset our database yet.

Interacting With the Rails Application

This section of the blog post will serve 2 purposes. It will show you how to run Rails commands through Docker, and also shows you how to initialize a Rails database.