Thermograph monorepo: graded-climate API + SSR frontend + infra, domain-specific containerized deploys
Two changes to deploy/entrypoint.sh, both needed before the app can run under Docker Swarm without re-triggering known incidents: One-shot migrate mode: `entrypoint.sh migrate` (or THERMOGRAPH_MIGRATE_ONLY=1) runs the Alembic migration and exits, for a Swarm one-shot task that brings the schema to head once rather than racing it across every web replica's boot. RUN_MIGRATIONS=0 skips the inline migrate for a deploy that runs the one-shot task separately. Default (unset) keeps today's behavior unchanged: every boot migrates itself before serving. Secrets shim: the app reads config from os.environ everywhere (an unset THERMOGRAPH_AUTH_SECRET falls back to a random per-process value; an unset VAPID key pair is freshly minted) - Swarm `secrets:` mount each secret as a FILE under /run/secrets/ instead, which the app would never see. Before alembic/uvicorn, mechanically export each /run/secrets/<name> whose uppercased name is a THERMOGRAPH_* var, unless already set in the process env; THERMOGRAPH_DATABASE_URL is built from a postgres_password secret the same way compose's own interpolation builds it today. Verified against fake alembic/uvicorn binaries in a throwaway container: default boot, migrate-only mode (both trigger forms), RUN_MIGRATIONS=0, secrets populating unset vars, an existing env var beating its secret file, and no /run/secrets present at all (today's plain compose path, unaffected). shellcheck clean. |
||
|---|---|---|
| accounts | ||
| alembic | ||
| core | ||
| data | ||
| deploy | ||
| notifications | ||
| templates | ||
| tests | ||
| web | ||
| alembic.ini | ||
| app.py | ||
| cities.json | ||
| cities_flavor.json | ||
| gen_cities.py | ||
| gen_flavor.py | ||
| indexnow.py | ||
| migrate.py | ||
| migrate_accounts_to_pg.py | ||
| migrate_cache_to_pg.py | ||
| paths.py | ||
| requirements-dev.txt | ||
| requirements.txt | ||
| warm_cities.py | ||