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.