Skip to content

Ror Docker

DodaTech 3 min read

title: Ruby on Rails Docker — Complete Guide to Containerization description: 'Learn Docker for Ruby on Rails: Dockerfile for Rails, docker-compose with PostgreSQL, environment variables, multi-stage builds, asset precompilation, and production containers.' date: 2026-06-28 lastmod: 2026-06-28 weight: 32 tags: [backend, ror]


Docker containers package Rails applications with Ruby, gems, and configuration for consistent deployment across development, staging, and production environments.

## What You'll Learn

By the end of this tutorial, you'll create Dockerfiles for Rails apps, configure docker-compose with PostgreSQL and Redis, manage environment variables, precompile assets in Docker, and deploy with containers.

## Real-World Use

A Rails microservice runs in Docker on AWS ECS. CI builds the image, pushes to ECR, and ECS deploys with zero downtime. Environment variables configure database URLs and secret keys.

## Docker Learning Path

```mermaid
flowchart LR
  A[Security] --> B[Docker]
  B --> C[Deployment]
  C --> D[Reference]
  B --> E{You Are Here}
  style E fill:#f90,color:#fff

Dockerfile

FROM ruby:3.3-slim AS build
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install --jobs 4
COPY . .
RUN SECRET_KEY_BASE=placeholder RAILS_ENV=production bundle exec rails assets:precompile

FROM ruby:3.3-slim AS runtime
RUN apt-get update -qq && apt-get install -y libpq-dev nodejs && rm -rf /var/lib/apt/lists/*
RUN adduser --disabled-password rails
WORKDIR /app
COPY --from=build /app /app
COPY --from=build /usr/local/bundle /usr/local/bundle
USER rails
EXPOSE 3000
ENV RAILS_ENV=production
ENV RAILS_SERVE_STATIC_FILES=true
CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose.yml

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://postgres:password@db:5432/myapp_production
      - REDIS_URL=redis://redis:6379/1
      - SECRET_KEY_BASE=${SECRET_KEY_BASE}
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp_production
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
volumes:
  postgres_data:
  redis_data:

Environment Configuration

# .env file (not committed)
SECRET_KEY_BASE=your-secret-key-here
DATABASE_URL=postgres://postgres:password@db:5432/myapp_production
REDIS_URL=redis://redis:6379/1
# config/database.yml
production:
  url: <%= ENV["DATABASE_URL"] %>
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

Entrypoint Script

#!/bin/bash
# bin/docker-entrypoint
set -e
# Remove pre-existing server PID
rm -f tmp/pids/server.pid
# Run database migrations
bundle exec rails db:migrate 2>/dev/null || bundle exec rails db:setup
exec "$@"
COPY bin/docker-entrypoint /usr/bin/
RUN chmod +x /usr/bin/docker-entrypoint
ENTRYPOINT ["docker-entrypoint"]
CMD ["rails", "server", "-b", "0.0.0.0"]

Common Mistakes

1. Including Development Gems in Production

Group development/test gems in the Gemfile. The Docker production build skips them with bundle install --without development test.

2. Running Migrations Automatically

Auto-running migrations in production can cause downtime. Run them manually or as a separate deployment step.

3. Missing Node.js for Asset Compilation

Rails requires a JavaScript runtime (Node.js) for uglifier and coffee-script. Install in the Dockerfile.

4. Not Setting RAILS_SERVE_STATIC_FILES

In production behind a different server, set RAILS_SERVE_STATIC_FILES=true or serve assets through Nginx.

5. Hardcoding Secrets in Dockerfile

Secrets in Dockerfiles are visible to anyone with image access. Use environment variables passed at runtime.

Practice Questions

1. Why use multi-stage Docker builds for Rails?

Build stage compiles assets and installs gems. Runtime stage is minimal (no build tools, smaller image).

2. How do you handle database migrations in Docker?

Run migrations in the entrypoint script or as a separate one-off container before starting the app.

3. What environment variables does a Rails app need in Docker?

DATABASE_URL, SECRET_KEY_BASE, REDIS_URL (if using Sidekiq), RAILS_ENV, RAILS_SERVE_STATIC_FILES.

4. How do you serve static assets in Dockerized Rails?

Set RAILS_SERVE_STATIC_FILES=true or use Nginx as a reverse proxy to serve public/assets/.

5. Challenge: Create a Dockerfile and docker-compose for a Rails app with PostgreSQL.

FROM ruby:3.3-slim
RUN apt-get update && apt-get install -y libpq-dev nodejs
WORKDIR /app
COPY Gemfile* ./
RUN bundle install
COPY . .
CMD ["rails", "server", "-b", "0.0.0.0"]

FAQ

What base image should I use for Rails?

ruby:3.3-slim for production (minimal). ruby:3.3 for development (includes build tools).

How do I run Sidekiq in Docker?

Add a separate service in docker-compose: command: ['bundle', 'exec', 'sidekiq']. Same image, different command.

Should I use Alpine images for Rails?

Alpine uses musl libc which can cause compatibility issues. slim images (Debian-based) are more reliable.

How do I handle file uploads in Docker?

Don't store uploads on the container filesystem. Use cloud storage (S3, GCS) or a shared volume.

How do I debug a Rails container?

Override the command: docker compose run app bash. Or use binding.pry with stdin_open: true.

Mini Project: Dockerized Rails with PostgreSQL

Create a complete Docker setup for a Rails app.

# Dockerfile, docker-compose.yml, .env
docker compose build
docker compose up
# App runs at localhost:3000

What's Next

Ruby on Rails Deployment Ruby on Rails Reference

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro