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.