Stage 4 · Provision
Docker Compose
Compose File Basics
Define services, images, builds, ports, volumes, networks, and environment in compose.yaml.
What Is Docker Compose?
Docker Compose is a tool for defining and running multi-container applications. Instead of long docker run commands with many flags, you declare your entire application stack in a YAML file. Compose reads the file, creates networks, volumes, and containers with a single command.
Compose File Structure
services:
web:
image: nginx:alpine
ports:
- "8080:80"The top-level key is services. Each service defines a container. The image key specifies which image to use. Ports maps host ports to container ports.
Services
A service is a configuration for running a container. It specifies the image, environment, ports, volumes, networks, and other options. Compose creates one container per service by default. Scale with --scale or deploy.replicas.
services:
api:
image: node:20-alpine
working_dir: /app
command: node server.js
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://db:5432/app
ports:
- "3000:3000"
volumes:
- ./src:/app
networks:
- backend
depends_on:
- dbThis service defines the image, working directory, command, environment variables, ports, volumes, networks, and dependencies. Each key maps directly to a docker run option.
Build Configuration
Instead of using a pre-built image, you can build from a Dockerfile using the build key. Compose builds the image before starting the container. This is essential for development workflows.
services:
api:
build:
context: .
dockerfile: Dockerfile.dev
args:
NODE_ENV: development
target: development
ports:
- "3000:3000"
# Shorthand for simple builds
worker:
build: ./workerThe build context is the directory sent to the Docker daemon. dockerfile specifies which Dockerfile to use. args pass build arguments. target selects a multi-stage build target.
When you change your Dockerfile or source code, use docker compose up --build to rebuild images before starting containers. Without --build, Compose uses cached images.
Ports and Volumes
services:
web:
image: nginx:alpine
ports:
- "8080:80" # host:container
- "127.0.0.1:8443:443" # localhost only
volumes:
- ./html:/usr/share/nginx/html # bind mount
- static-files:/var/www/static # named volume
volumes:
static-files:Ports follow the same format as docker run -p. Volumes can be bind mounts (relative or absolute paths) or named volumes (declared in the top-level volumes section).
Networks
services:
api:
image: myapp
networks:
- frontend
- backend
db:
image: postgres:16-alpine
networks:
- backend
networks:
frontend:
backend:
driver: bridgeServices on the same network can reach each other by service name. The frontend network is accessible to the api service. The backend network connects api and db. Isolation between networks prevents unnecessary communication.
By default, Compose creates a network named <project>_default. All services connect to it. You can define custom networks for isolation — for example, separating frontend from backend services.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.