Skip to content

Monorepo Compose Layering

This document defines the Docker Compose conventions used across the monorepo.

Goals

  • Keep one canonical definition per service.
  • Separate base service definitions from environment-specific behavior.
  • Make local development, devcontainer startup, and CI stacks composable from the same files.

File Roles

  • infra/docker/compose/compose.yaml
    • Base shell only.
    • Declares shared project-level settings like compose project name and shared networks.
  • infra/docker/compose/services/*.yaml
    • Canonical service fragments.
    • One file per service where practical (for example api.yaml, postgres.yaml, redis.yaml, docs.yaml).
    • Should contain stable defaults for that service.
  • infra/docker/compose/compose.dev.yaml
    • Local development overlay.
    • Contains development-only behavior such as bind mounts, local command overrides, and local environment wiring.

Layering Order

Always layer compose files in this order:

  1. Base shell (compose.yaml)
  2. Service fragments (services/*.yaml)
  3. Environment overlay (compose.dev.yaml, or other overlays)

Example local stack:

docker compose \
    -f infra/docker/compose/compose.yaml \
    -f infra/docker/compose/services/api.yaml \
    -f infra/docker/compose/services/postgres.yaml \
    -f infra/docker/compose/services/redis.yaml \
    -f infra/docker/compose/compose.dev.yaml \
    up --build

Conventions

  • Do not duplicate a service definition across multiple files.
  • Put environment-specific overrides in overlays instead of creating duplicated service variants.
  • If compose.dev.yaml adds depends_on or environment variables that reference dependencies, include the matching service fragments in the compose invocation.
  • Keep service fragments reusable by devcontainer, CLI workflows, and CI workflows.

Devcontainer Alignment

Project devcontainers should follow the same layering model and include only the fragments they require.

For apps/api, the stack includes:

  • compose.yaml
  • services/api.yaml
  • services/docs.yaml
  • services/postgres.yaml
  • services/redis.yaml
  • compose.dev.yaml

Validation

Validate merged compose files before committing:

docker compose <compose file list> config --quiet

The repository helper target also validates common combinations:

make -f tools/docker/Makefile validate-compose