Deployment: pages and fragments leave the container uncompressed, and the documentation does not say the proxy should compress them #1152
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#1152
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What exists today
config/settings/base.py:94-132lists the middleware: WhiteNoise compresses static files at build time (gzip and Brotli, see A3), but nothing compresses what views return;django.middleware.gzip.GZipMiddlewareis absent. The image runs gunicorn bound to port 8000 (docker/Dockerfile:388-393), which does not compress either. So whether pages travel compressed depends entirely on the operator's proxy.The documentation does not raise it.
postulo.wiki/Installing-Postulo.md:267-270says "Postulo serves its own static files through WhiteNoise, so the proxy only needs to pass requests through";postulo.wiki/Hardening.md:46-50("Add at the proxy what an application cannot do for itself") lists rate limits and file headers but not compression. Proxies differ: Caddy compresses only with anencodedirective, and nginx only withgzip on(Debian's packaged configuration sets it, and then compressestext/htmlalone, not htmx's JSON or the API's), so an operator following the pages as written will often serve uncompressed HTML.Pages are large because of the server-rendered design (the unpaginated board in A5 is the extreme), and every signed-in page is
Cache-Control: no-store(core/middleware.py:395-419, deliberate, #787), so each view is a full transfer.What would change
Recommended: documentation only. A short section in
Hardening.md(orInstalling-Postulo.mdstep 6) saying that Postulo does not compress pages itself and that the proxy should, with the one line for Caddy (encode zstd gzip) and for nginx (gzip on; gzip_types text/html application/json ...;), and a sentence pointing at whatever the user decides about responses that carry secrets.The alternative is Django's own
GZipMiddleware(no extra library), which would compress for operators without a capable proxy. Its documentation carries a warning about BREACH; whether that applies to Postulo's pages is a security question and is left to the user, not assessed here.What it saves or protects
medium: HTML is repetitive and compresses roughly tenfold (30 board cards' status menus: 165 kB raw, 2 kB gzip; see A5); the saving is per page view and per htmx swap, since signed-in pages are
no-storeAccessibility
none
Decided by the maintainer (2026-10-31)
document compression at the reverse proxy (Hardening, Installing); no middleware
Decisions
GZipMiddleware? Recommended: document it at the proxy; it keeps the application's behaviour unchanged and leaves the security trade-off where the operator can see it. The user decides; the security side was not assessed.Found by the efficiency and reliability audit of 2026-10-30 (finding A6; index postulo/postulo#1108). Checked against
mainatdaee30b15(2026-10-30).