Docker Compose is a tool for defining and running multi-container applications. It uses YAML files to configure service groups and is designed for quickly setting up development environments.
open_in_new Official documentation
Installation
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
See open_in_new docs.docker.com/compose/install for current versions.
docker-compose.yml
Be careful not to use unescaped $ characters — escape them as $$ if needed.
Example:
version: '3'
services:
web:
image: nginx
ports:
- "8080:80"
volumes:
- nginx_html:/usr/share/nginx/html/
links:
- redis
redis:
image: redis
volumes:
nginx_html: {}
Four top-level keys: version, services, networks, volumes.
services
Each service definition represents one container. The service name becomes part of the container name.
version: '3'
services:
weather-app:
build:
context: .
args:
- VERSION=v2.0
ports:
- "8081:3000"
environment:
- NODE_ENV=production
Key service options:
- container_name — explicit container name.
- build — build from a Dockerfile in the given context (
.). Each service needs eitherbuildorimage. - image — image tag or ID, like the
imageargument indocker run. - ports — same as
-pindocker run. Use quotes to avoid YAML parsing issues (e.g.,56:56as hex). - environment — same as
-eindocker run. - volumes — same as
-vindocker run. - networks — attach to named networks:
services:
test:
networks:
- my_network
- another_network
- depends_on — declare service dependencies:
services:
test:
depends_on:
- mysql
- links — legacy container linking (prefer networks):
identidock:
links:
- dnmonster
- extends — inherit configuration from a shared file. Values in
linksandvolumes-fromare not inherited.
networks
Define networks managed by Compose:
networks:
my_network:
my_second_network:
volumes
Define volumes managed by Compose:
volumes:
my_volume:
my_second_volume:
Driver options can be added as needed.
Restart option
no is the default restart policy, and it does not restart a container under any circumstance.
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
When always is specified, the container always restarts.
unless-stopped always restarts a container, except when the container is stopped (manually or otherwise).
The on-failure policy restarts a container if the exit code indicates an on-failure error. Optionally, limit retries with :max-retries:
restart: on-failure:10
open_in_new Documentation page .
Compose commands
up
Create and start all containers defined in the Compose file. Logs are merged into one stream. Use -d for detached mode.
docker-compose up
docker-compose up -d
Set a custom compose file via environment variable:
COMPOSE_FILE=prod.yml docker-compose up -d
ps
List containers created by Compose.
docker-compose ps
stop / start / restart / down
docker-compose stop # stop without removing
docker-compose start # start stopped services
docker-compose restart
docker-compose down # stop and remove containers, networks, images, volumes
build
Rebuild all images from Dockerfiles. up only builds if images do not exist — run build explicitly when source changes.
docker-compose build
run
Run a one-off command in a service container (not as a long-running service). Dependent services start unless --no-deps is set. Commands passed via run override the service command. By default, run does not create the ports defined in the service config.
docker-compose run <service> <command>
logs
Show colorized, merged logs from all Compose-managed containers.
docker-compose logs
rm
Remove stopped containers. Use -v to also remove volumes managed by Docker.
docker-compose rm
docker-compose rm -v
Lifecycle
After changing source code, run docker-compose build then docker-compose up -d. Compose rebuilds the image and replaces the running container. Existing volumes from old containers are preserved — databases and caches survive upgrades (which can cause stale data; be careful when replacing containers).
If only the Compose YAML changed (no image rebuild needed), run docker-compose up -d to recreate containers with new settings. Use --force-recreate to stop everything and recreate all containers.
After a work session, run docker-compose stop. The same containers restart with docker-compose start or up if source code has not changed. Use docker-compose rm to permanently remove the application’s containers.
Andrew Dorokhov