Deploy Django App to Production with Heroku.

Samiddha
16 min readMay 17, 2021
Image credit: ”https://assets.pinterest.com/ext/embed.html?id=834854849667487364"

Django is a very powerful and secure python framework for web development. If you start reading the article, that means you may developed your web app. But you don’t know how to deploy your web app for production at free of coast. You will find many platforms in internet to deploy your Django app. But most of them is not free; you have to pay money to deploy your app with this platform and also you need to buy a domain for your app. If you want to serve not only static files, also want to server media files and want to store user uploaded files, then you need a storage infrastructure like AWS S3, Azure Storage. But these storage platforms are expensive.

But DON’T WORRY! I will show you how to deploy your app without paying any money and even you don’t need to buy any domain for your web app. And we will use a free cloud infrastructure.

UPDATE: From November 28, 2022, the free tier plan of Heroku will no more available. So, after that data, you can’t use Heroku at free anymore. And all the apps you deployed in Heroku with the free tier plan will stop working after that date.

Let’s Get Started…..

Requirements:

  1. An account on Dropbox
  2. A GitHub account
  3. An account on Heroku

Step 1: Make Some Change In Your Django Project to Prepare the Web App for Production:

Here is our Project Structure for this Tutorial:

Project Structure

Install the following packages in your django project with pip-

pip install python-decouplepip install gunicornpip install django-herokupip install django-storages[dropbox]pip install django-dropbox-storagepip install whitenoisepip install django-cors-headerspip install mysqlclient

Now add the following code at the beginning of the settings.py:

Import modules in settings.py

Now add django_dropbox_storage, storages and corsheaders to the INSTALLED_APPS in settings.py:

INSTALLED_APPS in settings.py

NOTE:

  1. If your web-app need to server not only Static Files, need Media Files or user uploaded files also; then you have to install django-storages[dropbox] and django-dropbox-storage in your web app.
  2. If you want to enable or disable CORS in your web-app, then you have to install django-cors-headers . I suggest you to install it to increase the security of your web-app.

Add Middleware Classes:

  1. WhiteNoiseMiddleware: Add whitenoise.middleware.WhiteNoiseMiddleware MIDDLEWARE in settings.py.
  2. CorsMiddleware: If you install django-cors-header, then You will also need to add corsheaders.middleware.CorsMiddleware in MIDDLEWARE in settings.py. CorsMiddleWare should be placed as high as possible, especially before any middleware that can generate responses, such as Django’s CommonMiddleWareor Whitenoise’s WhiteNoiseMiddleware. If it is not before, it will not be able to add the CORS headers to these responses.
MIDDLEWARE in settings.py

Add the following code anywhere in settings.py:

add this line in settings.py

File extensions to skip when compressing. If you define an empty list then WhiteNoise will compress all types of files. If you define any file type in the list (like jpg, png) then the WhiteNoise will only compress only the defined file types. It would be safe to leave this list empty and attempt to compress all files.

Set DEBUG to False:

Set DEBUG to False in settings.py

Always keep in mind; when you deploy/host your django-app, then you should set DEBUG to False. By default django set DEBUG to True.

DEBUG = True, means when any error is occurred in your project, then django will show the error in the browser; if DEBUG=False, instead of showing the error, you cans ee that the web page show the text Server Error. If you set DEBUG=True on production, then if any error is occurred, the error is shown to the client also. But it’s not secure to show errors to clients, it makes your website vulnerable.

Hide SECRET_KEY value:

You should not directly use SECRET_KEY or any other confidential value like API Key in your code. You must use it with the environment variable.

How to Set Environment Variable?

step 1: Create a .env file in the project’s root directory, i.e., in which folder manage.py is present.

step 2: Open the .env file with any text editor (like Notepad, Notepad++), and set environment variable and value of environment variable in the following format (Never forget to save the file after changes)-

variable_name1=value_of_variable_name1variable_name2=value_of_variable_name2

My SECRET_KEY is-

So I added the SECRET_KEY value in .env file like that:

SECRET_KEY=hxw(-5yd_nm0q8m=51)^gz!fi!t)oq_gpr=*c^vi@

Add your SECRET_CODE like the above in .env file.

Now In settings.py it will be:

Hide SECRET_KEY value in settings.py

Keep in mind, when you deploy yours web app for production, then never use confidential data (like API key, SECRET_KEY) directly in your code. You must use these data with environment variable. And never upload or push the .env file in GitHub or anywhere. Keep this file only in your PC.

Set ALLOWED_HOSTS:

Set ALLOWED_HOSTS in settings.py

Here, we will set the value of the environment variable DOMAIN_NAME in Heroku, not in .env file. (I will show this in the final step).
You can see here we use a default parameter; when a variable is not set in .env, then the config function will return the value of the default.
In that case, DOMAIN_NAME is not defined still now, so the config function will return 127.0.0.1.

Add Extra Security to your website.

If you want much more security on your website, then you can add the following code in settings.py. If you don’t need extra security then you can skip this. But I always recommend you to increase the security.

Add this code in settings.py to maximize security

Setup Database:

Now, in settings.py, update the DATABASE connection-

DATABASE in settings.py

In that case, we will set the values of environment variables in Heroku, not in .env. (I will show this in the final step).

Now Add the following code in settings.py at the very bottom, to ensure seamless deployment on Heroku

Now, run the following command in terminal (CLI): If you are working in virtual environment, make sure that your virtual environment is activated.

pip freeze > requirements.txt

Make sure your virtual environment is active, and in CLI you are in the root directory of the project (in which directory manage.py is present).

This command will generate a new file with the name requirements.txt in the project’s root directory. This file contains the name of all the pip packages that you have installed for that project. This fill will instruct the Heroku to install that packages in the Heroku server to run your website.

Step 2: Setup Dropbox:

If you only want to serve static files on production, then you can skip the step. If you want to serve media files and want to store user uploaded files also on production, then this step is required.

  1. Add the following code in settings.py:

2. Go to Dropbox Developers.

3. On the top-right of the web page you will find a button App console. Click on the button. After click the button you will be redirect to a new page (Sign In page).

3. Now create an account on Dropbox

Sign In page of Dropbox
Sign Up page of Dropbox

After Sign Up go to this link https://www.dropbox.com/developers/apps. And follow this procedure

Create a new app on Dropbox

Now select all the input as per as the bellow image

Give the details of the app

Here, we give name of app as TestApp. You can give any reasonable name to your app.

After successfully created app, you will be redirect to a new page. Now you need to configure your created app and need to link the app with your django project. Step by step follow the procedures as shown as image to do theses things.

Step — I:

In the page you will find your App key and App secret.

Add the value of App key and App secret in .env file:

DROPBOX_APP_KEY=92wicdedg7p1vllDROPBOX_APP_SECRET=h3ui62ox3v6sc12

In settings.py:

In your case, value of APP_KEY and APP_SECRET will be different

Step — II:

After successfully generate the access token, your access token will be shown.

Copy the access token, and in .env file add this token -

DROPBOX_OAUTH2_TOKEN=your-access-token

In settings.py:

Step — III:

Set Access token expiration to No expiration. By default this is set to Short-lived.

Step — IV:

Go to Top of the page-

Step — V: Click the checkboxes that are checked in the bellow image:

Configuration of Dropbox app

Step — VI:

Go to this link: https://www.dropbox.com/home/Apps

Here you will find a folder; the name of the folder is exactly same as the created app name. In our case folder name is TestApp.

Go to this folder and inside that folder create a new folder-

1.

2.

3.

Give a name to the new folder. For this tutorial, I give the name assets.

Create a new folder

Now add the following code in settings.py:

DROPBOX_ROOT_PATH = '/new_created_folder_name/'

In our case, this will be:

Step 3: Setup your GitHub

At first sign in to GitHub. If you don’t have any GitHub account sign up now.

Download & Install Git in Your Computer:

Go to this link https://git-scm.com/downloads and download the git. For installation see- How to install git.

Configure Git in Your Computer:

After successfully installation of git, open git bash application in your computer and run the following commands in git bash-

Now Click Here. You will find a New Button in top-left of the page.

After Clicked the button, you will be redirect to a new page. The page contain some input field.

Let see, what to do in the page…

  1. Owner: In Owner field you will see that it shown your username with profile photo. You don’t need to do anything with this field.
  2. Repository name: In this field, type a name; this will be the name of your repository. You can give any name to your repository. You can give the name as same as your web app. Like if name of your web app is ‘BlogApp’, then you can give the repository name as ‘BlogApp_repo’. This name should be unique (If you create a repository with name ‘My Repository’, then you can’t make another repository with the same name in your account); for the demonstration I give the repository name as TestApp_repo.
  3. Description: In the field give some information about your project. This is optional.
  4. Public/Private: If you want that anybody can see (access) your repository on the internet, then you can make your repository as Public. If you want that, anybody can’t see your repository on internet, then you can make your repository as Private. Private repositories are only accessible to you and people you explicitly share access. It is better to make your repository as private.
  5. Add .gitignore: Click the checkbox; After checked, you will see that, a new option is available with the name .gitignore template, click on that, then form the dropdown menu select Python.
  6. Create repository: After complete all of the above mentioned steps, click the Create repository button.

Now, from your PC file manager go the root directory of your project (in which directory manage.py is presents). On that directory, press right click; in context menu you will see an option Git Bash Here, click the option and git bash will be open.

Now, in git bash-

  1. type $ git init and press Enter.
  2. type $ git remote add origin https://github.com/username/repo_name and press Enter. Here, in my case username will be Username and repo_name will be TestApp. So, in my case the command will be- $ git remote add origin https://github.com/Username/TestApp
  3. type $ git pull origin master --rebase and press Enter.
  4. type $ git add --a and press Enter.
  5. type $ git commit -m “Initial Commit" and press Enter.
  6. type $ git push origin master and press Enter. This command will push (upload) your code to GitHub. To run that command you PC need to connect to the internet.

NOTE: Each time when you make any change in your code, then you need to run the commands of 4, 5and 6 one by one.

After execute all the above command, you will se that a new file (.gitignore) will be added in your root directory.

Step 4: Setup Heroku

This is the final step. In this step we will finally deploy our web app.

Now, go to root directory of your django project (in which directory manage.py is presets) from file manager. And follow these procedures-

  1. Procfile: In the project root directory create a new file and file name will be Procfile; Be careful, don’t use extension with the file name i.e. file name should not be like procfile.txt or .Procfile; File name must be just Procfile. After created the file, open the file with any text editor (like Notepad, Notepad++) and write the following content in a single line-
web: gunicorn project_folder.wsgi --log-file - --log-level 'debug' --preload --max-requests 1200 --timeout 30 --keep-alive 30

Here, project_folder is the folder name, in which folder wsgi.py is presents. This code will instruct the Heroku to use gunicorn to run the server for your website, it will execute the script of .wsgi file to initialize the service.

In my case, this will be:

web: gunicorn TestProject.wsgi --log-file - --log-level 'debug' --preload --max-requests 1200 --timeout 30 --keep-alive 30

2. python: Create another file in the root directory and give the file name python. Don’t use any extension name. And leave the file empty. By detecting the file Heroku will understand it is a Python project.

2. runtime.txt: Again, in the project root directory create another file and give the file name runtime.txt. Open the file with text editor and just write the version of Python. For example, if version of your Python is 3.8.9; then we have to write — python-3.8.9. This file will instruct the Heroku to install the Python version of 3.8.9 to run the project.

How to check the version of Python?

Run the following command to check your Python version:-

python --version

Now, you have to create an account on Heroku. Go to this link https://signup.heroku.com/ to create an account.

NOTE: In Primary development language select Python.

After create your first account, follow these procedures as shown in the images -

NOTE: These procedures also be done with Heroku CLI, But using CLI is little bit difficult for beginner; using UI is easy for beginner. So I make the tutorial with UI.

1.

2.

App name is unique. Your website domain will automatically create depend on that app name. Your website domain will be create in this format- app_name.herokuapp.com. I give the app name first-test-app-site, so in that case, our website domain will be first-test-app-site.herokuapp.com. This will be our DOMAIN_NAME.

After give an app name, click on Create app.

Still now, we didn’t define the DOMAIN_NAME in our .env file. Now set the DOMAIN_NAME in .env file. In my case, this will be-

DOMAIN_NAME=first-test-app-site.herokuapp.com

3.

4. In Settings Panel

5.

Remember? we use environment variable in the first step of the tutorial. And say that, we will set the variables in Heroku. Now it’s time to set all the variables for production. Values of the variable that you set in .env file can’t be used in production/deployment. .env is only available for Development. To add variables and values, in KEY input field you have to enter the name of the variables and in VALUE input field you have to enter the values of the variables and then press Add each time. You already defined the values of SECRET_KEY, DROPBOX_APP_KEY, DROPBOX_APP_SECRET, DROPBOX_OAUTH2_TOKEN and DOMAIN_NAME in .env file. Copy all the data from .env and paste it here.

For Example,

in .env:

DROPBOX_APP_KEY=92wicdedg7p1vll

in Heroku:

6.

7. In the Resources Panel:

8.

After click on the button, a new page will be opened in new tab. In the top-right of the new page there has a search bar. In the search bar search for
Heroku Postgres.
And all search results will be appear.

9.

Click on that search result.

10.

11.

App name is the name, by which name you create your Heroku app with 2nd procedure of step-4. In my case, the app name will be first-test-app-site.

12.

After click the Submit Order Form you will be redirect to Resources Panel. Now do this-

13.

14.

15.

Database credentials

Remember? In Step-1 we Setup Database with some environment variable, but we didn’t define the values of this variable. Now it’s time to define the values of the variables with the method, which method we have discussed in 5th Procedure of Step-4.

You can see that in the above image, there are some information given, now use this information to define the values of the variables-

DATABASE_ENGINE : django.db.backends.mysql
DATABASE_NAME : Database
DATABASE_USER : User
DATABASE_PASSWORD : Password
DATABASE_HOST : Host
DATABASE_PORT : Port
DATABASE_URL : URL

In my case, this is-

Config vars

16.

17.

Now you have to connect your Heroku App with your GitHub Account.

In Step-3, you already create a GitHub account.

18.

In Step-3, I already discussed how to create a GitHub repository.

In this input field, after type your repo name press the Search button. If any repository exists in your GitHub account with this name, the in bottom of the input, it will show your repository. Here you will find a Connect button. Press the button and wait for some time.

19.

Almost done!

After clicking the button wait some time; If all of your configuration is right, then your web-app will be deploy successfully.

REMEMBER! Each time when you make any changes in your django-app, then at first you have to push this changes to GitHub (in Step-3, it has been said); and after doing that you have to click the Deploy Branch button. If you don not do this, then your changes will not make any effect in your website.

You can see all the logs in this section; If during the deployment any errors occurred, then it will be display here.

Deploy logs

20.

Now your Web-App is deployed. But if you open the site, you will see Server Error. This is happened because still you did not migrate your database to newly created Heroku database. You have to migrate your database to Heroku Postgresql database. To do so follow this procedure -

REMEMBER! Each time when you run python manage.py makemigration Command in your local project you have to do this, after redeploy your app.

In top-right of the page, there are two button-

After click on the button, in dropdown menu you see an option Run Console, click on that-

21.

Now, you can see a input field. In that input field type — python manage.py migrate and click on Run button.

console

After successfully execute the command close the console and in top-right of the page you can see a button Open app. Click on that button.

Now you will see your site working properly.

Finally, your website is deployed.

--

--