The Problem

I tried to deploy my Django News project to Heroku. However I couldn’t accomplish to deploy it; it was failing every time: Gives Build Failed.

The Strugle

I followed cookiecutter-django instruction:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
$ heroku create --buildpack https://github.com/heroku/heroku-buildpack-python

$ heroku addons:create heroku-postgresql:hobby-dev
# On Windows use double quotes for the time zone, e.g.
# heroku pg:backups schedule --at "02:00 America/Los_Angeles" DATABASE_URL
$ heroku pg:backups schedule --at '02:00 America/Los_Angeles' DATABASE_URL
$ heroku pg:promote DATABASE_URL

$ heroku addons:create heroku-redis:hobby-dev

$ heroku addons:create mailgun:starter

$ heroku config:set PYTHONHASHSEED=random

$ heroku config:set WEB_CONCURRENCY=4

$ heroku config:set DJANGO_DEBUG=False
$ heroku config:set DJANGO_SETTINGS_MODULE=config.settings.production
$ heroku config:set DJANGO_SECRET_KEY="$(openssl rand -base64 64)"

# Generating a 32 character-long random string without any of the visually similar characters "IOl01":
$ heroku config:set DJANGO_ADMIN_URL="$(openssl rand -base64 4096 | tr -dc 'A-HJ-NP-Za-km-z2-9' | head -c 32)/"

# Set this to your Heroku app url, e.g. 'bionic-beaver-28392.herokuapp.com'
$ heroku config:set DJANGO_ALLOWED_HOSTS=

# Assign with AWS_ACCESS_KEY_ID
$ heroku config:set DJANGO_AWS_ACCESS_KEY_ID=

# Assign with AWS_SECRET_ACCESS_KEY
$ heroku config:set DJANGO_AWS_SECRET_ACCESS_KEY=

# Assign with AWS_STORAGE_BUCKET_NAME
$ heroku config:set DJANGO_AWS_STORAGE_BUCKET_NAME=

$ git push heroku master

$ heroku run python manage.py createsuperuser

$ heroku run python manage.py check --deploy

$ heroku open

Everything was OK till the push phase, line 37. This line gives Build Failed error. The shorted output from Heroku can be seen below:

-----> Python app detected
 !     Python has released a security update! Please consider upgrading to python-3.8.5
       Learn More: https://devcenter.heroku.com/articles/python-runtimes
-----> Installing python-3.8.3
-----> Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2
-----> Installing SQLite3
-----> Installing requirements with pip
       Collecting pytz==2020.1
         Downloading pytz-2020.1-py2.py3-none-any.whl (510 kB)
       Collecting python-slugify==4.0.1
         Downloading python-slugify-4.0.1.tar.gz (11 kB)

         ...
         BLA BLA BLA
         ...

           Running setup.py install for psycopg2: started
           Running setup.py install for psycopg2: finished with status 'done'
       Successfully installed Collectfast-2.2.0 Pillow-7.2.0 amqp-2.6.1 argon2-cffi-20.1.0 asgiref-3.2.10 billiard-3.6.3.0 cachetools-4.1.1 celery-4.4.6 certifi-2020.6.20 cffi-1.14.2 chardet-3.0.4 defusedxml-0.6.0 django-3.0.8 django-allauth-0.42.0 django-anymail-7.1.0 django-celery-beat-2.0.0 django-crispy-forms-1.9.1 django-environ-0.4.5 django-js-asset-1.2.2 django-model-utils-4.0.0 django-mptt-0.10.0 django-ratelimit-2.0.0 django-redis-4.12.1 django-storages-1.9.1 django-timezone-field-4.0 djangorestframework-3.11.0 flower-0.9.5 future-0.18.2 google-api-core-1.22.1 google-auth-1.20.1 google-cloud-core-1.4.1 google-cloud-storage-1.31.0 google-crc32c-1.0.0 google-resumable-media-1.0.0 googleapis-common-protos-1.52.0 gunicorn-20.0.4 hiredis-1.0.1 humanize-2.6.0 idna-2.10 kombu-4.6.11 mistune-0.8.4 oauthlib-3.1.0 prometheus-client-0.8.0 protobuf-3.13.0 psycopg2-2.8.5 pyasn1-0.4.8 pyasn1-modules-0.2.8 pycparser-2.20 python-crontab-2.5.1 python-dateutil-2.8.1 python-slugify-4.0.1 python3-openid-3.2.0 pytz-2020.1 redis-3.5.3 requests-2.24.0 requests-oauthlib-1.3.0 rsa-4.6 sentry-sdk-0.16.1 six-1.15.0 sqlparse-0.3.1 text-unidecode-1.3 tornado-6.0.4 typing-extensions-3.7.4.3 urllib3-1.25.10 vine-1.3.0
-----> $ python manage.py collectstatic --noinput
       Traceback (most recent call last):
         File "/app/.heroku/python/lib/python3.8/site-packages/environ/environ.py", line 273, in get_value
           value = self.ENVIRON[var]
         File "/app/.heroku/python/lib/python3.8/os.py", line 675, in __getitem__
           raise KeyError(key) from None
       KeyError: 'DJANGO_GCP_STORAGE_BUCKET_NAME'
       During handling of the above exception, another exception occurred:
       Traceback (most recent call last):
         File "manage.py", line 31, in <module>
           execute_from_command_line(sys.argv)
         File "/app/.heroku/python/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
           utility.execute()
         File "/app/.heroku/python/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
           self.fetch_command(subcommand).run_from_argv(self.argv)
         File "/app/.heroku/python/lib/python3.8/site-packages/django/core/management/__init__.py", line 231, in fetch_command
           settings.INSTALLED_APPS
         File "/app/.heroku/python/lib/python3.8/site-packages/django/conf/__init__.py", line 76, in __getattr__
           self._setup(name)
         File "/app/.heroku/python/lib/python3.8/site-packages/django/conf/__init__.py", line 63, in _setup
           self._wrapped = Settings(settings_module)
         File "/app/.heroku/python/lib/python3.8/site-packages/django/conf/__init__.py", line 142, in __init__
           mod = importlib.import_module(self.SETTINGS_MODULE)
         File "/app/.heroku/python/lib/python3.8/importlib/__init__.py", line 127, in import_module
           return _bootstrap._gcd_import(name[level:], package, level)
         File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
         File "<frozen importlib._bootstrap>", line 991, in _find_and_load
         File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
         File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
         File "<frozen importlib._bootstrap_external>", line 783, in exec_module
         File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
         File "/tmp/build_9bb85fa2/config/settings/production.py", line 69, in <module>
           GS_BUCKET_NAME = env("DJANGO_GCP_STORAGE_BUCKET_NAME")
         File "/app/.heroku/python/lib/python3.8/site-packages/environ/environ.py", line 123, in __call__
           return self.get_value(var, cast=cast, default=default, parse_default=parse_default)
         File "/app/.heroku/python/lib/python3.8/site-packages/environ/environ.py", line 277, in get_value
           raise ImproperlyConfigured(error_msg)
       django.core.exceptions.ImproperlyConfigured: Set the DJANGO_GCP_STORAGE_BUCKET_NAME environment variable
 !     Error while running '$ python manage.py collectstatic --noinput'.
       See traceback above for details.
       You may need to update application code to resolve this error.
       Or, you can disable collectstatic for this application:
          $ heroku config:set DISABLE_COLLECTSTATIC=1
       https://devcenter.heroku.com/articles/django-assets
 !     Push rejected, failed to compile Python app.
 !     Push failed

I can see the Error Log which says: variable DJANGO_GCP_STORAGE_BUCKET_NAME not set. Yes it is supposed to be not to set.

In the beginning of the project, I chose Google Cloud Platform as the “Cloud Provider”. But for simplicity and easy to use I switched to WhiteNoise to serve staticfiles.

But I already deleted the variable which is set in “production setting":

# configs/settings/production.py
GS_BUCKET_NAME = env("DJANGO_GCP_STORAGE_BUCKET_NAME")

So what is your problem then Heroku? Why do you use my old commit of the project?

I almost struggled for 2 hours to find the solution.

The Solution

The solution was to specify the branch you push to Heroku. The default command;

$ git push heroku master

pushes your master branch to deployment’s master branch. But I am not on master, I am on heroku branch which is the current one with a dozen of commits ahead.

As mentioned in doc Deploying from a branch besides master:Heroku, I changed my branch to push:

$ git push heroku heroku:master

And now it was SUCCESS. The pain released —until the next one for sure.

All done!