Create the production deployment and packaging story #50
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
The app currently runs from a development checkout: a venv,
uvicorn --reload, and a Vitedev server. There is no deployment story, which means there is no supported way to
actually run Circa for its intended purpose over the years a family collection takes to work through.
Scope
A reproducible deployment: containerization, production configuration, and an upgrade path.
Implementation notes
The worker is a separate process from the API and must be deployed as such.
implicit migration on boot makes rollback and multi-process startup hazardous.
implications for both.
10.1.1.14, which already runs Docker.Done when
References
README.md(development-only instructions today)AGENTS.md(dev server at10.1.1.14, Docker available)Depends on: #14 (fail fast on insecure configuration).
Substantially done across two repos. Leaving this open on the last box, which is the one that needs a real run.
This repo (
8239ae9,c45d4a7, released as v0.3.1): a backend image and a frontend image, and apublishjob that pushes both on a version tag. The deployment itself lives inRhoving/iac-repo#262 / PR #263 — acirca-ansibleproject on that repo's role pattern, deploying dev todocker-testand production todocker-hostfrom the same pinned tag.Against the "Done when" list
down -vcannot take the two things worth keeping, and a future backup job can reach them without going through Docker.Verified rather than assumed
tesseract --version→ 5.5.0 inside the backend image, and the full OCR chain across two containers: ingest a front/back pair, worker claims the job, evidence row lands. Without it every job #144 queues fails permanently, per photograph, silently.alembic upgrade headfrom an empty volume →000 → 017, and the API started on a fresh volume without migrating, confirming migrations really are not implicit./api/health→ 200 with only the backend's headers, SPA fallback servesindex.html,/api/nopereturns the backend's JSON 404 rather than being swallowed, and a query string arrives byte-for-byte.client_max_body_size 220m. The nginx default is 1 MB and a 4×6 print at 400dpi is about 2.8 — the browser upload path (#142) this deploy exists for would have refused every scan.proxy_passcaches the address for the life of the process, so every upgrade would otherwise leave the frontend 502ing until someone restarted it too.0.3.1, with:latestmoved.Two things this turned up
A green run that built nothing. The first v0.3.1 tag run passed every gate and published no image — the runner skipped
publishon anif:expression that works in shelf-life but not under this workflow's filtered triggers. Fixed by deciding in the shell against$GITHUB_REFand printing all three ref variables unconditionally (c45d4a7). Recorded because "CI is green" was, for about an hour, a true statement about nothing.#145 — EXIF extraction fails on every TIFF, found while building the backend image and confirmed on the host, so not container-induced. Worth fixing before a real collection goes in rather than after: EXIF is read at ingest, so anything imported before the fix carries no
exifevidence, and re-deriving means re-reading every original.