Fix the image build: fetch the git dependency in its own stage

The build died at `uv sync`: django-lucide is our fork, declared as a git source
and pinned by the lock to a commit, so uv shells out to `git` to fetch it — and
python:3.14-slim has no git.

Installing git in the runtime image would have fixed it and left a build tool, plus
its dependency tree, in production for the sake of one package that is already
vendored into the venv by then. So the virtualenv is now built in a stage that has
git, and the finished .venv is copied into a runtime stage that does not. Same base
image, so the compiled wheels inside it stay ABI compatible.

Also drops the second `uv sync`, which installed the project itself: there is no
[build-system] and rosterchief is not a package — gunicorn imports it from the
working directory, exactly as it does locally.

Unverified end to end: still no container runtime on this machine.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 18:07:54 +02:00
parent 534d01d6fe
commit 5d42691a10
2 changed files with 44 additions and 11 deletions

View File

@@ -67,6 +67,22 @@ docker compose run --rm web python manage.py check --deploy
**off** in code, because defaulting them to `not DEBUG` would redirect every test request to
https and break the suite anywhere `DEBUG` is unset.
### One dependency comes from git
`django-lucide` is our fork (`[tool.uv.sources]` in `pyproject.toml`, pinned by `uv.lock` to a
commit), so **uv shells out to `git`** to fetch it. `python:*-slim` has no git, which is why
the image builds the virtualenv in a **separate stage** that installs git, and copies the
finished `.venv` into a runtime stage that does not have it — a build tool has no business in
a production image.
Two consequences worth knowing:
- The build needs **network access to GitHub**, and the fork must stay reachable. If that ever
becomes awkward (a private runner, an air-gapped build), publish the fork to a private index
or vendor the wheel, and the git stage disappears.
- `uv.lock` pins the exact commit, so the build is reproducible even though the source is a
branch. Don't build with `--no-frozen`.
The first `docker compose up` will take a minute or two: Caddy is provisioning the wildcard
certificate over DNS-01, and DNS propagation is not instant. Watch it with
`docker compose logs -f caddy`.