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:
- Base shell (
compose.yaml) - Service fragments (
services/*.yaml) - 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.yamladdsdepends_onor 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.yamlservices/api.yamlservices/docs.yamlservices/postgres.yamlservices/redis.yamlcompose.dev.yaml
Validation¶
Validate merged compose files before committing:
The repository helper target also validates common combinations: