Dockerizing an Existing Rails App

Jimmy Cheung
3 min readSep 28, 2020

Dockerizing an existing Rails app will be very similar to my existing guide on creating a new Rails app.

However, there are definitely some differences and nuances.

First, you have to make sure that you are using postgresql in your app. If that is not the case, you can convert your database using this article.

Then, you will need to define the starter files like with creating a new Rails app in Docker. However, it is a more streamlined process this time, but with many similarities.

Dockerfile

As discussed in the new Rails app article, you will have to create a new dockerfile that will build the app image. This dockerfile will exist in the root directory of the rails app. Here is the basic template:

FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

Entrypoint

Next, as with the new rails app, we want to use an entrypoint. This step can be avoided if you are not using the entrypoint in your dockerfile. This file will also exist in the directory of the rails app.

#entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

Docker Compose

Then, you can build the docker-compose file. You can read more about the docker-compose from my previous article. This last file will also exist in the root directory of the rails app.

#docker-compose.yml
version: '3'
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: password
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db

Database Settings

Then, you can adjust the config/database.yml to point the rails app at the right database:

default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000

The notable change will be the ‘host: db’ line, allowing the rails app to see the db container.

Building the project and setting up the db

Lastly, you can build the project and set up the db:

$ docker-compose build
$ docker-compose run web rake db:create db:migrate
$ docker-compose up

These steps will build the image off the docker-compose file, then run and generate your database, and lastly run your image in a container.

Conclusion

At the end of this, you’ll have your Rails app in a docker container that you can access via localhost:3000. However, instead of using rails s in the future to launch your server, you will use ‘docker-compose up’.

Sources

--

--