Docker

Lesson 10

Compose services, volumes, and networks

Use Compose to define service boundaries, persistent volumes, and internal networks without overexposing ports or state.

Good Code

compose.yaml
services:
  app:
    build: .
    environment:
      DATABASE_HOST: db
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "3000:3000"
    networks:
      - internal

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: reviews
      POSTGRES_USER: reviews
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U reviews"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - internal

volumes:
  postgres_data:

networks:
  internal:

Bad Code

compose.yaml
services:
  app:
    build: .
    network_mode: host
    volumes:
      - .:/app
      - /:/host

  db:
    image: postgres:latest
    ports:
      - "5432:5432"

Review Notes

What to review

Good Code

The good version names persistence, keeps services on an internal network, and exposes only the application port needed by the host.

Bad Code

The bad version uses host networking, mounts the host filesystem, and exposes the database without a clear reason.

Takeaways

  • A Compose file should make service relationships explicit while keeping persistence and exposure deliberate.