Hook
Need to run several containers (e.g., a web server + database) without a flood of docker run commands? Docker Compose does that for you.
Problem / Context
As a project grows, individual docker run commands become hard to maintain: you must remember ports, volumes, environment variables. Without a central file reproducing the environment on a new machine is error‑prone.
Why it matters
Compose gives you a deterministic and repeatable local environment, lets you spin up a full stack for development, testing and even small production clusters.
How to do it
1. docker-compose.yml
version: "3.9"
services:
web:
image: nginx:stable-alpine
ports:
- "8080:80"
depends_on:
- db
environment:
- DB_HOST=db
db:
image: postgres:15-alpine
volumes:
- db-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
db-data:
2. .env
POSTGRES_USER=app
POSTGRES_PASSWORD=secret
POSTGRES_DB=appdb
3. Starting the stack
docker compose up -d # bring everything up in background
docker compose ps # check status
4. Logs and debugging
docker compose logs -f web # follow Nginx output
5. Cleaning up
docker compose down --volumes # stop and remove volumes
Anti‑patterns
- Using the
latesttag – unpredictable in production. - Hard‑coded passwords in
docker-compose.yml– store them in.envor a secret manager. - Missing
depends_on– services may start in the wrong order. - Leaving volumes attached – can pollute test results; always clean them up.
Conclusion / Action plan
- Write
docker-compose.ymland a matching.envfile. - Run
docker compose up -dand verify the web service responds. - Add monitoring (Grafana + Prometheus) for production use.
- Move all secrets to a secure store.
- Clean up volumes after testing to keep the environment tidy.