Docker Compose is a tool for defining and running multi-container applications using a YAML file. With a single docker compose up command, you can create and start all the services, networks, and volumes your application needs.
docker-compose.yml Structure
A Compose file has four top-level keys:
version: "3.9" # optional in Compose V2+
services: # container definitions
volumes: # named volumes
networks: # custom networks
Defining Services
Each service is a container. Here's a web app with PostgreSQL:
services:
web:
build: .
ports:
environment:
DATABASE_URL: postgres://user:pass@db:5432/mydb
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 10s
timeout: 5s
retries: 5
volumes:
pgdata:
Key Service Properties
build vs image
build: . — build from Dockerfile in current directorybuild: { context: ./app, dockerfile: Dockerfile.prod } — build with custom contextimage: nginx:alpine — pull from Docker Hubports
ports:
environment and env_file
environment:
NODE_ENV: production
API_KEY: ${API_KEY} # from shell environment
env_file:
volumes
volumes:
depends_on with health checks
depends_on:
db:
condition: service_healthy # wait for healthcheck to pass
redis:
condition: service_started # just wait for container start
Networking
By default, all services in a Compose file share one network and can reach each other by service name:
# web can connect to db at host "db", port 5432
environment:
DATABASE_URL: postgres://user:pass@db:5432/mydb
Custom networks isolate services:
services:
web:
networks: [frontend, backend]
db:
networks: [backend]
nginx:
networks: [frontend]
networks:
frontend:
backend:
internal: true # no external internet access
Common Service Templates
Redis
redis:
image: redis:7-alpine
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
ports:
MongoDB
mongo:
image: mongo:7
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: secret
volumes:
Nginx reverse proxy
nginx:
image: nginx:alpine
ports:
volumes:
depends_on: [web]
Compose Profiles (Selective Services)
Profiles let you start only certain services:
services:
web:
profiles: [] # always starts
docs:
profiles: ["docs"]
debug:
profiles: ["debug"]
docker compose --profile docs up # starts web + docs
docker compose --profile debug up # starts web + debug
Essential Commands
docker compose up -d # start in background
docker compose down # stop and remove containers
docker compose down -v # also remove volumes
docker compose logs -f web # follow logs for a service
docker compose exec web sh # shell into a running container
docker compose ps # list running services
docker compose build --no-cache # rebuild without cache
Override Files
docker-compose.override.yml is automatically merged with the base file:
# docker-compose.override.yml (dev overrides)
services:
web:
volumes:
command: npm run dev
Generate a ready-to-use docker-compose.yml with our Docker Compose Generator — pick your services and get the YAML instantly.
