homeresume
 
   

Docker Compose overview

Published June 20, 2026Last updated June 20, 20264 min read

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 api container, Redis is reachable at redis:6379, not localhost: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:

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

Environment - inline variables or an env file:

environment:
REDIS_URL: redis://redis:6379
env_file:
- .env

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

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

Commands

CommandPurpose
docker compose upStart services (foreground, logs in terminal)
docker compose up -dStart in detached mode
docker compose up --buildRebuild images before starting
docker compose downStop and remove containers
docker compose down -vAlso remove named volumes
docker compose psList running services
docker compose logs -f apiFollow logs for one service
docker compose exec api shOpen a shell in a running container
docker compose pullPull latest images

When to use what

ToolBest for
docker runOne-off containers, quick image tests
Docker ComposeLocal multi-service stacks, dev databases and queues
KubernetesProduction orchestration, scaling, rolling deploys

Service-specific setups

Demo

Runnable files for this post live in the docker-compose-overview-demo folder. Get access via code demos.