简体   繁体   中英

Problems debugging Django `collectstatic` in a cloudControl deployment

I have a Django application deployed to cloudControl. 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). After the deploy, the static folder for the application is empty, so you get 500 Server Errors continually.

I can solve it changing the Procfile , but it is not consistent either:

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:

669 static files copied to '/srv/www/staticfiles/static', 669 post-processed.

But /srv/www/staticfiles/static is empty.


How can I know why collectstatic is not being executed in the push phase?

I've been able to debug the problem, using a custom python buildpack , so here is the answer for further reference.

The problem was in the settings.py file. The first thing I do in this file is to check if we are in a cloudControl environment or in a local environment. 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:

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.

Now the bad news: in the push phase there is no CRED_FILE available.

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). That's why collectstatic was failing silently in the push phase.

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. 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 .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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