How to deploy a Django website on Heroku securely?

How to deploy a Django website on Heroku securely?

Publish your website on the Heroku and show it to the world


Are you facing a problem with deploying your Django website on Heroku? Don’t worry. Read this quick tutorial. You will be able to deploy your website on Heroku with ease and securely. We will have different configurations for Heroku deployment that will make your application more secure and manageable. In this tutorial, I will explain how to deploy your application safely with best practices. 

Note - I assume you have created your Django website and your website is running on the local server. 

Here are the steps to do it. 


Step 1 - Installations

You can skip this part if you have already installed these applications. Install the following applications. 

Heroku installation 

GIT installation

If you are not using GIT then follow the below steps otherwise you can skip this part. 

git config --global user.name "Your name here"
git config --global user.email "your_email@example.com" 

Note - You have to run this command only once after the installation. 


Step 2 - Creating a repository on the Github website

Don’t worry about the repository. You can understand it as an online folder (remote folder) for your project where you will upload your project. Basically, it will be an online copy of your project. 

Steps:

  • Go to the Github website. Make sure to log in. Click on New Repository
  • Now, you can write any name for your repository. Now, click on Create Repository
  • Go to your project folder, right-click, and click on the open in terminal.
  • Run the following command 
git init 
git remote add origin https://github.com/rhtm123/your_repo_name.git 
git branch -M main

Note - Don’t forget to replace your_repo_name with your repository name. 


Step 3 - Installing necessary python packages and creating requirements.txt file

Here, I am assuming you have created your Django Project already.

Go to your project folder and then right-click and click on the open in terminal

Run this command 

pip install gunicorn dj-database-url psycopg2

Run this command to create requirements.txt

pip freeze > requirements.txt

Step 4 - Creating a new setting for Heroku deployment

We will create another setting file for our Heroku deployment. The idea is we want to have separate settings for deployment and local server. 

  • Create a new file (heroku_settings.py) in the same folder as settings.py
  • Add the following lines to the file
from yourdjangoprojectname.settings import *
import sys
import os
def find_or_create_secret_key():
    """ 
    Look for secret_key.py and return the SECRET_KEY entry in it if the file exists.
    Otherwise, generate a new secret key, save it in secret_key.py, and return the key.
    """
    SECRET_KEY_DIR = os.path.dirname(__file__)
    SECRET_KEY_FILEPATH = os.path.join(SECRET_KEY_DIR, 'secret_key.py') 
    sys.path.insert(1,SECRET_KEY_DIR) 
    if os.path.isfile(SECRET_KEY_FILEPATH):
        from secret_key import SECRET_KEY
        return SECRET_KEY
    else:
        from django.utils.crypto import get_random_string
        chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
        new_key = get_random_string(50, chars)
        with open(SECRET_KEY_FILEPATH, 'w') as f:
            f.write("# Django secret key\n# Do NOT check this into version control.\n\nSECRET_KEY = '%s'\n" % new_key)
        from secret_key import SECRET_KEY
        return SECRET_KEY
SECRET_KEY = find_or_create_secret_key()
STATIC_ROOT  =   os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
# Extra lookup directories for collectstatic to find static files
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
import dj_database_url 
prod_db  =  dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(prod_db)


Note: 
  • Don’t forget to replace yourdjangoprojectname with your project name. 
  • You can see we are not using manual SECRET_KEY in this file. Instead, Our SECRET_KEY will be stored in secret_key.py file.

Step 5 - Creating .gitignore file

We will create .gitignore file in our root folder. This file is very important if you want to push your code to the GitHub repo. We mention the paths of all the files, and folders in this file we don’t want to upload on the GitHub repo. Of course, we don’t want to upload our secret_key.py to the GitHub repo. Open this file and add the following lines. 

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# db
db.sqlite3
# secret file
secret_key.py

Step 6 - Change in wsgi.py

Open wsgi.py and replace everything with this.

import os
from django.core.wsgi import get_wsgi_application
from django.contrib.staticfiles.handlers import StaticFilesHandler
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'yourdjangoprojectname.heroku_settings') 
application = StaticFilesHandler(get_wsgi_application())

Note -

  • Don’t forget to replace yourdjangoprojectname with your project name. 

Step 7 - Procfile and runtime.txt
  • Create a Procfile in your project folder (this file has no extension). Open this file and add the line below.
web: gunicorn yourdjangoprojectname.wsgi --log-file -
  • Create a runtime.txt in your project folder. In this file we will mention the python version. Open this file and add this line (replace the version as per your project)
python-3.8.10


Note: 

  • Procfile file does not any extension. 
  • Don't forget to replace yourdjangoprojectname with your project name.

Step 8 - heroku_manage.py
Create a new file (heroku_manage.py) in your project folder. Open this file and add the following codes

import os
import sys
def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'yourdjangoprojectname.heroku_settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)
if __name__ == '__main__':
    main()

Note: 
  • Don't forget to replace yourdjangoprojectname with your project name.

Step 9 - Heroku login

You need to log in to Heroku to push your code. Just run the following command. This will redirect you to your browser. 

heroku login

Step 10 - Create a  Heroku App

We will create a Heroku app from the terminal. Run the following code. 

heroku create herokudjangoapp

Add this line in heroku_settings.py

ALLOWED_HOSTS = ['herokudjangoapp.herokuapp.com']
Note: 
  • Choose any name that is available
  • Don't forget to replace herokudjangoapp with your name.

Step 11 - Push your code

Now, time to push our code to the Heroku server. Run this code before pushing it.

python heroku_manage.py runserver

Note: If there is some error, solve the issue first and then proceed further. 

If everything is running as expected run the following commands

git add .
git commit -m "your message"
heroku config:set DISABLE_COLLECTSTATIC=1
git push heroku main

The Output will be like this

Counting objects: 26, done.

Delta compression using up to 4 threads.

Compressing objects: 100% (20/20), done.

Writing objects: 100% (26/26), 31.14 KiB | 0 bytes/s, done.

Total 26 (delta 1), reused 0 (delta 0)

remote: Compressing source files... done.

remote: Building source:

.....

remote: -----> Launching...

remote:        Released v1

remote:        https://herokudjangoapp.herokuapp.com/ deployed to Heroku

remote: 

remote: Verifying deploy... done.

To https://git.heroku.com/herokudjangoapp.git

[new branch]      master -> master


NOTE -   Your website will be available at this link - https://herokudjangoapp.herokuapp.com/ . Of course, your heroku app name will be different. 

Step 12 - Migrate the database and collectstatic

Run the following commands. This will create the required tables for your website. 

heroku run python heroku_manage.py migrate
heroku run python heroku_manage.py collectstatic


Step 13 - Create a superuser for your Heroku website

You can create a superuser to access your admin panel. Run the following command in your terminal. 

heroku run python heroku_manage.py createsuperuser

Step 14 -  When you make some modification
You don't have to repeat from the start when you make some modification. Run the following commands every time you make some changes.

git add .
git commit -m "your message"
git push heroku main

Congratulations. You have deployed your Django website on Heroku securely.