Docker Compose is the free multi-container orchestration tool that defines your entire development environment in one YAML file. Run complex stacks with docker compose up.
Why Docker Compose?
-
One command —
docker compose upstarts everything - Declarative — define services, networks, volumes in YAML
- Development environment — identical setup for every team member
- Service discovery — containers find each other by name
- Hot reload — mount source code for live development
- Built into Docker — no separate installation since Docker 20.10+
Quick Start
# compose.yaml
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
volumes:
- ./src:/app/src # Hot reload
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
pgdata:
# Start everything
docker compose up -d
# View logs
docker compose logs -f app
# Stop everything
docker compose down
# Stop and remove volumes (clean slate)
docker compose down -v
Full-Stack Web App
services:
# Frontend (React/Next.js)
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- ./frontend/src:/app/src
- /app/node_modules
environment:
- NEXT_PUBLIC_API_URL=http://localhost:4000
# Backend API
api:
build:
context: ./backend
dockerfile: Dockerfile.dev
ports:
- "4000:4000"
volumes:
- ./backend/src:/app/src
environment:
- DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
- REDIS_URL=redis://cache:6379
- JWT_SECRET=super-secret-key
depends_on:
db:
condition: service_healthy
# Background workers
worker:
build: ./backend
command: node worker.js
environment:
- REDIS_URL=redis://cache:6379
- DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
depends_on:
- cache
- db
# Database
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 5s
retries: 5
# Redis cache + queue
cache:
image: redis:7-alpine
# Adminer (database UI)
adminer:
image: adminer
ports:
- "8080:8080"
volumes:
pgdata:
Profiles (Dev vs Production)
services:
app:
build: .
ports:
- "3000:3000"
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
# Only starts in dev profile
adminer:
image: adminer
ports:
- "8080:8080"
profiles:
- dev
# Only starts in debug profile
mailhog:
image: mailhog/mailhog
ports:
- "1025:1025"
- "8025:8025"
profiles:
- dev
- debug
# Production (no dev tools)
docker compose up -d
# Development (with adminer + mailhog)
docker compose --profile dev up -d
Multi-Stage Builds
# Dockerfile
# Stage 1: Build
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:22-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["node", "dist/server.js"]
Health Checks
services:
api:
build: .
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
Networking
services:
frontend:
networks:
- frontend-net
api:
networks:
- frontend-net # Can talk to frontend
- backend-net # Can talk to db
db:
networks:
- backend-net # Isolated from frontend
networks:
frontend-net:
backend-net:
Docker Compose vs Kubernetes vs Docker Swarm
| Feature | Docker Compose | Kubernetes | Docker Swarm |
|---|---|---|---|
| Complexity | Low | Very High | Medium |
| Best for | Dev/small prod | Large production | Medium production |
| Scaling | Manual | Auto-scaling | Manual |
| Config | YAML (simple) | YAML (complex) | YAML |
| Load balancing | Nginx/Traefik | Built-in | Built-in |
| Health checks | Yes | Yes | Yes |
| Secrets | Environment/files | Secrets API | Secrets API |
Need to scrape data from any website and get it in structured JSON? Check out my web scraping tools on Apify — no coding required, results in minutes.
Have a custom data extraction project? Email me at spinov001@gmail.com — I build tailored scraping solutions for businesses.
Top comments (0)