【问题标题】:Can't make WhiteNoise work with Django & Heroku for production无法让 WhiteNoise 与 Django 和 Heroku 一起用于生产
【发布时间】:2025-12-10 06:15:02
【问题描述】:

我正在尝试在 Heroku 上复制一个生产网站,为此我按照以下 3 个指南分步操作:

由于我使用的是 Django 1.11,我不知道我是否需要做一些与这些指南不同的事情。

我的 production.py 的一部分(与 settings.py 相同,但仅用于生产)如下所示:

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

DEBUG = bool( os.environ.get('DJANGO_DEBUG', True) )

ALLOWED_HOSTS = ['(((MY WEBSITE))).herokuapp.com']

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

MIDDLEWARE = [
# 'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

以及production.py的底部

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]

STATIC_URL = '/static/'

CORS_REPLACE_HTTPS_REFERER      = True
HOST_SCHEME                     = "https://"
SECURE_PROXY_SSL_HEADER         = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT             = True
SESSION_COOKIE_SECURE           = True
CSRF_COOKIE_SECURE              = True
SECURE_HSTS_INCLUDE_SUBDOMAINS  = True
SECURE_HSTS_SECONDS             = 1000000
SECURE_FRAME_DENY               = True

SECURE_CONTENT_TYPE_NOSNIFF     = True
SECURE_BROWSER_XSS_FILTER       = True
SECURE_HSTS_PRELOAD             = True
X_FRAME_OPTIONS                 = 'DENY'

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

DEBUG = True 时一切正常,但是当我设置 DEBUG = False 时,我得到一个服务器错误 (500),这意味着在处理静态文件时 Django 和/或 WhiteNoise 有问题,但我真不知道问题出在哪里。

其他相关文件: Procfile(heroku 需要)

web: gunicorn (((MY WEBSITE))).wsgi --log-file -

wsgi.py

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "(((MY WEBSITE))).settings")

application = get_wsgi_application()

最后一推:

((((MY WEBSITE)))) PS C:\users\Luis\Dev\(((MY WEBSITE)))\src> git push heroku master
Counting objects: 15, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (15/15), 1.76 KiB | 1.76 MiB/s, done.
Total 15 (delta 9), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing requirements with pip
remote:
remote: -----> $ python manage.py collectstatic --noinput
remote:        180 static files copied to '/tmp/build_f959f2c0c358dd398ff8dc5e3868dcdf/staticfiles', 194 post-processed
remote:
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 114.6M
remote: -----> Launching...
remote:        Released v30
remote:        https://(((MY WEBSITE))).herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https:// git.heroku.com/(((MY WEBSITE))).git
   4accd59..f3ec57d  master -> master
((((MY WEBSITE)))) PS C:\users\Luis\Dev\(((MY WEBSITE)))\src> heroku config:set DJANGO_DEBUG=''
Setting DJANGO_DEBUG and restarting (((MY WEBSITE)))... done, v31

(来自 Windows 10 PowerShell)

我可以提供任何其他信息。

编辑 1:Heroku 日志

((((MY WEBSITE)))) PS C:\users\Luis\Dev\(((MY WEBSITE)))\src> heroku logs

...

2017-10-12T15:37:30.520087+00:00 heroku[web.1]: Restarting
2017-10-12T15:37:30.520672+00:00 heroku[web.1]: State changed from up to starting
2017-10-12T15:37:29.813498+00:00 app[api]: Release v33 created by user (((MY EMAIL)))@gmail.com
2017-10-12T15:37:29.813498+00:00 app[api]: Set DJANGO_DEBUG config vars by user (((MY EMAIL)))@gmail.com
2017-10-12T15:37:31.361203+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2017-10-12T15:37:31.381777+00:00 app[web.1]: [2017-10-12 15:37:31 +0000] [9] [INFO] Worker exiting (pid: 9)
2017-10-12T15:37:31.384572+00:00 app[web.1]: [2017-10-12 15:37:31 +0000] [8] [INFO] Worker exiting (pid: 8)
2017-10-12T15:37:31.384240+00:00 app[web.1]: [2017-10-12 15:37:31 +0000] [4] [INFO] Handling signal: term
2017-10-12T15:37:31.803827+00:00 app[web.1]: [2017-10-12 15:37:31 +0000] [4] [INFO] Shutting down: Master
2017-10-12T15:37:32.395851+00:00 heroku[web.1]: Process exited with status 0
2017-10-12T15:37:37.767520+00:00 heroku[web.1]: Starting process with command `gunicorn (((MY WEBSITE))).wsgi --log-file -`
2017-10-12T15:37:40.329480+00:00 app[web.1]: [2017-10-12 15:37:40 +0000] [4] [INFO] Starting gunicorn 19.7.1
2017-10-12T15:37:40.329980+00:00 app[web.1]: [2017-10-12 15:37:40 +0000] [4] [INFO] Listening at: http://0.0.0.0:35812 (4)
2017-10-12T15:37:40.330075+00:00 app[web.1]: [2017-10-12 15:37:40 +0000] [4] [INFO] Using worker: sync
2017-10-12T15:37:40.333422+00:00 app[web.1]: [2017-10-12 15:37:40 +0000] [8] [INFO] Booting worker with pid: 8
2017-10-12T15:37:40.400345+00:00 app[web.1]: [2017-10-12 15:37:40 +0000] [10] [INFO] Booting worker with pid: 10
2017-10-12T15:37:41.576143+00:00 heroku[web.1]: State changed from starting to up
2017-10-12T15:37:50.369924+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big1.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=ec600bfe-db53-4133-9964-76ec4b01fa06 fwd="186.242.96.167" dyno=web.1 connect=2ms service=67ms status=200 bytes=1534224 protocol=https
2017-10-12T15:37:50.697986+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big9.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=7a74a519-106e-46a1-9714-8a4f60f9f919 fwd="186.242.96.167" dyno=web.1 connect=1ms service=100ms status=200 bytes=1262299 protocol=https
2017-10-12T15:37:50.768865+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big4.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=fb430cc6-843d-43df-ab0b-b8840c0fd587 fwd="186.242.96.167" dyno=web.1 connect=2ms service=166ms status=200 bytes=1405390 protocol=https
2017-10-12T15:37:50.672386+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big5.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=70c1a959-a2be-40f0-a4e5-6da60895e3dd fwd="186.242.96.167" dyno=web.1 connect=0ms service=80ms status=200 bytes=1221233 protocol=https
2017-10-12T15:37:50.749487+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big8.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=e72091eb-a9f3-4b69-8f78-eba9fb5e826a fwd="186.242.96.167" dyno=web.1 connect=1ms service=141ms status=200 bytes=1239167 protocol=https
2017-10-12T15:37:50.720786+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big7.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=1dc85d82-b8b9-4d35-b461-bdec2181b0cf fwd="186.242.96.167" dyno=web.1 connect=2ms service=116ms status=200 bytes=1228519 protocol=https
2017-10-12T15:37:50.783929+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big2.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=dc430a8f-8d01-4ee2-a26b-9fadd00f6f5b fwd="186.242.96.167" dyno=web.1 connect=1ms service=171ms status=200 bytes=1515225 protocol=https
2017-10-12T15:37:50.738707+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big3.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=7158de90-258f-43ec-a974-edc1b3ae0039 fwd="186.242.96.167" dyno=web.1 connect=0ms service=143ms status=200 bytes=1656610 protocol=https
2017-10-12T15:37:50.851201+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big6.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=6128369a-560a-41e4-bb0e-990473935a85 fwd="186.242.96.167" dyno=web.1 connect=4ms service=233ms status=200 bytes=1238918 protocol=https
2017-10-12T15:37:52.202544+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big10.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=8fed9a74-56d4-4458-ad67-b906ba4534ce fwd="186.242.96.167" dyno=web.1 connect=0ms service=47ms status=200 bytes=1321351 protocol=https
2017-10-12T15:37:52.845341+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big12.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=752a5b5d-1a99-4908-9c89-7d539f90c0ba fwd="186.242.96.167" dyno=web.1 connect=1ms service=46ms status=200 bytes=1469642 protocol=https
2017-10-12T15:37:52.814850+00:00 heroku[router]: at=info method=GET path="/static/images/portfolio/big11.jpg" host=(((MY WEBSITE))).herokuapp.com request_id=7042189d-0303-47d6-827b-4943ae2d9d20 fwd="186.242.96.167" dyno=web.1 connect=0ms service=40ms status=200 bytes=1313499 protocol=https
2017-10-12T15:39:31.770328+00:00 heroku[router]: at=info method=GET path="/" host=(((MY WEBSITE))).herokuapp.com request_id=78b9aa71-a519-4636-b267-272393570c04 fwd="186.242.96.167" dyno=web.1 connect=1ms service=78ms status=500 bytes=228 protocol=https

【问题讨论】:

  • 当您获得 500 时,Heroku 日志会显示什么?
  • 我只是设置heroku config:set DJANGO_DEBUG='' 来制作DEBUG=False 和Shift+F5(硬刷新)页面,这就是我得到的(见上文)。
  • 但是你说你遇到了 500 错误,那是哪里?
  • 嗯,每次我刷新时它都会显示在我的浏览器上Server Error (500)。如果有其他位置可以获得更准确的日志,请告诉我。我是新来的。
  • 如何在 WhiteNoise 处理静态文件时生成 DEBUG = TRUE?因为我尝试遵循本指南:using-whitenoise-in-development 并没有给我服务器错误 (500)。我现在有点迷路了。

标签: django python-3.x heroku production-environment production


【解决方案1】:

这条线突然出现在我看来看起来不对:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
    '/var/www/static/',
]

/var/www/static 行是从哪里来的?所有这些路径都应该是项目中的目录,Django 应该在其中查找静态文件。 Heroku 上不存在该目录,这可能是导致 Django 抛出错误的原因。

【讨论】:

  • 确实是错误的,被评论和粘贴在这里有点被取消评论。更新了主帖,抱歉。 服务器错误 (500) 仍然发生。 :(
【解决方案2】:

首先,你应该在中间件中的'django.middleware.security.SecurityMiddleware'中注释掉

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

这 (STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage') 确实遇到了服务器错误。 之后,您应该在终端或 bash 中运行以下命令: python manage.py collectstatic 这会将所有静态文件从 static 文件夹复制到 staticfiles 文件夹,该文件夹将在您的浏览器中作为静态文件提供。

【讨论】: