What Is Docker Compose? A Beginner's Guide (2026)
Docker Compose lets you define and run multi-container applications with a single file. Here's what it does, how it works, and when to use it — explained simply.
Running a web application usually means running multiple things at once — a web server, a database, maybe a cache. Docker Compose lets you define all of them in one file and start everything with one command.
The Problem Docker Compose Solves
Without Compose, starting a web app with a database looks like:
# Step 1: Create a network
docker network create myapp-network
# Step 2: Start PostgreSQL
docker run -d \
--name postgres \
--network myapp-network \
-e POSTGRES_PASSWORD=secret \
-v postgres-data:/var/lib/postgresql/data \
postgres:16
# Step 3: Start Redis
docker run -d \
--name redis \
--network myapp-network \
redis:7
# Step 4: Start your app
docker run -d \
--name myapp \
--network myapp-network \
-p 3000:3000 \
-e DATABASE_URL=postgres://postgres:secret@postgres:5432/mydb \
-e REDIS_URL=redis://redis:6379 \
myapp:latestThat's 4 commands. And you need to remember the right order. And if you want to stop everything, you need 3 more commands.
With Docker Compose, all of that becomes one file and one command.
The Same Thing With Docker Compose
# docker-compose.yml
version: "3.9"
services:
app:
image: myapp:latest
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://postgres:secret@db:5432/mydb
REDIS_URL: redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: redis:7
volumes:
- redis-data:/data
volumes:
postgres-data:
redis-data:Now:
docker compose up -d # start everything
docker compose down # stop everything
docker compose logs -f # see all logs
docker compose ps # see status of all servicesKey Concepts
Services
Each container is a service. In the example above: app, db, and cache are three services.
services:
web: # service name (also the hostname inside Docker network)
image: nginxServices can talk to each other using the service name as hostname. Your app can connect to PostgreSQL at db:5432 because the service is named db.
Volumes
Volumes save data permanently. Without a volume, all database data disappears when you stop the container.
services:
db:
image: postgres:16
volumes:
- postgres-data:/var/lib/postgresql/data # named volume
volumes:
postgres-data: # define the volume hereNetworks
Compose automatically creates a network for your project. All services in the same docker-compose.yml can talk to each other by service name. No manual network setup needed.
depends_on
Tells Compose which services to start first:
services:
app:
depends_on:
db:
condition: service_healthy # wait until db is healthyWithout depends_on, Compose starts everything at once — your app might start before the database is ready.
Building From Source
Instead of using a pre-built image, Compose can build your app from a Dockerfile:
services:
app:
build:
context: . # build from current directory
dockerfile: Dockerfile # using this Dockerfile
ports:
- "3000:3000"docker compose up --build # rebuild image and startEnvironment Variables and .env Files
Don't hardcode secrets in docker-compose.yml. Use a .env file:
# .env
POSTGRES_PASSWORD=mysecretpassword
APP_PORT=3000# docker-compose.yml
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # reads from .env
app:
image: myapp:latest
ports:
- "${APP_PORT}:3000"Add .env to .gitignore — never commit secrets.
Useful Commands
# Start all services in background
docker compose up -d
# Start and rebuild images
docker compose up -d --build
# Stop all services (keeps data)
docker compose stop
# Stop and remove containers + networks
docker compose down
# Stop and remove everything including volumes (DELETES DATA)
docker compose down -v
# See logs from all services
docker compose logs -f
# See logs from one service
docker compose logs -f app
# Run a command in a running container
docker compose exec app sh
docker compose exec db psql -U postgres
# See running services
docker compose ps
# Pull latest images
docker compose pullMultiple Environments with Override Files
Use multiple files for different environments:
# docker-compose.yml (base)
services:
app:
image: myapp:latest
# docker-compose.override.yml (local dev — auto-loaded)
services:
app:
build: . # build from source locally
volumes:
- .:/app # mount source code for hot reload
environment:
DEBUG: "true"
# docker-compose.prod.yml (production)
services:
app:
image: myapp:v1.2.3 # specific version in prod
restart: always# Local (uses base + override automatically)
docker compose up
# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml upWhen to Use Docker Compose
Good for:
- Local development environments
- Running all project dependencies with one command
- Integration testing in CI
- Simple single-server deployments
Not for:
- Production at scale (use Kubernetes)
- Running across multiple servers
- Auto-scaling based on load
Docker Compose is your best friend for local development. For production clusters handling real traffic, you'll eventually want Kubernetes — but Compose is where most people start, and it's the right tool for local work.
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
Docker Complete Beginners Guide — Everything You Need to Know
What is Docker, why engineers use it, and how to get started with containers from scratch. A practical, no-fluff guide.
Docker Compose Complete Guide 2026: From Zero to Production
Master Docker Compose in 2026. Learn how to write docker-compose.yml files, manage volumes, networks, environment variables, health checks, and run multi-container apps the right way.
What is a Container Registry? Docker Hub, ECR, GCR Explained (2026)
What is a container registry, why do you need one, and which one should you use? Docker Hub vs ECR vs GCR vs GitHub Container Registry — simply explained.