ADR-0005 — Containerisation & CI/CD¶
- Status: Accepted
- Date: 2026-06-03
- Author: Maxime GOURGUECHON
- Related: ADR-0001, ADR-0003
Context¶
The deliverable must be reproducible and shippable: a one-command local run, a slim production image, and automated quality gates.
Decision¶
Docker — multi-stage, slim, non-root¶
- Builder stage creates an isolated
/opt/venvand installs runtime dependencies only (requirements.txt) — the heavy DL/dev toolchain (torch, linters) is excluded, keeping the image small. - Runtime stage (
python:3.12-slim) copies the venv, installslibgomp1(required by XGBoost/LightGBM), runs as an unprivilegedappuser, setsBMW_OFFLINE_MODE=truefor deterministic startup, and exposes a Streamlit health-checked service on8501. .dockerignorekeeps the build context lean (no.git, tests, notebooks, caches, model artefacts).
Compose¶
docker-compose.yml provides a single dashboard service with port mapping,
healthcheck and restart: unless-stopped for friction-free local runs.
GitHub Actions — quality then docker¶
qualitymatrix over Python 3.11/3.12:black --check,isort --check,flake8, thenpytestwith coverage. Runs withBMW_OFFLINE_MODE=trueso it never depends on a third-party API (the hybrid clients fall back to mocks).dockerbuilds the image with Buildx + GHA layer cache (no push) to prove the container builds on every change.concurrencycancels superseded runs to save minutes.
Rationale¶
- 3.12 base, not 3.13: broadest wheel availability for the scientific stack in containers; the code itself supports 3.11–3.13.
- Runtime-only image: the dashboard needs neither
torchnor linters, so they stay out of production. - Offline CI: deterministic and fast; live API behaviour is covered by the client design and exercised manually, not in CI.
Consequences¶
- + Reproducible, small, secure-by-default image; green-by-design CI.
- − The DL benchmark is not re-run in CI (heavy); its results are committed
as reports and reproducible locally via
make.