Docker Compose Cheatsheet - Most useful commands with examples
BTW, docker-compose is different from docker compose...
Here’s a Docker Compose cheatsheet with annotated examples to help you master Compose files and commands quickly.
Compose File Reference: docker-compose.yml
Core structure:
version: '3' # Compose file format version
services:
web:
image: nginx:latest
ports:
- "8080:80" # Host port 8080:Container port 80
db:
image: postgres
environment: # Environment variables
POSTGRES_PASSWORD: example
volumes:
- db_data:/var/lib/postgresql/data
networks: # Custom network
appnet:
driver: bridge
volumes: # Named volume
db_data:
- services: Each container in your multi-container app. In the example above we have two services:
web
anddb
. - networks & volumes: Define isolated networks and persistent storage - we have
appnet
network anddb_data
volume here.
Examples
Single service with port mapping
services:
app:
build: .
ports:
- "8000:80" # Host port 8000:Container port 80
Exposes app on host port 8000 and builds from Dockerfile in current directory.
Multi-service with shared volume and custom network
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- type: bind
source: ./app
target: /app
networks:
- mynet
db:
image: postgres
volumes:
- db_data:/var/lib/postgresql/data
networks:
- mynet
networks:
mynet:
volumes:
db_data:
Web and DB on same network; DB uses persisted named volume - db_data
.
Using build context and Dockerfile path
You can build docker image on demand from the specified in docker-compose.yam Dockerfile.
services:
app:
build:
context: .
dockerfile: docker/MyDockerfile
Sharing data between services
services:
web:
image: nginx
volumes:
- shared_data:/usr/share/nginx/html
worker:
image: myworker
volumes:
- shared_data:/usr/src/app/data
volumes:
shared_data:
Both services access same volume (for static files or data exchanges) - shared_data
.
Advanced Compose File Options
- environment: Set ENV variables for containers.
- depends_on: Control service startup order.
- deploy.replicas: Scale service in Swarm mode.
Example:
services:
web:
image: nginx
deploy:
replicas: 3
depends_on:
- db
Starts 3 web instances; only controls startup order (not readiness).
Essential Docker Compose Commands
Command | Description | Example Usage |
---|---|---|
docker-compose up |
Creates and starts containers | docker-compose up |
docker-compose up -d |
Run in background | docker-compose up -d |
docker-compose exec |
Execute command in running container | docker-compose exec web bash |
docker-compose build |
Build/rebuild images | docker-compose build |
docker-compose down |
Stop and remove containers, networks, volumes, and images | docker-compose down |
docker-compose logs -f |
View and follow logs | docker-compose logs -f |
docker-compose ps |
List running containers | docker-compose ps |
docker-compose run |
Run one-off commands (bypasses command in Compose file) | docker-compose run web python manage.py migrate |
docker-compose stop |
Stop running containers (can restart with start ) |
docker-compose stop |
docker-compose restart |
Restart services | docker-compose restart web |
docker-compose pull |
Pull service images | docker-compose pull |
docker-compose rm |
Remove stopped service containers | docker-compose rm web |
docker-compose config |
Validate and view Compose file | docker-compose config |
docker-compose up --scale web=3 |
Start multiple instances of a service | docker-compose up --scale web=3 |
Common Compose Patterns
-
Databases with persistent data
services: mysql: image: mysql environment: MYSQL_ROOT_PASSWORD: password volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:
DB data persists in the
mysql_data
volume across container restarts. -
Bind mounting code for development
services: app: build: . volumes: - .:/app
Live-edit code on host, auto-reflected in container.
Useful Flags
-d
: Detach mode (run in background).--build
: Force rebuild images before starting.--force-recreate
: Recreate containers even if unchanged.--remove-orphans
: Remove containers not defined in Compose file.
Defining and Customizing Services
You can define and customize services, networks, and volumes in Docker Compose by leveraging the docker-compose.yml
file, which centralizes all your application’s configuration and orchestration needs.
- Services are defined under the
services
key. - Each service represents a container configuration, where you can set:
- Image: Select an image from Docker Hub or another registry.
- Ports: Map container ports to host ports.
- Environment variables: Pass configuration values.
- Volumes: Persist data or share files/folders with the host or other services.
- Networks: Control which networks the service can access.
Example:
services:
web:
image: nginx:latest
ports:
- "8080:80" # Host port 8080:Container port 80
environment:
- NGINX_HOST=localhost
volumes:
- web_data:/usr/share/nginx/html
networks:
- frontend
db:
image: postgres:13
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret
volumes:
- db_data:/var/lib/postgresql/data
networks:
- backend
- Here, the
web
service uses the nginx image, sets an environment variable, attaches a volume, opens port 80 as 8080 on the host, and connects to thefrontend
network. Thedb
service does something similar for PostgreSQL.
Customizing Networks
- Networks control which services can communicate. Compose creates a default network, but you can define more, specify custom drivers, set options, and determine which service joins which network for fine-grained isolation.
- Define networks at the top level under
networks
, and list which networks a service should attach to with the service-levelnetworks
key.
Example:
networks:
frontend:
driver: bridge
backend:
driver: bridge
driver_opts:
com.docker.network.bridge.host_binding_ipv4: "127.0.0.1"
- Attach networks to services:
services:
app:
networks:
- frontend
- backend
db:
networks:
- backend
- This setup allows the
app
service to access both users on thefrontend
andbackend
networks, whiledb
is only accessible within thebackend
.
Customizing Volumes
- Volumes are defined under the top-level
volumes
key. Mount them to containers using thevolumes
key under a service. - Volumes can be named, use custom drivers, and be shared across multiple services for data persistence and sharing.
Example:
volumes:
web_data: # Named volume for web content
db_data: # Named volume for database
services:
web:
volumes:
- web_data:/usr/share/nginx/html
db:
volumes:
- db_data:/var/lib/postgresql/data
- In this example,
web_data
is persisted and available to any container that mounts it.db_data
ensures database data is never lost upon container recreation. - You can define bind-mounts with custom driver options for advanced cases:
volumes:
db_data:
driver: local
driver_opts:
type: none
device: /data/db_data
o: bind
- This configuration sets up a bind-mount from the host path
/data/db_data
into the container.
Summary of Best Practices:
- Use the service name as a DNS hostname for inter-service communication.
- Attach services to multiple networks as needed to control access.
- Use named volumes for persistent storage and data sharing.
- Define everything using YAML, enabling version control and easy deployment scripts.
Multiple compose files
To organize complex multi-service setups in Docker Compose, you can use multiple compose files and override files, allowing modular, environment-specific, and scalable configurations. Here’s how this works:
- Base and Override File Structure
- Create a base file (
compose.yaml
ordocker-compose.yml
) containing all common, default service definitions. - Add environment-specific override files (e.g.,
docker-compose.override.yml
,docker-compose.dev.yml
,docker-compose.prod.yml
).
Example file structure:
/project-directory
|-- docker-compose.yml # Base configuration
|-- docker-compose.override.yml # Local/dev overrides (applied automatically)
|-- docker-compose.prod.yml # Production overrides
|-- docker-compose.test.yml # Test overrides (if needed)
The base config defines core services, while each override customizes settings for a specific environment or case.
- How File Overrides Work
- Merging: When you run
docker compose up
, Docker Compose merges the base with any overrides in order; subsequent files override, extend, or add to settings in previous files. - Overriding Fields: If a service or field is defined in multiple files, the last-specified file’s value is used. New fields are added.
Example merge:
docker-compose.yml
:services: web: image: myapp ports: - "8000:80"
docker-compose.override.yml
:services: web: environment: - DEBUG=true
- Result: The
web
service uses both the base image and port plus the overriddenDEBUG
environment variable.
- Command Usage for Multiple Files
- Default behavior: If present, Docker Compose automatically loads
docker-compose.override.yml
together withdocker-compose.yml
when you run any command. - Specifying files manually: Use
-f
flags to control which files are merged and in what order:docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
- This ignores the default override and uses the production-specific settings.
- Practical Organization Strategies
- Environment separation: Use one override per environment: dev, test, prod, etc.
- Microservices and teams: Break configuration into separate files for different services or teams, and combine as needed.
- Feature toggles: Additional files can introduce or remove optional services or configuration for temporary needs (e.g., a
compose.debug.yml
for extra logging).
- Benefits
- Clarity: Keeps individual files small and focused.
- Scalability: Easily add new services, environments, or settings.
- Maintainability: Only change or review relevant sections for a given deployment.
- Example: Switching Environments
Development:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
Production:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Each environment gets only the configuration necessary for it, with all shared config in the base file.
Organizing complex Compose setups with multiple files - and leveraging the override/merge system-ensures modularity, environment-specific customization, and easy scalability for large, multi-service Docker applications.