Django caching issue when deployed to the DigitalOcean App Platform

I followed the How To Deploy a Django App on App Platform guide from DigitalOcean and successfully created a Django server which I'm using through /admin pages.

Through the App Platform, I use GitHub to push changes to production. I'm having an issue with CSS and JS files that don't update after I push changes: I've tried hard refreshing my browser, using a different browser, deleting browser caches, and nothing seems to work, the files don't update. Using the Console, I can see that the files are updated on the server (including under staticfiles), but they don't update in the browser.

I read up on the STORAGES setting and the ManifestStaticFilesStorage class, so I tried adding the following setting as a means of cache busting:

STORAGES = {
    'staticfiles': {
        'BACKEND': 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage',
    },
    'default': {
        'BACKEND': 'django.core.files.storage.FileSystemStorage',
    },
}

When I deploy this to production, everything seems to crash except the page I'm currently on (with the JS/CSS I've been testing). I tried deploying with DEBUG=True, but this affects the execution of the static tag by changing whether Django looks for files with their regular or hashed name, so it doesn't reproduce the errors.

I'm stumped, how do I even debug this?

My Django settings file has:

# settings.py
STATIC_URL = 'static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'

On App Platform, I have an attached static resource component with a single HTTP Request Route of /static and an Output Directory of staticfiles.

  1. First, install WhiteNoise:
pip install whitenoise
  1. Add WhiteNoise to your middleware in settings.py. Make sure it's added after the security middleware and before all other middleware:
MIDDLEWARE = [
    # ...
    "django.middleware.security.SecurityMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",  # Add this line
    # ...
]
  1. Configure your static files storage in settings.py:
STORAGES = {
    "default": {
        # Your cloud storage backend configuration for media files
        # For example, for AWS:
        # "BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
    },
    "staticfiles": {
        # Comment out or remove the default static files storage
        # "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
        
        # Use WhiteNoise's compressed manifest static files storage
        "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
    },
}
  1. Add the collectstatic command to your predeploy commands:
python manage.py collectstatic --no-input

This setup will:

  • Serve your static files efficiently with WhiteNoise
  • Compress and add cache headers to your static files
  • Create a manifest of all your static files with hashed names for cache busting

Note: Make sure your STATIC_ROOT is properly configured in settings.py:

STATIC_ROOT = BASE_DIR / "staticfiles"  # or your preferred static files directory
Back to Top