Django with whitenoise.storage.CompressedManifestStaticFilesStorage on Heroku

I had been having trouble deploying the Django app to Heroku with "whitenoise.storage.CompressedManifestStaticFilesStorage."

Premise

  • Use docker
  • Django 3.2.4
  • whitenoise 5.3.0

Deploying flow

  1. Push to GitHub
  2. Build a container image from a Dockerfile in CircleCI
  3. Push the container image to Heroku

In this time, mistakes were in the flow 2.

Mistakes

settings.py was below:

# ...

DEBUG = os.getenv('APP_DEBUG', 'true') == 'true'
APP_ENV = os.getenv('APP_ENV', 'dev')

# ...

MIDDLEWARE = [
    # ...
    # @see https://devcenter.heroku.com/articles/django-assets
    'whitenoise.middleware.WhiteNoiseMiddleware',
]

# ...

STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
# STATIC_URL = '/static/'
STATIC_URL = '/assets/'
# STATICFILES_DIRS = [
#     BASE_DIR / "static",
# ]

if APP_ENV == 'prod':
    # Error!
    STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
    # OK. Why?
    # STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'

It was OK to run on Heroku with "whitenoise.storage.CompressedStaticFilesStorage", but Error500 raised when using "whitenoise.storage.CompressedManifestStaticFilesStorage".

Cause

The cause was in Dockerfile. APP_ENV=prod and DEBUG=false were set in Heroku, but these environment variables were not added in CircleCI. Therefore the correct container image didn't run on Heroku.

Fixed

Fixed Dockerfile as follow:

# ...

# Added lines below.
# Django: Collect static
ENV APP_ENV=prod APP_DEBUG=false
RUN rm -rf assets && python manage.py collectstatic --no-input

# ...

13