Docker Compose runs multi-container applications from a single YAML file. One command can start an API, a database, a message broker, and supporting tools for local development – without installing each service on the host machine.
This post covers Compose concepts and commands. For ready-made stacks, see the service-specific posts linked at the end (Postgres/Redis, RabbitMQ, MongoDB, Kafka, DynamoDB/SQS).
Prerequisites
- Docker Engine installed
- Compose V2 – use
docker compose(with a space). Current Docker Desktop includes it; no separate Compose install is required.
Mental model
-
Project – the folder that contains
docker-compose.yml. The project name defaults to the directory name and prefixes container names. -
Services – named containers defined in the file (
api,redis,postgres). Each service maps to one image or build context. -
Network – Compose creates a default network so services resolve each other by name. From the
apicontainer, Redis is reachable atredis:6379, notlocalhost:6379. -
Volumes – named or bind mounts for data that survives
docker compose down(unless you pass-v).
Minimal compose file
A two-service stack: a Node API and Redis. No top-level version: key – it is deprecated in the current Compose specification.
services:
api:
build: .
ports:
- 3000:3000
environment:
REDIS_URL: redis://redis:6379
depends_on:
- redis
redis:
image: redis:alpine
volumes:
- redis-data:/data
volumes:
redis-data:
Enter fullscreen mode Exit fullscreen mode
Run docker compose up --build from the directory that contains this file.
Core concepts
Ports – map host ports to container ports as host:container:
ports:
- 3000:3000
Enter fullscreen mode Exit fullscreen mode
Environment – inline variables or an env file:
environment:
REDIS_URL: redis://redis:6379
env_file:
- .env
Enter fullscreen mode Exit fullscreen mode
Volumes – named volumes are managed by Docker (good for database data). Bind mounts map a host path into the container (good for live code reload during development):
volumes:
- redis-data:/data # named
- ./src:/app/src:ro # bind mount
Enter fullscreen mode Exit fullscreen mode
Networks – services on the default network can reach each other by service name. Custom networks isolate groups of services (see the Postgres and Redis post for a multi-network example).
depends_on – controls startup order. It does not wait for the dependency to be ready; add a healthcheck or retry logic in the app when you need readiness.
restart – policies like on-failure:3 or unless-stopped keep containers running after crashes or host reboots.
healthcheck – optional probe so Compose and other services know when a container is ready:
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 5s
timeout: 3s
retries: 5
Enter fullscreen mode Exit fullscreen mode
Commands
Command Purposedocker compose up
Start services (foreground, logs in terminal)
docker compose up -d
Start in detached mode
docker compose up --build
Rebuild images before starting
docker compose down
Stop and remove containers
docker compose down -v
Also remove named volumes
docker compose ps
List running services
docker compose logs -f api
Follow logs for one service
docker compose exec api sh
Open a shell in a running container
docker compose pull
Pull latest images
When to use what
Tool Best fordocker run
One-off containers, quick image tests
Docker Compose
Local multi-service stacks, dev databases and queues
Kubernetes
Production orchestration, scaling, rolling deploys
Service-specific setups
- Postgres and Redis containers with Docker Compose – databases with Pgweb and Redis Commander
- RabbitMQ container with Docker Compose – message broker with management UI
- MongoDB containers with Docker Compose – MongoDB with Mongo Express
- Kafka containers with Docker Compose – KRaft-mode Kafka with Kafka UI
- DynamoDB and SQS containers with Docker Compose – DynamoDB Local and ElasticMQ
Need help with your project?
Get personalized advice on your architecture, code, or career in a 45-minute 1-on-1 consultation.
답글 남기기