Rails 6 production container with Docker

Without docker-compose!

Disclaimers: This is not an article about how Dockerize a Rails App for development, but how to Dockerize an app in a production environment ready to deploy. Ideally, this part should be delegated to the CI.

There are plenty of examples of how Dockerize an App in development mode and often with docker-compose. That is great but it doesn’t help when it comes to host and deploy our containers in production.

Let’s start with the simple weblog of rails [1] btw, the code can be found here [2] This article might take some short cuts to keeping it short and straight to the point.

If Ruby, Rails and Postgresql are already installed on your machine you might skip the next section, otherwise, check it out.

Rails with Docker

The official Rails image on the Docker hub is deprecated [3] for good reason, it doesn’t make sense to have a universal image for Rails as we are likely to customize it for our needs. Here a simple image to create a Rails app with Postgresql.

Now we can build the Rails Docker image:

We can see the newest image create on our system

Create a Rails App

Now we can create the new Rails App.

Note: we bind the current directory onto our container, like that the code generated will be reflected in our file system and we can open the code with our text editor and change what needs to be modified.

For conviniency we create an alias for this command

Starting Postgresql

We are using the Docker Postgresql Image.

First, let create a dedicated network for our application

We can find it here:

This way we ensure all communications are going through this network.

Before starting the database we create a volume for our data:

Note: The postgres image create a default volume for us but with a random id as name. It’s nicer to have proper name:

Now we can start our database:

Note: Do not use underscore on the name of that container, Docker use the name of the container to resolve hostname internally, see the container names as hostnames. If Docker is flexible when resolving hostnames, ActiveRecord is less, it uses URI::RFC2396_Parser to parse the DATABASE_URL so we need a valid hostname format.

An important thing here is to start the container in the same network, this way the Rails app can communicate freely with the database.

Start Redis

Before running our Rails app we need to start a Redis instance as ActionCable use it in production. If we follow along with the DHH weblog example we are going to need it.

Again here we start to create a named volume:

And start Redis

An important thing here is to start the container in the same network, this way the Rails app can communicate freely with Redis.

btw we might need to add the redis gem:

be sure to install it r bunde

Create a Resources

Let’s create something on our app.

Lovely, now we have something to play with.

Dockerize the Rails App

Now we are ready to Dockerize our Rails app

Note: We use Docker multi-stage in order to reduce the weight of the image, we are down from +1Gb to 0.4Gb. If you don’t feel confident with that just remove the code from the second FROM

Now we have to build the image:

Note: I use --squash to reduce the number of Docker layers. This is part of the last and experimental buildx if you are not using it, just omit this option.

FYI I’m using Docker Engine 20.10.3 with these settings:

We can check the image size

Create the Rails Image

Time to create the Docker image of our Rails App.

Starting the Rails App in Production Mode

Now everything is set up we can start our app.

Things are getting interesting

What have we just done here? We’ve started the container with all the configuration we wanted too.

We’ve indicated where to find Redis and Posgres, note how the hostnames are replaced by the container names. As well we didn’t publish any ports as the containers have full access to their network.

We can check if all our containers are in the same network with:

Now we can interact with the container to creating the database and start the app.

Now we can start the app

Note: Here, we reuse the running container with`exec`, but we’re likely to need to run the complete command next time:

You can go visit http://localhost:3025/posts

Or curl the app.

Important note, this container is not connected with your filesystem, any changes made on the app need to recreate the image to reflect them.

That it! Hope it demystifies how to start a Rails App in production mode with Docker. As we are not using docker-compose we can use the Orchestre we want to and managing our containers as we wish.

Passionate Software Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store