Heroku部署Django应用Debug=False时出现500错误及静态文件问题
Hey there, let's work through your Django-Heroku static file issue step by step—this is a common gotcha, so we'll get it sorted!
1. Where are the static files actually being copied?
Heroku uses ephemeral dynos, which means every time you run heroku run bash, you're spinning up a brand-new temporary container based on your app's slug (the packaged version of your code). When you manually run heroku run python manage.py collectstatic, those files only exist in that one-off dyno—they don't get saved to your app's slug, so the next bash session won't see them.
The correct way to run collectstatic on Heroku is during the build phase (when you deploy your code). Heroku's Django buildpack will automatically run collectstatic by default, unless you've set the DISABLE_COLLECTSTATIC environment variable to 1. The files collected during build are stored in your app's slug, so every dyno that starts up will have access to them in /app/staticfiles.
2. Is this the cause of the 500 error?
Absolutely. The ValueError: Missing staticfiles manifest entry for 'css/font-rules-roboto.css' in your logs is the direct culprit. When DEBUG=False, Django (with Whitenoise's CompressedManifestStaticFilesStorage) checks the generated manifest.json file to map static file names to their hashed versions (for cache busting). If it can't find an entry for that CSS file, it throws a hard 500 error instead of serving a broken link.
1. Ensure Heroku runs collectstatic during deployment
- First, check your Heroku build logs (run
heroku logs --tail --source build) to see if there's a line likeRunning collectstatic.... If you seeSkipping collectstatic because DISABLE_COLLECTSTATIC is set, you need to unset that variable:heroku config:unset DISABLE_COLLECTSTATIC - Redeploy your app to trigger a new build with collectstatic enabled.
2. Verify your Django static settings are correct
Double-check these in your settings.py:
import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent # Static files (CSS, JavaScript, Images) STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), # If you have a project-level static folder ] # Whitenoise storage for manifest and compression STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Also, make sure Whitenoise is in your middleware (order matters!):
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', # Place this right after SecurityMiddleware 'django.contrib.sessions.middleware.SessionMiddleware', # ... other middleware ... ]
3. Fix the missing manifest entry error
- Check file references in templates: Make sure you're using Django's static template tag instead of hardcoding paths. In your templates:
{% load static %} <link rel="stylesheet" href="{% static 'css/font-rules-roboto.css' %}"> - Confirm the file exists locally: Ensure
css/font-rules-roboto.csslives in one of your app'sstaticdirectories (e.g.,myapp/static/css/) or in the project-levelstaticfolder defined inSTATICFILES_DIRS. - Clear old static files: Locally, run
python manage.py collectstatic --clearto delete old cached files, then commit any changes (like updatedmanifest.json) and redeploy. - Temporary debug check: If you're still stuck, switch to the non-manifest storage temporarily to rule out other issues:
Redeploy—if the 500 goes away, you know the problem is specifically with the manifest generation for that CSS file. Switch back once fixed, as the manifest storage is better for performance.STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
4. Verify static files are in the slug
After redeploying, run heroku run bash and execute ls -la /app/staticfiles/css/—you should see font-rules-roboto.css (and its hashed version, like font-rules-roboto.abc123.css) listed here. If not, your collectstatic step isn't running correctly during build.
内容的提问来源于stack exchange,提问作者David.B

