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

Conclusion / Action plan

  1. Write docker-compose.yml and a matching .env file.
  2. Run docker compose up -d and verify the web service responds.
  3. Add monitoring (Grafana + Prometheus) for production use.
  4. Move all secrets to a secure store.
  5. Clean up volumes after testing to keep the environment tidy.