简体   繁体   English

在cloudControl部署中调试Django`collectstatic`的问题

[英]Problems debugging Django `collectstatic` in a cloudControl deployment

I have a Django application deployed to cloudControl. 我有一个部署到cloudControl的Django应用程序。 Configuration is standard and the push/deploy happens without (apparent) errors. 配置是标准配置,推送/部署不会发生(明显)错误。

But the collectstatic step is not being executed: it fails silently (I see no -----> Collecting static files message). 但是collectstatic步骤没有执行:它静默失败(我看不到-----> Collecting static files消息)。 After the deploy, the static folder for the application is empty, so you get 500 Server Errors continually. 部署后,该应用程序的静态文件夹为空,因此您会连续收到500个服务器错误。

I can solve it changing the Procfile , but it is not consistent either: 我可以通过更改Procfile来解决它,但是它也不是一致的:

web: python manage.py collectstatic --noinput; gunicorn app.wsgi:application --config gunicorn_cnf.py --bind 0.0.0.0:${PORT:-5000}`

collectstatic works as it should locally, and if I run cctrlapp app/deployment run "python manage.py collectstatic --noinput" no errors are shown either: collectstatic可以在本地正常运行,并且如果我运行cctrlapp app/deployment run "python manage.py collectstatic --noinput"不会显示任何错误:

669 static files copied to '/srv/www/staticfiles/static', 669 post-processed. 将669个静态文件复制到'/ srv / www / staticfiles / static',后处理669。

But /srv/www/staticfiles/static is empty. 但是/srv/www/staticfiles/static为空。


How can I know why collectstatic is not being executed in the push phase? 我怎么知道为什么在push阶段没有执行collectstatic?

I've been able to debug the problem, using a custom python buildpack , so here is the answer for further reference. 我已经能够使用自定义的python buildpack调试问题,所以这里是进一步参考的答案。

The problem was in the settings.py file. 问题出在settings.py文件中。 The first thing I do in this file is to check if we are in a cloudControl environment or in a local environment. 我在此文件中要做的第一件事是检查我们是在cloudControl环境中还是在本地环境中。 I do it looking for the CRED_FILE environment variable (not so different of what is suggested ): if no variable is found, I load a local JSON file that mimics that credentials variable for development: 我这样做是在寻找CRED_FILE环境变量(与建议的变量没有太大不同):如果未找到任何变量,则会加载一个本地JSON文件,该文件模仿该凭据变量进行开发:

try:
    cred_file = os.environ['CRED_FILE']
    DEBUG = False

except KeyError:
    cred_file = os.path.join(BASE_DIR, 'creds.json')
    DEBUG = True

Once I know the environment, I can have different INSTALLED_APPS ( requirements.txt files are slightly different in production and development, too) or change some settings. 知道环境后,我就可以拥有不同的INSTALLED_APPS (在生产和开发中, requirements.txt文件也略有不同)或更改某些设置。

Now the bad news: in the push phase there is no CRED_FILE available. 现在的坏消息是:在推送阶段没有可用的CRED_FILE

So I was trying to load apps that were not installed (because they were only in the development requirements file, like coverage or django-debug-toolbar ) or use credentials that were not set ( creds.json is, of course, not uploaded to the repository: only a TXT with dummy values is uploaded as a reference). 因此,我试图加载未安装的应用程序(因为它们仅在开发需求文件中,例如coveragedjango-debug-toolbar )或使用未设置的凭据(当然, creds.json未上传到资源库:仅上传具有虚拟值的TXT作为参考)。 That's why collectstatic was failing silently in the push phase. 这就是为什么collectstatic在推阶段默默地失败。

Here is my solution (it will work as long as you have a dummy credentials file in your repo): 这是我的解决方案(只要您的存储库中有虚拟凭据文件,它就可以工作):

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

Credentials are not used by collectstatic , so you can have anything in the creds.json.txt file. 凭证不是collectstatic使用的,因此creds.json.txt文件中可以包含任何内容。 Not very clean, but it works as expected now. 不是很干净,但是现在可以正常工作了。


EDIT 编辑

As pointed by @pst in a comment there is an environment variable to know if the buildpack is running, so we could use that one too to load the desired credentials and set DEBUG . 正如@pst在评论中指出的那样,有一个环境变量可以知道buildpack是否正在运行,因此我们也可以使用该变量来加载所需的凭据并设置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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM