Deploying A Ready-To-Go Django Website On Heroku


May 26, 2023 • Django psycopg Heroku PostgreSQL



If you are like me you may have made your website fully on a dev branch with database entries and are looking to add it to production. I looked around a lot to try to narrow down the best host platform for my website and finally landed on Heroku. It made deployment very easy and learned how to use and interface Heroku with GitHub. In this blog I will go over the following:

 

  1. Migrating SQLite to PostgreSQL
  2. Preparing your project folder and files for production
  3. Adding your files to github
  4. Setting up Heroku and connecting it to GitHub
  5. Deploying your website
  6. Using a Google domain

 

 

1. Migrating SQLite to PostgreSQL

 

This step is fairly easy will only take a few minutes and there are steps you can skip past I will mention. If you're like me then you may have made your dev version of your website with SQLite which comes by default with Django. Sadly SQLite is not a good database for production level and it is file-based which can lead to problems since heroku is cloud based and it would be weird to have a SQLite database hosted in the cloud.

 

Some of the necessary steps for the database such as adding db environment variables to Heroku and setting up the database on Heroku will be discussed in the following sections, but for now we will just convert your old SQLite db to a PostgreSQL db.

 

Realistically if you want to do this quick and skip the local testing steps you can just do steps 1 and steps 3, I would also do step 4 since you will make a requirements.txt file later that will be generated based on the libraries needed for the project. Step 5 will also be needed but you can do this once you have Heroku setup and you will see why later. 

 

1. Backing up the db

Run the following command to backup the data in json format.

python manage.py dumpdata > data.json

 

2. Install PostgreSQL

If you're like me and have used or have PostgreSQL/pgAdmin installed then you can probably skip this step. You will also be hosting your db on an aws server through Heroku anyways so it is not entirely necessary to do this step unless you are wanting to see if the migration will work.

 

Download PostgreSQL/pgAdmin here: https://www.postgresql.org/

 

3. Configuring the settings.py file

This file is the one from your Django project folder. Find the DATABASES section in the settings file and change the following:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

To this:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'test',
        'USER': 'postgres',
        'PASSWORD': 'test123',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

If you want to test the db then create a database called test. If you don't then just leave it as is for now, we will convert these to .env variables and they will be accessed via Heroku in their env variables section of the app you create there. If this is confusing don't worry it will be discussed later. 

 

4. Installing psycopg2

One of the best database adapters, I use it for many other python projects and it works very well. To install it run the following.

pip install psycopg2

 

5. Sync the database and load the data

To sync the data use the following command.

python manage.py migrate --run-syncdb

To load the data into the database do the following command.

python manage.py loaddata data.json

 

You may face potential issues with duplicate keys. If you run into this issue with then you can run the following commands after running the sync command.

python manage.py dbshell

Then add.

TRUNCATE django_content_type;

If that doesn't work than you can add this instead.

TRUNCATE django_content_type CASCADE;

Once you do this run the load command again and it should work just fine.

 

 

2. Preparing your project folder and files for production

 

This part is not too difficult, you just need to adjust a few things in the settings file in order to get it ready for Heroku. There are many ways to do this and mine is one that I found simple and error free. This section also goes over security and storing important info into a .env file to mitigate potential important data from being accessible to others. 

 

1. Setup the Procfile

Go to your projects root folder (the one with manage.py) and add a Procfile (of type File). Add the following line to your code.

web: gunicorn <myproject>.wsgi –log-file -

Where <myproject> is the folder name containing the settings.py file. This is of course the line when using gunicorn which is what I use as my WSGI server for this project. If you use something like waitress-server then you would need to find the appropriate line to add to the Procfile.

 

2. Install Gunicorn, django-heroku, and Whitenoise

First step is to install Gunicorn and Django Heroku. To do so type the following in a terminal.

pip install gunicorn and django-heroku

Next you want to add Whitenoise.

pip install whitenoise

After this open the settings.py file and add the following line to the middlewares section.

'whitenoise.middleware.WhiteNoiseMiddleware',

I added this step in case in the future I would use some static files but for now my website uses a cdn with my files/images stored in GitHub.

 

3. Setup the requirements.txt file and a runtime.txt file

Once you have all the necessary libraries installed you want to generate a requirements.txt file. This file can be regenerated if needed so each time heroku deploys a new branch it knows which libraries to install. To generate the file run the following.

pip freeze > requirements.txt

This file should be in the root directory where the manage.py file is. If you look in the file you will see a list of libraries line by line that you have been using in dev of the website.

 

Once you have finished the requirements.txt file you want to create a runtime.txt file. In the file all you need to insert is the following.

python-3.11.1

If you use a different version then you can change the version after the "-".

 

4. Updating a few things in the settings.py file

First thing you want to do is import a couple libraries.

import django_heroku
import dj_database_url

Then at the bottom of the settings file, add the following.

django_heroku.settings(locals())

The database import will be used to return a Django database connection dict, while the Heroku library will configure the app so it can work with Heroku.

 

5. Setting up security

Very important step, this will isolate all the important information you don't want someone with website access to access.

 

1. First thing you watn to do is create a .env file (file format should be an ENV File).

Note: this .env file will be useful for any dev side when you configure heroku any variables in this file will be added through their webapp since you will add this to your .gitignore so Heroku won't read the .env file.

 

2. In this file add any information you would like to hide. I include the following.

 

3. Next you want to setup a library that can associate the values in this file with the settings.py file. To do this, install python-decouple.

pip install python-decouple

Add the following line to you settings.py file.

from decouple import config

So now you are going to use config to replace the information you want to hide. For ex.

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('DEBUG', cast=bool)

or for the db.

'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': config('NAME'),
        'USER': config('USER'),
        'PASSWORD': config('PASSWORD'),
        'HOST': config('HOST'),
        'PORT': config('PORT'),
    }

 

4. Next you want to add a .gitignore file. The file type is just a simple .txt file so you can make a text file and name it .gitignore. All you need to add to the file is .env or any other file you would like to ignore pushing to github as well.

 

 

3. Adding your files to Github

 

In my opinionm this is the best way to give Heroku access to your website files. GitHub makes it easy to update your code locally and push the changes to Heroku. I also recommend using GitHub since many companies use it for version control so it can give you practice.

 

  1. If you don't have it already, you need to install Git on your computer here https://git-scm.com/.
  2. Go to GitHub and sign in.
  3. Make a repo and name it to your liking, something related to the project ideally.

 

Once done, use commands to push the files to your repo. You can find these commands in GitHub. I use the following. git init will initialize the necessary git files in the project folder so make sure you are in the project folder with manage.py before running the commands.

git init

git commit -m "first commit"

git branch -M main

git remote add origin https://github.com/username/reponame.git

git push -u origin main

 

That's it, you should be done now and ready to move onto the next step.

 

 

4. Setting up Heroku and connecting it to GitHub

 

First thing you need to do is create a Heroku account here https://signup.heroku.com/login

 

Creating the environment

  1. Once in the account click "New" in the top right corner to create a new app.
  2. Download the Heroku CLI on your computer. guide here https://devcenter.heroku.com/articles/heroku-cli
  3. If you installed it correctly you should get a version response when typing "heroku --version".
  4. Now in the command line type in "heroku login" and press any key to login via browser.
  5. Then enter the following into the command line "heroku git:remote –a <name>" with <name> being Heroku app name.
  6. To see if you are connected, type "git remote --v".
  7. Back in the Heroku app look for Open App in the top right corner and click it.
  8. This will open the page that will be your homepage of the website. Copy the url without the leading "https://" and without the ending "/".
  9. Now go back to your settings.py file and add the following to the ALLOWED_HOSTS list inside the []. ["yoururl.heroku.com", "127.0.0.1"].
  10. Now back in the Heroku app page click on the settings tab.
  11. Scroll till you see the Add Buildpack button, click it and add Python as your language.
  12. Since you changed your settings.py file above, push the changes to git.
    • git add
    • git commit -m "New settings changes"
    • git push

 

Adding Postgres

Go to resources tab in the Heroku web app and type in "Heroku Postgres". Select it and click "Submit Order Form". This will attach a PostgreSQL db to your app.

 

Click on the "Heroku Postgres" search and it will redirect you to the db page. Then once the page is open click on Settings -> View Credentials. I personally added the credentials to my .env file so that when I work on the site locally I will be able to push anything needed for the db to the same db the live site uses. You will also need to add these credentials to the environment variables as show in the next step below.

 

Adding environment variables to Heroku

Heroku has it's own way of accessing your special info since you don't add/don't want to add the inportant info directly to your settings file or in your git repo. To do this go to settings in the Heroku web app.

 

Under config vars, click show config vars. Add any necessary Key/Value pairs, the key should match the name you used in your settings.py file and the value should be the secret info that you want separate from the rest of the website code.

 

The nice thing about this you can change the values in real time if needed without the need to redeploy.

 

Pushing table data to Postgres

If you're like me you have added tables and rows to your old SQLite database and need to add them to the PostgreSQL database. To do so you need to follow the next steps. Note, these steps are very similar to the ones above in part 1 but you need to do a few different things since we are pushing these changes to the Heroku side. 

If you followed the steps above you should have the .json file containing the old SQLite data in the files Heroku has access to. If so run the following.

heroku run python manage.py migrate --run-syncdb --app=your_app_name

Then run the next command.

heroku run python manage.py loaddata data.json --app=your_app_name

 

Potential issue resolution

If this command doesn't work you are probably experiencing a PostgreSQL duplicate key issue. If so you need to run a few commands in the dbshell. To do so, run the following.

heroku pg:psql

Once inside the Shell, add the following.

TRUNCATE django_content_type;

If this doesn't work and you get an error run.

TRUNCATE django_content_type CASCADE;

Now you can rerun the command.

heroku run python manage.py loaddata data.json --app=your_app_name

 

 

5. Deploying your website

 

Everything should be ready to go now and you are ready to deploy the website!

 

  1. In Heroku web app click on the Deploy tab.
  2. Connect Heroku to your GitHub repository.
  3. They will ask you to authorize so make sure to do so.
  4. Specify the repo to connect to and click search.
  5. Now click deploy and hope that you set everything up right so you have no errors.
  6. Once it is deployed and you have fixed any potential issues shown in the log click view site to see the website.

 

 

6. Using a Google domain

 

If you're like me and have your own personal domain, you may want to use that as your website URL. To do so use the following steps.

 

  1. In Heroku web app go to Settings -> Add your domain.
    • Add www.[yourdomain.domainsuffix] to your app, www. is needed.
    • Copy the DNS Target generated.
  2. In Google Domains -> DNS -> Resource Records -> Custom Records -> Manage Custom Records
    • www, CNAME, 1 hour, [DNS Target]
  3. Back in Heroku enable SSL Cert in settings. Once you do give it some time to update (45m-1h) and then in Domains under ACM Status it should say Ok and you should be able to see this above: Your app can be found at https://www.yourdomain.com rather than Your app can be found at http://www.yourdomain.com.

 

Back in Google Domains, go to the website tab. In the website click add forwarding (or edit forwarding) and what you want to do is set:

This helps redirect to the proper url when you search or someone searches domainname.com.

Conclusion

 

This blog covers the basics of getting a Django project into production using Heroku. This was for me a very smooth process and if done correctly should have minimal to no issues and errors throughout! If you have any questions or issues, leave a comment and I will try my best to reply swiftly.




Leave a comment:




Comments:


On Jan. 13, 2025  http://boyarka-Inform.com wrote:

hi!,I like your writing very a lot! share we be in contact mpre about your post on AOL? I neded a specialist on this house too solvee myy problem. Maybe that is you! Looking aheasd to peer you. http://boyarka-Inform.com