Return to home page

Setup Rails API with Docker Compose

Update Notice - 01.2023 :
This article is outdated and shows bad practises about creating Docker images. Check out improved version of this article here.

The most important thing when dealing with Rails is to use Linux, it's a must! Also keep in mind that installing Rails is tricky and sometimes it can drive you crazy. Lets get straight into configuration.

In this configuration, a volume with Rails project inside the container is mapped to a directory with project on the local system. The only problem is with executables like Rubocop, so I use Visual Studio with Dev Containers extension and I can attach directly to container to make executables works.

If you are ready, open terminal and type the following commands:

mkdir <project-name> cd <project-name> touch Dockerfile touch entrypoint.sh touch docker-compose.yml touch .dockerignore touch .env touch Gemfile touch Gemfile.lock

Files listed below should have the following content:

.env

RUBY_VERSION=3.1.0 RAILS_USER=rails-user GEM_HOME=/home/${RAILS_USER}/.gem/${RUBY_VERSION} POSTGRES_HOST=db POSTGRES_PORT=5432 POSTGRES_USERNAME=postgres POSTGRES_PASSWORD=postgres

docker-compose.yml

version: "3" services: db: image: postgres:13 volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" env_file: - ".env" rails: build: context: . args: - RUBY_VERSION=$RUBY_VERSION - RAILS_USER=$RAILS_USER - GEM_HOME=$GEM_HOME volumes: - .:/app - gems:$GEM_HOME ports: - "3000:3000" command: rails server -p 3000 -b '0.0.0.0' depends_on: - db env_file: - ".env" volumes: pgdata: gems:

Dockerfile

ARG RUBY_VERSION FROM ruby:$RUBY_VERSION-alpine ARG RAILS_USER ENV RAILS_ROOT /app ARG GEM_HOME ENV LANG C.UTF-8 RUN apk add --update --no-cache \ build-base \ postgresql-dev \ tzdata \ sudo \ git RUN adduser -D $RAILS_USER RUN mkdir -p $RAILS_ROOT \ chown $RAILS_USER $RAILS_ROOT WORKDIR $RAILS_ROOT COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] USER $RAILS_USER COPY --chown=$RAILS_USER Gemfile Gemfile.lock ./ RUN echo "gem: --user-install --env-shebang --no-rdoc --no-ri" > /home/$RAILS_USER/.gemrc ENV GEM_HOME $GEM_HOME ENV PATH $GEM_HOME/bin:$PATH RUN bundle install COPY --chown=$RAILS_USER . . EXPOSE 3000

entrypoint.sh

#!/bin/sh set -e # Remove a potentially pre-existing server.pid for Rails. rm -f $RAILS_ROOT/tmp/pids/server.pid exec "$@"

Gemfile.lock - should be empty

Gemfile

source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } gem "rails", "~> 7.0.3"

I assume you've already installed Docker on your machine (use docker command without prefacing with sudo every time).

Now, let's build docker image. Run the following command:

docker compose build

You should only type this one command below if you are setting up project for first time!

It creates new Rails API project inside container and installs it:

docker compose run --rm rails rails new . --force --api --database=postgresql --skip-test --skip-spring --skip-coffee

If installation went fine, we can move on to configuring database inside Rails project. Edit that code fragment inside volume in config/database.yml:

default: &default adapter: postgresql encoding: unicode host: <%= ENV['POSTGRES_HOST'] %> port: <%= ENV['POSTGRES_PORT'] %> pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: <%= ENV['POSTGRES_USERNAME'] %> password: <%= ENV['POSTGRES_PASSWORD'] %>

Now run both Postgres and Rails using docker compose:

docker compose up

Application isn't working yet, because we have to setup database and apply migrations. To access Rails container type in terminal:

docker compose exec rails sh

When we have direct access to rails executable, type:

rails db:setup

If everyting works, you are ready to start working on your project.

profile picture

I'm just curious about computer science, mainly web development.

I want this blog to describe what I did or learned today. These posts should be useful to a version of me from yesterday.

© 2024 Maciej Biel