Docker Compose Cheatsheet
The complete quick reference for docker-compose.yml syntax and docker compose CLI commands. Covers every key you will use in production, plus real-world example files you can copy and adapt.
Top-Level Keys
Every docker-compose.yml file is built from these root-level keys. The services key is the only one that is required.
| Key | Description |
|---|---|
| version | Compose file format version (deprecated in Compose V2 — included for legacy compatibility). |
| services | Define the containers (services) that make up your application. |
| volumes | Declare named volumes that can be shared across services. |
| networks | Create custom networks for inter-service communication. |
| configs | Define configuration objects that can be mounted into services. |
| secrets | Declare sensitive data that is made available to services at runtime. |
Service Configuration
Keys available inside each service definition. These control how the container is built, configured, and connected.
| Key | Description |
|---|---|
| image | The Docker image to use, e.g. postgres:16-alpine. |
| build | Build context and Dockerfile path. Accepts a string or object with context, dockerfile, args, target. |
| container_name | Custom name for the container (default is project_service_index). |
| command | Override the default CMD of the image. |
| entrypoint | Override the default ENTRYPOINT of the image. |
| ports | Map host ports to container ports. Short syntax: "8080:80". Long syntax supported. |
| expose | Expose ports to other services on the network without publishing to the host. |
| environment | Set environment variables as a map or list: KEY=value. |
| env_file | Load environment variables from one or more .env files. |
| volumes | Mount host paths or named volumes. Short: ./data:/var/lib/data. Long syntax supported. |
| networks | Attach the service to one or more networks. |
| depends_on | Express service startup order. Use condition: service_healthy for health-gated deps. |
| restart | Restart policy: no | always | on-failure | unless-stopped. |
| healthcheck | Define a health check: test, interval, timeout, retries, start_period. |
| deploy | Swarm/resource configuration: replicas, resources (limits/reservations), placement, update_config. |
| labels | Add metadata labels to the container. |
| logging | Configure the logging driver and options. |
| working_dir | Set the working directory inside the container. |
| user | Run the container process as this user (uid:gid). |
| stdin_open / tty | Keep STDIN open (stdin_open: true) and allocate a TTY (tty: true) for interactive use. |
| profiles | Assign the service to one or more profiles so it only starts when that profile is active. |
| platform | Target platform, e.g. linux/amd64 or linux/arm64. |
| shm_size | Size of /dev/shm, e.g. 256m. |
| cap_add / cap_drop | Add or drop Linux capabilities. |
| privileged | Run the container in privileged mode (full host access). |
| extra_hosts | Add entries to /etc/hosts inside the container. |
| dns | Custom DNS servers for the container. |
| tmpfs | Mount a temporary filesystem inside the container. |
| ulimits | Set container ulimits (nofile, nproc, etc.). |
Healthcheck
Health checks let Compose wait until a service is actually ready before starting dependent services. Combine with depends_on: condition: service_healthy.
| Key | Description |
|---|---|
| test | Command to run. Use ["CMD", "curl", "-f", "http://localhost"] or CMD-SHELL string. |
| interval | Time between checks, e.g. 30s. Default 30s. |
| timeout | Max time for a single check, e.g. 10s. Default 30s. |
| retries | Consecutive failures before marking unhealthy. Default 3. |
| start_period | Grace period before checks count, e.g. 40s. Default 0s. |
| start_interval | Interval during start_period (Compose V2.22+). Default same as interval. |
Volumes
Named volumes declared under the top-level volumes:key persist data beyond the container lifecycle. Bind mounts (host paths) are specified directly in the service's volumes: list.
| Key | Description |
|---|---|
| driver | Volume driver to use (default: local). |
| driver_opts | Driver-specific options as key-value pairs. |
| external | If true, the volume must already exist (not created by Compose). |
| name | Custom name for the volume on the Docker host. |
| labels | Metadata labels for the volume. |
Volume Mount Syntax
named_vol:/container/path— named volume./host/path:/container/path— bind mount (relative)/abs/path:/container/path:ro— read-only bind mounttype: volume, source: mydata, target: /data— long syntax
Networks
By default Compose creates a single network for your project. Custom networks let you isolate services and control which containers can talk to each other.
| Key | Description |
|---|---|
| driver | Network driver: bridge (default), host, overlay, macvlan, none. |
| driver_opts | Driver-specific options. |
| external | If true, the network must already exist. |
| internal | If true, restrict external access to the network. |
| ipam | IP Address Management: driver, config (subnet, gateway). |
| name | Custom name for the network. |
| attachable | Allow standalone containers to attach to this network (overlay only). |
Deploy & Resources
The deploy key controls replica count, resource limits, rolling update strategy, and placement. Originally Swarm-only, many fields are now respected by docker compose up in Compose V2.
| Key | Description |
|---|---|
| replicas | Number of container replicas to run. |
| resources.limits | CPU and memory limits, e.g. cpus: '0.5', memory: 512M. |
| resources.reservations | Guaranteed CPU and memory reservations. |
| restart_policy | Condition, delay, max_attempts, window for restarts. |
| update_config | Rolling update settings: parallelism, delay, failure_action, order. |
| rollback_config | Settings for automatic rollback on update failure. |
| placement.constraints | Placement constraints, e.g. node.role == manager. |
CLI Commands
All docker compose (V2) commands. The legacy docker-compose (hyphenated) syntax works the same way.
| Command | Description |
|---|---|
| docker compose up | Create and start all services defined in the compose file. |
| docker compose up -d | Start services in detached (background) mode. |
| docker compose up --build | Rebuild images before starting services. |
| docker compose up --force-recreate | Recreate containers even if config has not changed. |
| docker compose up --scale web=3 | Start with 3 replicas of the web service. |
| docker compose down | Stop and remove containers, networks created by up. |
| docker compose down -v | Also remove named volumes declared in the compose file. |
| docker compose down --rmi all | Also remove all images used by services. |
| docker compose build | Build or rebuild service images. |
| docker compose build --no-cache | Build without using cache layers. |
| docker compose pull | Pull the latest images for all services. |
| docker compose push | Push service images to a registry. |
| docker compose ps | List running containers for the project. |
| docker compose ps -a | List all containers (including stopped). |
| docker compose logs | View output logs from all services. |
| docker compose logs -f | Follow (tail) logs in real time. |
| docker compose logs web | View logs for a specific service. |
| docker compose exec web sh | Open an interactive shell in a running service container. |
| docker compose run web bash | Run a one-off command in a new container for the service. |
| docker compose stop | Stop running services without removing containers. |
| docker compose start | Start previously stopped services. |
| docker compose restart | Restart all services. |
| docker compose pause | Pause all running services. |
| docker compose unpause | Unpause paused services. |
| docker compose top | Display running processes for each service. |
| docker compose config | Validate and display the resolved compose file. |
| docker compose config --services | List service names defined in the compose file. |
| docker compose cp web:/app/log.txt ./log.txt | Copy files between a service container and the host. |
| docker compose watch | Watch for file changes and sync/rebuild automatically (Compose Watch). |
| docker compose events | Stream real-time events from containers. |
| docker compose port web 80 | Print the public port mapped to a service's container port. |
Example Compose Files
Copy these production-ready examples and adapt them to your project. Each demonstrates common patterns: health checks, named volumes, multi-network isolation, and resource limits.
Web App + PostgreSQL
services:
web:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://app:secret@db:5432/myapp
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 10s
timeout: 5s
retries: 5
volumes:
pgdata:Full Stack: Frontend + API + Postgres + Redis
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
NEXT_PUBLIC_API_URL: http://localhost:4000
depends_on:
- api
api:
build:
context: ./api
dockerfile: Dockerfile
ports:
- "4000:4000"
environment:
DATABASE_URL: postgres://app:secret@db:5432/myapp
REDIS_URL: redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
pgdata:Multi-Service with RabbitMQ, Nginx Reverse Proxy & Custom Networks
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/certs:/etc/nginx/certs:ro
depends_on:
- app1
- app2
networks:
- frontend
app1:
build: ./services/app1
expose:
- "8001"
environment:
- APP_NAME=service-one
deploy:
replicas: 2
resources:
limits:
cpus: "0.5"
memory: 256M
networks:
- frontend
- backend
app2:
build: ./services/app2
expose:
- "8002"
environment:
- APP_NAME=service-two
deploy:
replicas: 2
resources:
limits:
cpus: "0.5"
memory: 256M
networks:
- frontend
- backend
worker:
build: ./services/worker
environment:
RABBITMQ_URL: amqp://rabbit:5672
depends_on:
rabbit:
condition: service_healthy
deploy:
replicas: 3
networks:
- backend
rabbit:
image: rabbitmq:3-management-alpine
ports:
- "15672:15672"
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "check_running"]
interval: 30s
timeout: 10s
retries: 5
networks:
- backend
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: multi
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
networks:
frontend:
backend:
volumes:
pgdata:Development Override (docker-compose.override.yml)
# docker-compose.override.yml — auto-merged with docker-compose.yml
services:
web:
build:
context: .
target: development
volumes:
- .:/app
- /app/node_modules
environment:
NODE_ENV: development
DEBUG: "true"
ports:
- "9229:9229" # Node.js debugger
command: npm run dev
db:
ports:
- "5432:5432" # Expose DB to host for local toolsTips & Best Practices
Use .env Files
Store secrets and configuration in .env files and reference them with env_file: or variable substitution $${VAR}. Never hard-code secrets in the compose file.
Pin Image Tags
Always specify an explicit tag like postgres:16-alpine instead of postgres:latest. This ensures reproducible builds and prevents surprise breakages.
Health-Gated Dependencies
Use depends_on: condition: service_healthy instead of bare depends_on. This ensures a database is actually accepting connections before your app tries to connect.
Override Files for Dev
Create docker-compose.override.yml for development-only settings (hot reload, exposed ports, debug mode). Compose merges it automatically.