In this detailed guide, I’ll show you how to create a brand-new Ruby on Rails application
without installing Ruby, Rails, Node.js, Yarn, or PostgreSQL on your machine.
Everything will be isolated inside Docker containers.
✅ You’ll learn how to:
- Generate a new Rails app inside a container
- Run your app with PostgreSQL using Docker Compose
- Modify your app setup for proper development mode
- Understand why each step is important
- Follow production-quality best practices
Step 1: Build the Rails Application Using Docker
First, you need a special Dockerfile that generates your Rails app.
It installs Ruby, Rails, and any other dependencies inside a container.
Dockerfile
to Generate Rails App
# syntax=docker/dockerfile:1
# ---------- ARGUMENTS ----------
ARG RUBY_VERSION=latest
ARG RAILS_VERSION=latest
# ---------- BASE IMAGE ----------
FROM ruby:${RUBY_VERSION}
# ---------- ARGUMENTS INSIDE CONTAINER ----------
ARG RAILS_VERSION
ENV APP_NAME=rails_app
ENV RAILS_OPTIONS=""
# ---------- INSTALL DEPENDENCIES ----------
RUN apt-get update -qq && \
apt-get install -y build-essential nodejs yarn git && \
if [ "$RAILS_VERSION" = "latest" ]; then \
gem install rails; \
else \
gem install rails -v "$RAILS_VERSION"; \
fi
# ---------- SET WORKDIR ----------
WORKDIR /app
# ---------- COMMAND ----------
CMD if [ -n "$RAILS_OPTIONS" ]; then \
rails new "$APP_NAME" $RAILS_OPTIONS; \
else \
rails new "$APP_NAME"; \
fi
What this Dockerfile Does:
- Installs Ruby and Rails.
- Installs Node.js and Yarn (required for Rails 7 JavaScript pipeline).
- Sets
/app
as working directory. - Runs
rails new
to create a brand-new app, optionally with extra flags (like--api
,--database=postgresql
).
Step 2: Build and Run to Generate the App
Now build the generator image:
docker build \
--build-arg RUBY_VERSION=3.2.8 \
--build-arg RAILS_VERSION=7.1.3 \
--build-arg APP_NAME=myapp \
--build-arg RAILS_OPTIONS="--database=postgresql" \
-t rails-generator .
This builds a temporary Docker image that knows how to create Rails apps.
Now run it to generate the app on your local system:
docker run --rm -v "$PWD":/app rails-generator
Your new Rails application (myapp/
) will appear in your current directory.
Step 3: Update the Newly Created App for Development
When Rails creates an app, it’s often production-focused by default (especially Dockerfile).
We need to prepare it properly for local development.
3.1 Update the generated Dockerfile
Find the Dockerfile inside myapp/
and update this:
From:
# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_WITHOUT="development"
Change to:
# Set development environment for local development
ENV RAILS_ENV="development" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle"
Now Rails will run in development mode inside Docker.
3.2 Update config/database.yml
Rails by default assumes database is on localhost
.
But with Docker Compose, our database will be inside a service container (db
).
So, replace your config/database.yml
with:
default: &default
adapter: postgresql
encoding: unicode
host: <%= ENV['DATABASE_HOST'] || 'localhost' %>
username: <%= ENV['DATABASE_USERNAME'] || 'postgres' %>
password: <%= ENV['DATABASE_PASSWORD'] || 'password' %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
production:
<<: *default
database: myapp_production
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
Now Rails will connect automatically to the database service running in Compose.
Step 4: Create the docker-compose.yml
File
Now create a docker-compose.yml
file inside your project (myapp/
):
version: "3.9"
services:
db:
image: postgres:15
container_name: rails_db
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: myapp_development
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
web:
build:
context: .
dockerfile: Dockerfile
container_name: rails_web
command: bash -c "bundle install && ./bin/rails db:create db:migrate && ./bin/rails server -b 0.0.0.0"
volumes:
- .:/app
ports:
- "3000:3000"
environment:
DATABASE_HOST: db
DATABASE_USERNAME: postgres
DATABASE_PASSWORD: password
depends_on:
- db
volumes:
postgres_data:
Rails app talks to the db
container via network.
No manual installation of Postgres needed.
Step 5: Start Your App
docker-compose up --build
It will:
- Start PostgreSQL
- Install Ruby gems
- Create and migrate the database
- Start the Rails server
- Serve your app at http://localhost:3000
Why This Approach Is Powerful
Problem with Local Setup | Solved By This Method |
---|---|
Ruby version conflicts | Build image with desired Ruby version |
System polluted with gems, postgres, node, yarn | Fully isolated clean Docker environment |
Team onboarding pain (installing Ruby/Postgres/Yarn) | Just clone repo + docker-compose up |
Development vs Production mismatch | Docker Compose matches real server layout |
Local crashes due to gem compilation issues | Controlled consistent environment |
System dependency hell (Postgres client versions etc.) | Solved inside docker images |
Pro Tip for Further Improvements
You can add a .env
file to manage database credentials.
You can separate docker-compose.dev.yml
and docker-compose.prod.yml
for clean environments.
Final command summary:
Command | Purpose |
---|---|
docker build | Build Rails generator image |
docker run | Generate new app |
docker-compose up --build | Run app and database |
Learn more about Docker setup
Awesome https://is.gd/N1ikS2
Good https://is.gd/N1ikS2
Very good https://is.gd/N1ikS2
Good https://is.gd/N1ikS2
Awesome https://is.gd/N1ikS2