在 cloudControl 部署中调试 Django `collectstatic` 时出现问题
Problems debugging Django `collectstatic` in a cloudControl deployment
我有一个部署到 cloudControl 的 Django 应用程序。配置是标准的,push/deploy 没有(明显的)错误发生。
但是 collectstatic step 没有被执行:它默默地失败了(我没有看到 -----> Collecting static files
消息)。部署后,应用程序的静态文件夹为空,因此您不断收到 500 个服务器错误。
我可以通过更改Procfile
来解决它,但它也不一致:
web: python manage.py collectstatic --noinput; gunicorn app.wsgi:application --config gunicorn_cnf.py --bind 0.0.0.0:${PORT:-5000}`
collectstatic 在本地正常工作,如果我 运行 cctrlapp app/deployment run "python manage.py collectstatic --noinput"
也没有显示任何错误:
669 static files copied to '/srv/www/staticfiles/static', 669 post-processed.
但是/srv/www/staticfiles/static
是空的。
我怎么知道为什么在推送阶段没有执行 collectstatic?
我已经能够使用 custom python buildpack 调试问题,所以这里是答案以供进一步参考。
问题出在 settings.py
文件中。我在这个文件中做的第一件事是检查我们是在 cloudControl 环境中还是在本地环境中。我这样做是为了寻找 CRED_FILE
环境变量(与 what is suggested 没有太大区别):如果没有找到变量,我会加载一个本地 JSON 文件,该文件模仿用于开发的凭据变量:
try:
cred_file = os.environ['CRED_FILE']
DEBUG = False
except KeyError:
cred_file = os.path.join(BASE_DIR, 'creds.json')
DEBUG = True
了解环境后,我可以有不同的 INSTALLED_APPS
(requirements.txt
文件在生产和开发中也略有不同)或更改一些设置。
现在有个坏消息:在推送阶段没有 CRED_FILE
可用。
所以我试图加载未安装的应用程序(因为它们仅在开发要求文件中,如 coverage
或 django-debug-toolbar
)或使用未设置的凭据(creds.json
当然不会上传到存储库:仅上传带有虚拟值的 TXT 作为参考)。这就是为什么 collectstatic
在推送阶段默默失败的原因。
这是我的解决方案(只要您的存储库中有虚拟凭据文件,它就会起作用):
try:
cred_file = os.environ['CRED_FILE']
DEBUG = False
except KeyError:
if os.path.exists(os.path.join(BASE_DIR, 'creds.json')):
cred_file = os.path.join(BASE_DIR, 'creds.json')
DEBUG = True
else:
cred_file = os.path.join(BASE_DIR, 'creds.json.txt')
DEBUG = False
collectstatic
不使用凭据,因此您可以在 creds.json.txt
文件中包含任何内容。不是很干净,但现在可以按预期工作了。
编辑
正如@pst 在评论中指出的那样,有一个环境变量可以知道构建包是否为 运行,因此我们也可以使用该变量来加载所需的凭据并设置 DEBUG
。
if 'CRED_FILE' in os.environ:
cred_file = os.environ['CRED_FILE']
DEBUG = False
elif 'BUILDPACK_RUNNING' in os.environ:
cred_file = os.path.join(BASE_DIR, 'creds.json.txt')
DEBUG = False
else:
cred_file = os.path.join(BASE_DIR, 'creds.json')
DEBUG = True
我有一个部署到 cloudControl 的 Django 应用程序。配置是标准的,push/deploy 没有(明显的)错误发生。
但是 collectstatic step 没有被执行:它默默地失败了(我没有看到 -----> Collecting static files
消息)。部署后,应用程序的静态文件夹为空,因此您不断收到 500 个服务器错误。
我可以通过更改Procfile
来解决它,但它也不一致:
web: python manage.py collectstatic --noinput; gunicorn app.wsgi:application --config gunicorn_cnf.py --bind 0.0.0.0:${PORT:-5000}`
collectstatic 在本地正常工作,如果我 运行 cctrlapp app/deployment run "python manage.py collectstatic --noinput"
也没有显示任何错误:
669 static files copied to '/srv/www/staticfiles/static', 669 post-processed.
但是/srv/www/staticfiles/static
是空的。
我怎么知道为什么在推送阶段没有执行 collectstatic?
我已经能够使用 custom python buildpack 调试问题,所以这里是答案以供进一步参考。
问题出在 settings.py
文件中。我在这个文件中做的第一件事是检查我们是在 cloudControl 环境中还是在本地环境中。我这样做是为了寻找 CRED_FILE
环境变量(与 what is suggested 没有太大区别):如果没有找到变量,我会加载一个本地 JSON 文件,该文件模仿用于开发的凭据变量:
try:
cred_file = os.environ['CRED_FILE']
DEBUG = False
except KeyError:
cred_file = os.path.join(BASE_DIR, 'creds.json')
DEBUG = True
了解环境后,我可以有不同的 INSTALLED_APPS
(requirements.txt
文件在生产和开发中也略有不同)或更改一些设置。
现在有个坏消息:在推送阶段没有 CRED_FILE
可用。
所以我试图加载未安装的应用程序(因为它们仅在开发要求文件中,如 coverage
或 django-debug-toolbar
)或使用未设置的凭据(creds.json
当然不会上传到存储库:仅上传带有虚拟值的 TXT 作为参考)。这就是为什么 collectstatic
在推送阶段默默失败的原因。
这是我的解决方案(只要您的存储库中有虚拟凭据文件,它就会起作用):
try:
cred_file = os.environ['CRED_FILE']
DEBUG = False
except KeyError:
if os.path.exists(os.path.join(BASE_DIR, 'creds.json')):
cred_file = os.path.join(BASE_DIR, 'creds.json')
DEBUG = True
else:
cred_file = os.path.join(BASE_DIR, 'creds.json.txt')
DEBUG = False
collectstatic
不使用凭据,因此您可以在 creds.json.txt
文件中包含任何内容。不是很干净,但现在可以按预期工作了。
编辑
正如@pst 在评论中指出的那样,有一个环境变量可以知道构建包是否为 运行,因此我们也可以使用该变量来加载所需的凭据并设置 DEBUG
。
if 'CRED_FILE' in os.environ:
cred_file = os.environ['CRED_FILE']
DEBUG = False
elif 'BUILDPACK_RUNNING' in os.environ:
cred_file = os.path.join(BASE_DIR, 'creds.json.txt')
DEBUG = False
else:
cred_file = os.path.join(BASE_DIR, 'creds.json')
DEBUG = True