Official guide to composing multi-service stacks with health checks and networking. Read →
This lesson brings everything together: Node.js API + Worker + PostgreSQL + Redis + RabbitMQ running with one command.
# Start everything
docker compose up -d
# Watch all logs
docker compose logs -f
# Connect to Redis CLI
docker compose exec redis redis-cli
# RabbitMQ management UI
open http://localhost:15672 # user: user / password: password
# Connect to Postgres
docker compose exec db psql -U user myapp
# Scale workers for parallel job processing
docker compose up -d --scale worker=3
version: "3.9"
services:
api:
build: { context: ., dockerfile: Dockerfile }
ports: ["3000:3000"]
env_file: [.env]
depends_on:
db: { condition: service_healthy }
redis: { condition: service_healthy }
rabbitmq: { condition: service_healthy }
restart: unless-stopped
networks: [app]
logging:
driver: json-file
options: { max-size: "10m", max-file: "3" }
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 30s; timeout: 10s; retries: 3
worker:
build: .
command: node dist/workers/index.js
env_file: [.env]
depends_on:
rabbitmq: { condition: service_healthy }
redis: { condition: service_healthy }
restart: unless-stopped
networks: [app]
db:
image: postgres:16-alpine
environment: { POSTGRES_DB: myapp, POSTGRES_USER: user, POSTGRES_PASSWORD: password }
volumes: [postgres:/var/lib/postgresql/data]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
interval: 10s; timeout: 5s; retries: 5
networks: [app]
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes: [redis:/data]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s; timeout: 3s; retries: 3
networks: [app]
rabbitmq:
image: rabbitmq:3-management-alpine
environment: { RABBITMQ_DEFAULT_USER: user, RABBITMQ_DEFAULT_PASS: password }
ports: ["15672:15672"]
volumes: [rabbitmq:/var/lib/rabbitmq]
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "ping"]
interval: 15s; timeout: 10s; retries: 5
networks: [app]
volumes:
postgres:; redis:; rabbitmq:
networks:
app:
# .env for local development
NODE_ENV=development
PORT=3000
DATABASE_URL=postgres://user:password@db:5432/myapp
REDIS_URL=redis://redis:6379
RABBITMQ_URL=amqp://user:password@rabbitmq:5672
# Key insight: service names are hostnames inside the Docker network
# "db", "redis", "rabbitmq" — NOT localhost
In production on separate servers, replace these with real endpoints: your ElastiCache Redis URL, your RDS hostname, your AmazonMQ broker URL.
docker compose ps # Health status of all services
docker compose logs -f api # Live API logs
docker compose exec redis redis-cli KEYS "*" # Inspect Redis keys
docker compose exec rabbitmq rabbitmqctl list_queues name messages consumers
docker compose up -d --build api # Rebuild and restart one service