7. Deply Django App in Heroku

7.1. Set Up

Requirements-

  1. Git installed locally

  2. Postgres installed locally, if running the app locally

https://devcenter.heroku.com/articles/git

Install Heroku CLI into Ubuntu. Then login

$sudo snap install heroku --classid
# or if using apt
$ sudo apt install heroku
 $ heroku login
›   Warning: heroku update available from 7.42.4 to 7.42.6.
heroku: Press any key to open up the browser to login or q to exit:

Update Heroku, I believe it requires a restart after the update

$ snap refresh heroku
# or if using apt
$ heroku update

7.2. Prepare the App

As a security measure to prevent HTTP Host header attacks add an ‘*’ to ALLOWED_HOSTS.

# pages_project/settings.py
ALLOWED_HOSTS = ['*']

7.2.1. Install gunicorn

::

$ pip install gunicorn $ pip freeze > requirements.txt

7.2.2. Define a Procfile

The Procfile is a text file in the root directory of the application. The below declares a single process type= web. This process type will be attached to the HTTP routing stack of Heroku

web: gunicorn <my_project_name>.wsgi --log-file -

7.3. Deploy the App

7.3.1. Create an app in Heroku

$ heroku create <unique app name in heroku>     # app name optional
Creating app... done, ⬢ sheltered-brook-17119
https://sheltered-brook-17119.herokuapp.com/ | https://git.heroku.com/sheltered-brook-17119.git

Add a remote to your local repository. Note that heroku only deploys code to the master or main branch

$ heroku git:remote -a sheltered-brook-17119
set git remote heroku to https://git.heroku.com/sheltered-brook-17119.git
# check the remote was created
$ git remote -v
heroku  https://git.heroku.com/sheltered-brook-17119.git (fetch)
heroku  https://git.heroku.com/sheltered-brook-17119.git (push)
# rename a remote if you wish
$ git remote rename heroku heroku-staging

7.4. Configure Static Files on Heroku

If you wish you can tell Heroku to ignore or disable static files like CSS and javascript

$ heroku config:set DISABLE_COLLECTSTATIC=1

To configure Heroku to serve static files add the following to the settings.py file

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

# Extra places for collectstatic to find static files.
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

Also Django won’t automatically create the target directory STATIC_ROOT that collectstatic uses. If directory is not available you may need to create this directory for collectstatic. Git does not support empty file directories so you may have to create a file inside STATIC_ROOT, maybe an __init.py__ file.

7.4.1. WhiteNoise

Django does not support serving static files in production, but WhiteNoise can integrate static files into the Django application. First install WhiteNoise with pip.

$ pip install whitenoise

Add WhiteNoise into the settings.py middleware section.

MIDDLEWARE_CLASSES = (
# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/
'whitenoise.middleware.WhiteNoiseMiddleware',

7.4.2. Debugging

If collectstatic failed you can get additional feedback with

$ heroku config:set DEBUG_COLLECTSTATIC=1

7.5. Heroku Simplified DevOps

$ git push <remote_name> <branch_name>