Files
photoanalyzer/delivery_backlog/stories/US08-02-container-image.md

1.9 KiB

US08-02 — Build a Reproducible Application Image

Epic: E08

As an operator, I want one image that can run either application role, so deployment is a pull instead of a Python environment I have to reproduce by hand.

Context

The application shells out to exiftool and immich-go, writes into the library as a normal filesystem user, and serves a static frontend from frontend/. All three have to be true inside the image, or the container starts and then fails on the first real operation.

Acceptance criteria

  • A Dockerfile builds from a pinned Python base, installs the project and its runtime dependencies, and contains no test, playwright, or build-only tooling in the final layer.
  • exiftool and immich-go are present at pinned versions, and their versions are recorded in the image and reported by python -m photo_pipeline diagnostics.
  • The image runs as a non-root user whose UID/GID are build-time arguments, so files the application renames or writes keep the ownership the host library expects.
  • One entrypoint selects the role: serve or worker, passing through the existing CLI arguments; no supervisor runs two roles in one container.
  • serve containers declare a HEALTHCHECK against /api/v1/health/ready, so an unmigrated or misconfigured database is not reported healthy.
  • The image contains no secrets, no library data, no database, and no .git; the build context is constrained by .dockerignore.
  • Image build is reproducible from a clean checkout and documented in README.md.

Automated tests

  • A build-and-run test asserts the image starts, reports ready, serves the frontend index, and returns the pinned exiftool and immich-go versions.
  • A test asserts the container refuses to run as UID 0 and that a file created by the container is owned by the configured UID/GID.

Dependencies

  • US07-05