Repository navigation
Conversation
Register the compressor app and its static-file finder. Compression stays off whenever DEBUG is on (development and tests). In production it runs offline and writes bundles and the manifest (CACHE/manifest.json) to the Spaces bucket. Set COMPRESS_ROOT explicitly because production has no STATIC_ROOT. Also pin the offline manifest storage name, since django-compressor 4.6 defaults to the misspelled "compressor-offine".
Wrap each template's local stylesheet and script tags in {% compress %} blocks so production serves minified bundles with content-hashed filenames, which also busts the browser cache on each deploy.
- base.html: bundle base.css, izaya/layout.css and izaya.css into one stylesheet, and compress izaya.js (it keeps its defer attribute)
- Bundle page-level assets on home, timeline, statistics, the issue and attribution forms, and the collection form, detail and stats pages
- Load issue-form-usability.js next to bulma-calendar so the two share a bundle; it doesn't depend on the inline form script
- collection_stats: bundle Chart.js, the inline dark-mode script and chartkick in their original order
{% bulma %}, {% font_awesome %}, CDN scripts and inline scripts that use template variables stay outside the compress blocks.
Production compresses offline. If compress hasn't been run for the current templates, pages fail with OfflineGenerationError, so run it on every deploy. - Fresh install: run compress after collectstatic, then restart metron-web, because each gunicorn worker caches the manifest in memory - Updates: run compress from the newly built image in a one-off container before restarting, so workers never start against a stale manifest; collectstatic moves to the same one-off form - Mention the harmless django-filters crispy_form.html warning
- Set COMPRESS_URL to an absolute https:// URL. S3Boto3Storage emits https:// asset URLs, so the scheme-less STATIC_URL made offline compress reject every file. - Give each release its own offline manifest (CACHE/manifest-<METRON_RELEASE>.json). The value comes from a new Containerfile build arg, so running compress during a deploy no longer changes the manifest that running containers read, and rollbacks find their manifest still in place. Update DEPLOYMENT.md to pass the arg. - Wrap the bulma-calendar tags in issue_filter.html in compress blocks. - Put Chart.js, chartkick and bulma-calendar in their own compress blocks so each library keeps one URL across pages and the browser can reuse its cached copy. - Tests: assert on the actual Bulma stylesheet link, and give compressor an isolated in-memory cache instead of the shared Redis cache.
bpepple
marked this pull request as draft
November 5, 2026 16:24
Add an "Upgrading PostgreSQL" section to DEPLOYMENT.md covering routine minor updates and a 16 -> 18 dump/restore procedure. The major upgrade steps cover two things that a plain restore gets wrong: - The postgres:18 image moved PGDATA to /var/lib/postgresql/18/docker, so the volume must be mounted at /var/lib/postgresql. - pg_dump doesn't save the ALTER FUNCTION unaccent(text) IMMUTABLE change from migration 0050, because unaccent(text) belongs to an extension. Without redoing it before the restore, the *_name_unaccent_trgm_idx indexes fail to build and pg_restore keeps going anyway.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds django-compressor so production serves local CSS and JS as minified bundles with content-hashed filenames. Pages make fewer requests, and every deploy changes the filenames, so browsers fetch new assets instead of using cached copies from Spaces (cached for 7 days).
Development and tests are unchanged: compression is off whenever
DEBUGis on, so templates load the original files.Changes
django-compressor4.6.0compressorapp andCompressorFinderCACHE/manifest.jsonto the Spaces bucketCOMPRESS_ROOTexplicitly because production has noSTATIC_ROOT"compressor-offine"; this is fixed upstream in #1325 but not released yet.base.htmlbundlesbase.css,izaya/layout.cssandizaya.cssinto one stylesheet;izaya.jskeepsdefer{% bulma %},{% font_awesome %}, CDN scripts and inline scripts that use template variables stay outside the bundlesissue-form-usability.jsnow loads next to bulma-calendar so the two share a bundle (it doesn't depend on the inline form script)tests/metron/test_compress.pychecks that the home page uses bundles when compression is on and the original files when it's offDEPLOYMENT.mdadds thecompressstepDeployment
manage.py compress --forcemust run on every deploy. In production, any page whose{% compress %}block isn't in the manifest fails withOfflineGenerationError, and that includes the first deploy before any manifest exists.Run it from the new image before restarting:
Each gunicorn worker caches the manifest in memory, so restart after compressing. The "Invalid template django_filters/rest_framework/crispy_form.html" warning that
compressprints is harmless.Testing
pytest: 2240 passed, 2 skippedruff checkandruff format --checkpasscompress --forcebuilt 10 bundles from 156 templates with no errorsstatic/CACHE/manifest.jsonexists in the Spaces bucket