Search code examples
pythondjangoheroku

Heroku performing collectstatic as expected on deployment?


I have Django setup to collect my static files and copy them into S3 using django-storages and this works like a charm when I explicitly run

heroku run python manage.py collectstatic

However, I expect Heroku to perform this action automatically upon deployment (i.e. git push to Heroku) as described in this documentation https://devcenter.heroku.com/articles/django-assets . Apparently, the output of:

python manage.py collectstatic --dry-run --noinput

determines whether or not collectstatic is configured correctly (collectstatic works correctly when I run it explicitly). I get:

$ heroku run python manage.py collectstatic --dry-run --noinput
Running `python manage.py collectstatic --dry-run --noinput` attached to terminal... up, run.9607
Pretending to copy '/app/app_pkg/static/robots.txt'
.... # Lot of similar outputs not shown
16 static files copied.

That looks good to me but the documentation does not specify what I should see. When I deploy the project, everything appears to work fine and complete successfully.

-----> Installing dependencies using Pip (1.2.1)
       Cleaning up...
-----> Collecting static files
       16 static files copied.

-----> Discovering process types
       Procfile declares types -> web

The files do not show up in my S3 bucket though. If I then explicitly run

heroku run python manage.py collectstatic

all the files show up in the S3 bucket. I think Heroku should be performing this action for me and I'm not sure why its not. Is this expected behavior? Should I need to do it myself?


Solution

  • Odd no one has answered you yet! Simply add this to the beginning of your Procfile:

    web: python manage.py collectstatic --noinput
    

    This will run python manage collectstatic every time your app is deployed on Heroku.

    The cleanest way is to chain it to your existing Procfile like so:

    web: python my_django_app/manage.py collectstatic --noinput; bin/gunicorn_django --workers=4 --bind=0.0.0.0:$PORT my_django_app/settings.py
    

    Credit goes to Matthew Phiong & his awesome blog post