Skip to content

Serve Django Static Files with WhiteNoise

Django does not serve static files (CSS, JavaScript, images) in production by default. WhiteNoise is a lightweight middleware that lets your Django application serve its own static files without relying on a separate web server or CDN.

Step 1: Install WhiteNoise

uv add whitenoise

This adds WhiteNoise to pyproject.toml and uv.lock — commit both, and the build image installs it for you. If your project still uses a requirements.txt, add whitenoise to it instead.

Step 2: Add WhiteNoise to Middleware

In your settings.py, add WhiteNoise to the MIDDLEWARE list immediately after SecurityMiddleware:

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",  # Add this line
    # ... other middleware
]

Note

The placement matters. WhiteNoise must come directly after SecurityMiddleware so it can intercept requests for static files before they reach other middleware.

Step 3: Configure Static Files Settings

# settings.py
import os

STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")

# Optional: enable compression and caching
STORAGES = {
    "default": {
        "BACKEND": "django.core.files.storage.FileSystemStorage",
    },
    "staticfiles": {
        "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
    },
}

Tip

CompressedManifestStaticFilesStorage automatically compresses your static files and adds unique hashes to filenames for cache busting. This provides significant performance improvements.

Note

On Django 4.2 and newer this is configured through the STORAGES dict. The older STATICFILES_STORAGE setting was deprecated in 4.2 and removed in Django 5.1 — on current Django it is ignored silently, so a project still using it falls back to plain, uncompressed static files.

Step 4: Deploy

There is no build command to set. The Python build images detect manage.py and run python manage.py collectstatic --noinput automatically during the build, after installing your dependencies — so your static files are gathered into STATIC_ROOT before the application starts.

Deploy, and WhiteNoise will serve your static files directly from your Django application.

Tip

If you ever need to skip the automatic step — for example when you build static assets some other way — set the DISABLE_COLLECTSTATIC=1 environment variable.

Verifying It Works

After deployment, open your browser's developer tools and check that CSS and JavaScript files load correctly. You should see 200 responses for your static assets.

If static files return 404 errors, verify that:

  1. collectstatic ran successfully during the build (check build logs)
  2. STATIC_ROOT points to the correct directory
  3. WhiteNoise is in the correct position in MIDDLEWARE