In 2022, I started moving beyond simple deployments on Heroku and exploring Docker for the first time. Docker seemed intimidating at first, but once I got a Rails + React app running in containers, it completely changed the way I thought about deployments and collaboration.
Here’s how I approached Dockerizing a full-stack application.
Consistency → If it runs on my machine, it runs everywhere.
Isolation → Rails, React, Postgres, Redis — each in its own container.
Collaboration → No more “it broke on my setup” excuses.
Deployment-ready → The same image could be shipped to AWS, GCP, or DigitalOcean.
# Dockerfile for Rails
FROM ruby:3.1
WORKDIR /app
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
COPY Gemfile* ./
RUN bundle install
COPY . .
CMD ["rails", "server", "-b", "0.0.0.0"]
# Dockerfile for React
FROM node:16
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# Build for production
RUN npm run build
CMD ["npm", "start"]
To run backend, frontend, Postgres, and Redis together:
version: "3.9"
services:
backend:
build: ./backend
command: bundle exec rails s -b 0.0.0.0 -p 3000
ports:
- "3000:3000"
volumes:
- ./backend:/app
depends_on:
- db
- redis
frontend:
build: ./frontend
command: npm start
ports:
- "3001:3000"
volumes:
- ./frontend:/app
db:
image: postgres:14
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
redis:
image: redis:6
ports:
- "6379:6379"
docker-compose build
docker-compose up
Rails API → http://localhost:3000
React frontend → http://localhost:3001
Postgres & Redis up and connected 🚀
Volumes are critical for hot reloading in development.
.env files are the right way to manage secrets and configs.
Keep separate configs for dev and production (dev = hot reload, prod = prebuilt images).
Docker isn’t just for deployment — it’s for team consistency.
Docker felt like a steep learning curve at first, but it turned out to be one of the most valuable tools I picked up in 2022. It simplified my deployments, gave my team a common environment, and made me feel like I was building “real” production-ready systems.