Suggestion
Every project currently ships a hand-copied 4-stage Dockerfile (base / builder / dev / prod):
- 17x
projects/*/Dockerfile (api_public, website, workers, jobs, scrapers, firehose, ...)
- 1x root
Dockerfile (project_debugger only)
- 2x
_infra seeders (different pattern, python:3.11)
The per-project copies have already drifted:
| drift |
example |
| uv version |
root Dockerfile pinned 0.5.4, everything else 0.5.13 (fixed) |
| python base |
projects on 3.12, infra seeders on 3.11 |
| prod hardening |
projects/firehose prod stage runs as non-root appuser; most other prod stages run as root |
| typo |
root Dockerfile had COPY --from=... /uv uvx/ /bin/ (trailing slash = directory) |
Every future fix (bump uv, add non-root user, new build stage) must be hand-applied 17 times.
Options
- Keep 17 copies — maximum isolation, projects stay self-contained; cost is ongoing drift (already happened).
- One parametrized Dockerfile — single file using
ARG PROJECT_NAME, compose/CI pass --build-arg; single source of truth, less copy-paste; cost is a less "standard" layout and one file touching all deploys.
- Template/generator — a script (or
cookiecutter-style template) that (re)generates per-project Dockerfiles; keeps per-project files (readable, standalone) while enforcing consistency.
Questions
- Do we value standalone per-project Dockerfiles enough to keep duplicating?
- If consolidating: option 2 or 3?
- Should the infra seeders (python:3.11) move to 3.12 to match projects?
Suggestion
Every project currently ships a hand-copied 4-stage Dockerfile (base / builder / dev / prod):
projects/*/Dockerfile(api_public, website, workers, jobs, scrapers, firehose, ...)Dockerfile(project_debugger only)_infraseeders (different pattern, python:3.11)The per-project copies have already drifted:
0.5.4, everything else0.5.13(fixed)3.12, infra seeders on3.11projects/firehoseprod stage runs as non-rootappuser; most other prod stages run as rootCOPY --from=... /uv uvx/ /bin/(trailing slash = directory)Every future fix (bump uv, add non-root user, new build stage) must be hand-applied 17 times.
Options
ARG PROJECT_NAME, compose/CI pass--build-arg; single source of truth, less copy-paste; cost is a less "standard" layout and one file touching all deploys.cookiecutter-style template) that (re)generates per-project Dockerfiles; keeps per-project files (readable, standalone) while enforcing consistency.Questions