Worker crash-loop root cause (from container log):
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres
Two compounding issues:
1. Dockerfile copied pyproject.toml/uv.lock, ran 'uv sync --frozen',
then 'COPY backend ./backend' which OVERWROTE those dep files with the
shipped versions. The two could differ, so every entrypoint 'uv run'
detected drift and REBUILT/re-synced the project at container runtime
(seen as repeated 'Building crowdsight-backend...' + 'Uninstalled N /
Installed 1'), never installing the psycopg Postgres driver that the
image's own lock actually lists.
2. Result: alembic upgrade head over a postgres DATABASE_URL crashed with
NoSuchModuleError -> worker crash-loop.
Fix:
- Dockerfile: COPY backend (full source) BEFORE 'uv sync --frozen --no-dev',
so the installed deps match the shipped pyproject.toml/uv.lock exactly.
- Use 'uv run --frozen' for alembic/gunicorn/worker so nothing re-syncs at
runtime.
- entrypoint: fail fast with a clear message if DATABASE_URL is postgres
but psycopg is missing (instead of a confusing alembic traceback).
Verified: entrypoint bash syntax ok; 'uv run --frozen ... import psycopg'
passes; psycopg present in git-tracked uv.lock + pyproject.