US08-03 — Compose the Runtime and Mount the Library Safely #89

Open
opened 2026-08-17 21:11:35 +02:00 by domverse · 1 comment
Owner

Source specification: delivery_backlog/stories/US08-03-compose-runtime.md

US08-03 — Compose the Runtime and Mount the Library Safely

Epic: E08

As an operator, I want a single compose file that runs the API and the worker against my
real library, so a deployment is one command and the safety invariants survive it.

Context

The library process lock (US07-05) assumes both roles see the same lock file, and SQLite
in WAL mode assumes a real local filesystem. Container path policy is the same problem
as host path policy with a new failure mode: the configured library roots must name the
in-container mount paths, not the host paths.

Acceptance criteria

  • docker-compose.yml runs exactly one serve and one worker container from the same
    image and the same data volume, and a second worker is refused by the existing lock
    rather than by convention.
  • The library is a bind mount; PHOTO_PIPELINE_LIBRARY_ROOTS names the container-side
    paths, and a mismatch between mounted and configured roots fails at startup with a
    clear message instead of at the first write.
  • The data volume holds the database, WAL, thumbnail cache, and backups on a local
    filesystem; the composition documents that a network mount is unsupported for it.
  • Migrations run before serve and worker accept work, using the existing backup-then-
    migrate path, and an upgrade that fails leaves the previous database intact.
  • Configuration and secrets come from the environment, never from the image or a
    committed file; a .env.example lists every PHOTO_PIPELINE_* variable with safe
    defaults and no values.
  • The API port is published to host loopback by default; exposing it publicly requires
    the configured hostname and access secret from US08-01.
  • Containers restart automatically, and a restart mid-job resumes exactly as a host
    restart does today.
  • Backup, verify-backup, restore, and diagnostics are documented as container commands
    and work against the mounted volumes.

Automated tests

  • An integration test brings the composition up against a temporary fixture library,
    runs a job, restarts both containers, and asserts the job resumes and the database is
    intact.
  • Tests for: second worker refused, library-root mismatch refused at startup, failed
    migration leaving the previous database restorable.

Dependencies

  • US08-01, US08-02
Source specification: [delivery_backlog/stories/US08-03-compose-runtime.md](https://git.domverse-berlin.eu/domverse/photoanalyzer/src/branch/main/delivery_backlog/stories/US08-03-compose-runtime.md) # US08-03 — Compose the Runtime and Mount the Library Safely Epic: [E08](https://git.domverse-berlin.eu/domverse/photoanalyzer/src/branch/main/delivery_backlog/E08-container-deployment.md) As an operator, I want a single compose file that runs the API and the worker against my real library, so a deployment is one command and the safety invariants survive it. ## Context The library process lock (US07-05) assumes both roles see the same lock file, and SQLite in WAL mode assumes a real local filesystem. Container path policy is the same problem as host path policy with a new failure mode: the configured library roots must name the in-container mount paths, not the host paths. ## Acceptance criteria - `docker-compose.yml` runs exactly one `serve` and one `worker` container from the same image and the same data volume, and a second worker is refused by the existing lock rather than by convention. - The library is a bind mount; `PHOTO_PIPELINE_LIBRARY_ROOTS` names the container-side paths, and a mismatch between mounted and configured roots fails at startup with a clear message instead of at the first write. - The data volume holds the database, WAL, thumbnail cache, and backups on a local filesystem; the composition documents that a network mount is unsupported for it. - Migrations run before `serve` and `worker` accept work, using the existing backup-then- migrate path, and an upgrade that fails leaves the previous database intact. - Configuration and secrets come from the environment, never from the image or a committed file; a `.env.example` lists every `PHOTO_PIPELINE_*` variable with safe defaults and no values. - The API port is published to host loopback by default; exposing it publicly requires the configured hostname and access secret from US08-01. - Containers restart automatically, and a restart mid-job resumes exactly as a host restart does today. - Backup, verify-backup, restore, and diagnostics are documented as container commands and work against the mounted volumes. ## Automated tests - An integration test brings the composition up against a temporary fixture library, runs a job, restarts both containers, and asserts the job resumes and the database is intact. - Tests for: second worker refused, library-root mismatch refused at startup, failed migration leaving the previous database restorable. ## Dependencies - US08-01, US08-02
domverse added a new dependency 2026-08-17 21:12:19 +02:00
domverse added a new dependency 2026-08-17 21:12:20 +02:00
domverse added a new dependency 2026-08-17 21:12:20 +02:00
domverse added this to the Photo Analyzer Delivery project 2026-08-17 21:16:01 +02:00
domverse added this to the E08 — Container Deployment milestone 2026-08-17 21:17:42 +02:00
domverse added status/in-progress and removed status/backlog labels 2026-08-18 23:31:01 +02:00
domverse self-assigned this 2026-08-18 23:31:02 +02:00
Author
Owner

Claimed for implementation on branch us/US08-03-compose-the-runtime-and-mount-the-library-safely.

Claimed for implementation on branch `us/US08-03-compose-the-runtime-and-mount-the-library-safely`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: domverse/photoanalyzer#89