From b025f12856d9d688d4bc91543dba043194ee5ed6 Mon Sep 17 00:00:00 2001 From: Aleksandr Meshchriakov Date: Thu, 16 Jul 2026 15:42:35 +0200 Subject: [PATCH] fix: serve collected static files with whitenoise --- docker/scripts/start-web.sh | 2 ++ src/settings/base.py | 1 + tests/test_runtime_static.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 tests/test_runtime_static.py diff --git a/docker/scripts/start-web.sh b/docker/scripts/start-web.sh index 5b32530..047d5fa 100755 --- a/docker/scripts/start-web.sh +++ b/docker/scripts/start-web.sh @@ -9,6 +9,8 @@ case "${DJANGO_SETTINGS_MODULE}" in ;; esac +python src/manage.py collectstatic --noinput + exec gunicorn core.wsgi:application \ --bind "0.0.0.0:${PORT:-8000}" \ --workers "${GUNICORN_WORKERS:-3}" \ diff --git a/src/settings/base.py b/src/settings/base.py index 8242dda..c0d9496 100644 --- a/src/settings/base.py +++ b/src/settings/base.py @@ -227,6 +227,7 @@ USE_TZ = True STATIC_URL = "/static/" STATIC_ROOT = PROJECT_ROOT / "staticfiles" STATICFILES_DIRS = [BASE_DIR / "static"] +STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" MEDIA_URL = "/media/" MEDIA_ROOT = PROJECT_ROOT / "media" diff --git a/tests/test_runtime_static.py b/tests/test_runtime_static.py new file mode 100644 index 0000000..eccf7aa --- /dev/null +++ b/tests/test_runtime_static.py @@ -0,0 +1,31 @@ +"""Regression checks for production static-file delivery.""" + +from pathlib import Path + +from django.core.management import call_command +from django.test import Client, override_settings +from settings import base + + +def test_whitenoise_uses_compressed_manifest_storage(): + assert ( + base.STATICFILES_STORAGE + == "whitenoise.storage.CompressedManifestStaticFilesStorage" + ) + + +def test_web_startup_collects_static_files_before_gunicorn(): + script_path = Path(__file__).parents[1] / "docker" / "scripts" / "start-web.sh" + script = script_path.read_text(encoding="utf-8") + + assert "python src/manage.py collectstatic --noinput" in script + assert script.index("collectstatic --noinput") < script.index("exec gunicorn") + + +def test_whitenoise_serves_collected_swagger_asset(tmp_path): + with override_settings(STATIC_ROOT=tmp_path): + call_command("collectstatic", interactive=False, verbosity=0) + response = Client().get("/static/drf-yasg/style.css") + + assert response.status_code == 200 + assert response["Content-Type"].startswith("text/css")