So a deploy never needs a manual `alembic upgrade head`:
- Backend image gains an entrypoint that runs `alembic upgrade head` before
uvicorn when RUN_MIGRATIONS=1 (set on the backend service). This self-migrates
even on a Watchtower in-place image swap, which doesn't re-run one-shot jobs.
- A one-shot `migrate` service covers the `docker compose up` path; backend and
worker depend on it completing, which also serializes it with the backend
entrypoint so alembic never runs concurrently. `upgrade head` is idempotent.
Activating this needs the updated compose on the host once (Watchtower only
swaps images, not the compose file / env). After that, migrations are automatic.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>