e5a93194bf543cb8077dfdfd986e7f3b626c9ff3
Three things would have broken a deploy, all invisible until it happened: - psycopg was missing. dj-database-url parses postgres:// happily, so the app would have started and died on its first query. - No CACHES, so Django used LocMemCache -- private to one process. waffle caches each flag's targeting there, so under several gunicorn workers a toggle flipped in the control panel flushes ONE worker and the others keep serving the stale flag. That is a feature that "sometimes doesn't turn on", and it makes Redis a requirement of the first multi-worker deploy, not of the second server. - Uploads (club logos) sat on local disk. Fine on one box; on two, a logo uploaded to node A 404s on node B. Storage now switches to S3 the moment a bucket is configured, so adding a server stays a config change. HTTPS behind a proxy: SECURE_PROXY_SSL_HEADER is not optional once Caddy terminates TLS -- without it Django thinks every request is plain HTTP, request.is_secure() is false, WebAuthn disagrees with the browser about the origin, and SECURE_SSL_REDIRECT turns into a loop. HSTS covers subdomains, because every club is one. The SSL/cookie flags default to off and are switched on by the production environment on purpose: defaulting them to `not DEBUG` would redirect every test request to https and break the suite wherever DEBUG is unset. `check --deploy` is what catches a deploy that forgot them. Static files are served by WhiteNoise from the app itself, so a second app server needs no shared volume or CDN. Manifest storage is production-only: it demands a collectstatic manifest that no test run has. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Description
No description provided
Languages
Python
59.1%
HTML
28.3%
CSS
8%
JavaScript
4.2%
Shell
0.2%
Other
0.2%