WhiteNoise Documentation

repository·main·Indexed 22 days ago

https://github.com/evansd/whitenoise

WhiteNoise (v6.12.0) allows Python WSGI applications to serve their own static files directly, removing the need for external servers like nginx or S3. It provides features for caching headers, index file serving, and a CLI utility for pre-generating gzip and Brotli compressed files. The library includes specialized integration for Django via WhiteNoiseMiddleware and various storage backends for manifest-based caching and compression.

Tokens
10.4K
Snippets
25
Records
60
Agent score
83%

What's inside WhiteNoise

  1. Overview of WhiteNoise

    main

    WhiteNoise is a library for radically simplified static file serving for Python web applications. It allows your web app to serve its own static files, making it a self-contained unit that can be deployed anywhere (such as Heroku or OpenShift) without relying on external services like nginx or Amazon S3. It is designed to work with any WSGI-compatible application and includes special auto-configuration features for Django. It also handles best practices automatically, including:

    • Serving compressed content (gzip and Brotli formats) while correctly handling Accept-Encoding and Vary headers.
    • Setting far-future cache headers on immutable content.
    • Compatibility with CDNs for high-traffic performance.
  2. QuickStart for Django apps

    main

    To use WhiteNoise with a Django application, add whitenoise.middleware.WhiteNoiseMiddleware to your MIDDLEWARE list in settings.py. It must be placed above all other middleware except for django.middleware.security.SecurityMiddleware.

    MIDDLEWARE = [
        # ...
        "django.middleware.security.SecurityMiddleware",
        "whitenoise.middleware.WhiteNoiseMiddleware",
        # ...
    ]
  3. QuickStart for other WSGI apps

    main

    For non-Django WSGI applications, wrap your existing WSGI application instance with a WhiteNoise instance. You must specify the root directory where your static files are located. You can also use .add_files() to include additional directories with an optional prefix.

    from whitenoise import WhiteNoise
    
    from my_project import MyWSGIApp
    
    application = MyWSGIApp()
    application = WhiteNoise(application, root="/path/to/static/files")
    application.add_files("/path/to/more/static/files", prefix="more-files/")
  4. Integrate Frontend Build Systems (Webpack/Browserify)

    main

    You can integrate frontend build tools by using a three-tier directory structure:

    1. static_src: Contains source files (JS, CSS, etc.). This directory is checked into version control.
    2. static_build: The output directory for your build tool (e.g., Webpack). This directory is not checked into version control.
    3. static_root: The final destination after collectstatic. This directory is not checked into version control.

    Configuration: Add the build directory to your STATICFILES_DIRS in settings.py:

    STATICFILES_DIRS = [BASE_DIR / "static_build"]

    This allows Django to find processed files without needing to know which build tool produced them.

  5. Configure Django staticfiles for WhiteNoise

    main

    Before enabling WhiteNoise, ensure your Django project is configured to collect static files into a specific directory. Add STATIC_ROOT to your settings.py and run ./manage.py collectstatic during your deployment process.

    Always use the {% load static %} template tag to reference files instead of hardcoding URLs.

    STATIC_ROOT = BASE_DIR / "staticfiles"
  6. Configure WhiteNoise with a CDN (e.g., Amazon CloudFront)

    main

    For high-traffic sites, use a CDN. WhiteNoise sends appropriate cache headers so the CDN can serve files without contacting your application.

    To use a CDN like CloudFront, define a STATIC_HOST variable in settings.py. It is recommended to use an environment variable to avoid hardcoding the domain.

    Example using an environment variable:

    import os
    STATIC_HOST = os.environ.get("DJANGO_STATIC_HOST", "")
    STATIC_URL = STATIC_HOST + "/static/"

    On Heroku, set the variable using:

    heroku config:set DJANGO_STATIC_HOST=https://your-distribution-domain.cloudfront.net

    CloudFront Note: To serve Brotli or other non-gzip encodings, you must configure your CloudFront distribution to cache based on the Accept-Encoding header in the Behaviours tab.

    STATIC_HOST = os.environ.get("DJANGO_STATIC_HOST", "")
    STATIC_URL = STATIC_HOST + "/static/"
  7. Use WhiteNoise in development

    main

    By default, Django's runserver handles static files, which bypasses WhiteNoise's improvements. To use WhiteNoise in development to match production behavior, you can either:

    1. Pass the --nostatic flag to the runserver command.
    2. Add whitenoise.runserver_nostatic to the top of your INSTALLED_APPS list in settings.py.
    INSTALLED_APPS = [
        "whitenoise.runserver_nostatic",
        "django.contrib.staticfiles",
        # ...
    ]
  8. Serving Media Files with Django

    main

    WhiteNoise is not suitable for serving user-uploaded media files for several reasons:

    1. Startup limitation: WhiteNoise only checks for static files at startup; files added later won't be seen.
    2. Security risk: Serving user-uploaded files from the same domain as your main application is a security risk.
    3. Scalability: Using local disk for media makes it difficult to scale across multiple machines.

    Recommendation: Use a dedicated storage service like Amazon S3, Azure Storage, or Rackspace CloudFiles via the django-storages library.

  9. Enable WhiteNoise in a Flask application

    main

    To serve static files using WhiteNoise in a Flask application, wrap the Flask application's WSGI application object (app.wsgi_app) with a WhiteNoise instance.

    If you are using the standard Flask quick start approach, assign the wrapped object back to app.wsgi_app. You should specify the root argument to point to your static directory (e.g., root="static/").

    from flask import Flask
    from whitenoise import WhiteNoise
    
    app = Flask(__name__)
    app.wsgi_app = WhiteNoise(app.wsgi_app, root="static/")
  10. Enable Brotli compression

    main

    WhiteNoise supports Brotli compression, which is more efficient than gzip. To enable it, install the Brotli Python package using the WhiteNoise extra:

    pip install whitenoise[brotli]

    Note: Browsers will only request Brotli data over an HTTPS connection.

  11. Enable WhiteNoise middleware in Django

    main

    To allow WhiteNoise to serve your static files, add whitenoise.middleware.WhiteNoiseMiddleware to your MIDDLEWARE list in settings.py.

    Important: Place it directly after django.middleware.security.SecurityMiddleware (if present) and before all other middleware. Do not move it to the top of the list even if other third-party middleware suggests doing so.

    MIDDLEWARE = [
        # ...
        "django.middleware.security.SecurityMiddleware",
        "whitenoise.middleware.WhiteNoiseMiddleware",
        # ...
    ]
  12. Verify WhiteNoise Installation and Configuration

    main

    To confirm WhiteNoise is working correctly, run your application locally with DEBUG disabled and verify that static files still load.

    1. Run collectstatic to populate your static files directory:
      python manage.py collectstatic
    2. Set DEBUG = False in your settings.py.
    3. Start the server:
      python manage.py runserver
      If static files load as they would in production, the configuration is correct.
    python manage.py collectstatic
    python manage.py runserver