/healthz checks the database and does a cache ROUND TRIP, not a ping. Both matter:
a node that cannot reach Postgres serves nothing, and a cache that accepts writes
and returns nothing would have waffle read every feature flag as unset -- so
"healthy" has to mean more than "the process is listening", or the load balancer
will keep feeding traffic to a node that only looks alive.
No auth and no tenant on it: the proxy, and later a load balancer, must reach it on
any host.
DEPLOYMENT.md is the runbook, and leads with the five things that make this app not
a generic Django deploy: the wildcard cert forces DNS-01 (Let's Encrypt will not
issue a wildcard over HTTP-01); Redis is required on one server, not two, because
of the per-process flag cache; SECURE_PROXY_SSL_HEADER plus Caddy's
X-Forwarded-Proto or WebAuthn and the SSL redirect both break; uploads must reach
object storage BEFORE the second app server, not during; and invoices need native
pango.
Also documents why the archive job ships with --commit off, why migrations are run
explicitly rather than from the entrypoint, and how to test the restore before the
day you need it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>