I’m playing with a vanilla-flavored Rails 7 project using Tailwind CSS and PostgreSQL, and on a whim I decided to find out how hard it would be to “Docker-ize” the app. To my surprise, it didn’t take that much effort. Docker has been around for quite awhile, but I did not have any direct experience with it while I was still employed. It looked pretty intimidating, and it does get more interesting when you add stuff like Redis and Sidekiq, but that was not an issue in my case.

The excellent book “Agile Web Development With Rails 7“, authored by Sam Ruby and Dave Thomas provides a solid example of Docker integration with an existing Rails app in Chapter 17.

After installing Docker Desktop (which includes Compose), you need to create a Dockerfile file and a docker-compose YAML file in the Rails application root directory:

# Dockerfile

FROM phusion/passenger-full:2.3.0

RUN rm /etc/nginx/sites-enabled/default
RUN rm -f /etc/service/nginx/down
RUN rm -f /etc/service/redis/down
ADD config/nginx.conf /etc/nginx/sites-enabled/your-rails-app.conf

#START:your-rails-app
USER app
RUN mkdir /home/app/your-rails-app
WORKDIR /home/app/your-rails-app

ENV RAILS_ENV=production
ENV BUNDLE_WITHOUT="development test"
COPY --chown=your-rails-app:your-rails-app Gemfile Gemfile.lock .
RUN bundle install
COPY --chown=app:app . .

RUN SECRET_KEY_BASE=`bin/rails secret` \
  bin/rails assets:precompile
#END:your-rails-app

#START:init
USER root
CMD ["/sbin/my_init"]
#END:init

Phusion Passenger 2.3.0 shown in the first line is one of the many images available from the Docker repo, and I selected it to match my Ruby version for the project (3.1.2)

# docker-compose.yml

version: "3.8"

services:
  db:
    image: postgres:14
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password

  web:
    build: .
    volumes:
      - ./log:/home/app/your-rails-app/log
    secrets:
      - source: master_key
        target: /home/app/your-rails-app/config/master.key
    ports:
      - "8001:80"
    depends_on:
      - db

secrets:
  master_key:
    file: ./config/master.key

volumes:
  pgdata:

The docker-compose.yml file assumes you have set up your logins and passwords using the Rails credentials feature to store encrypted password information.

A nginx.conf file also needs to be created under the rails_root/config directory. Then it was a matter of running docker compose build and docker compose up, and then using the Docker CLI to build and populate the database. Launching localhost:8001 in a new browser tab gave me a containerized version of my app. Very impressive.