Running 10
docker run commands manually with complex flags is tedious and error-prone. Docker Compose allows you to define and run your entire multi-container infrastructure declaratively in a single YAML file.TL;DR (Quick Summary)#
- Docker Compose: CLI tool (
docker compose) for defining multi-container environments. - Service Dependencies: Use
depends_onwithcondition: service_healthyto force startup order (e.g., waiting for Postgres to accept connections before starting Node.js). - Environment Files: Use
.envfiles to store variables locally without committing secrets to Git.
1. Multi-Container Stack Architecture#
graph TD
subgraph Docker Compose Stack (app-network)
NginxProxy["Nginx Reverse Proxy :80"] -->|Proxy Pass| WebApp["Node.js API Service :3000"]
WebApp -->|DB Connection| Postgres["Postgres DB :5432"]
WebApp -->|Cache Connection| Redis["Redis Cache :6379"]
Postgres --- Volume["('Named Volume: db-data')"]
end
2. Step-by-Step Lab: Building a Production Multi-Service Stack#
Let’s write a complete docker-compose.yaml file featuring a Node API, Postgres database, and Redis cache.
The docker-compose.yaml File#
Create docker-compose.yaml:
version: '3.8'
services:
api:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- DB_HOST=postgres
- DB_PASS=${DB_PASSWORD}
- REDIS_HOST=redis
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
networks:
- app-net
restart: always
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: app_user
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: app_db
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app_user -d app_db"]
interval: 5s
timeout: 5s
retries: 5
networks:
- app-net
redis:
image: redis:7-alpine
networks:
- app-net
networks:
app-net:
driver: bridge
volumes:
db-data:The .env File#
Create .env:
DB_PASSWORD=SuperSecretPass123!3. Essential Docker Compose CLI Commands#
# 1. Start all containers in background mode
docker compose up -d
# 2. View combined logs from all services in real time
docker compose logs -f
# 3. Check health status of all running services
docker compose ps
# 4. Stop and remove all containers, networks, and volumes
docker compose down -v4. Troubleshooting & Common Errors#
Error 1: API Crashes with ECONNREFUSED on Database Boot#
The Cause: depends_on without healthchecks only waits for the database container to start, NOT for PostgreSQL to be ready to accept TCP connections!
The Fix: Always add a healthcheck block to the database service and set condition: service_healthy on the dependent app service.
Summary & Next Steps#
In this episode:
- We orchestrated multi-container architectures using
docker-compose.yaml. - We configured strict startup dependencies using healthchecks.
- We passed secrets safely via
.envfiles.
Congratulations! You have completed the Docker Deep Series!
Next, we move to Module 4: Go (Golang) Deep Series (TotalTypeScript / Matt Pocock Depth)!

