Deploying Django App to Heroku: Full Guide
Tags: django, python, heroku, webdev
Published: 2020-09-20 16:10:19

# Introduction

You made an app with Django. Great! , and you are excited to show it to everyone on the planet. For that, you need to put it somewhere online so that others can access it. 

Okay, you did some research and selected Heroku. Great Choice!👍

Now you started to deploy your app and did your research online and now you have many different resources to follow which suggest millions of ways to do it. 
So you are confused, frustrated and stuck and somehow managed to put host it but after that, to your surprise, you found that your CSS files didn't show up.🤦‍♂️

OK, Now let's solve your problems. This article covers almost everything that you will need.

## Roadmap

- Install Required Tools
- Create Required Files
- Create a Heroku app
- Edit settings.py
- Make changes for static files

# Install the required tools

For deploying to Heroku you need to have Heroku CLI (Command Line Interface) installed. 

You can do this by going here: https://devcenter.heroku.com/articles/heroku-cli

CLI is required because it will enable us to use features like login, run migrations etc.

# Create files required by Heroku

After installing the CLI let's create all the files that Heroku needs.

Files are : 

1. **requirements.txt**

    Requirements.txt is the simplest to make. Just run the command
    ```
    pip freeze > requirements.txt 
    ```

    This command will make a .txt file which will contain all the packages that are required by your current Django Application.


    **Note: If you add any package further then run this command again, this way the file will be updated with the new packages**


    What is the use of ***requirements.txt***?
    As you can see that it contains all the dependencies that your app requires. So when you put your app on Heroku it will tell Heroku which packages to install.

2. **Procfile**

    After this make a new file name Procfile and do not put any extension in it. It is a file required by Heroku

    According to Heroku :

    Heroku apps include a **Procfile** that specifies the commands that are executed by the app on startup. You can use a Procfile to declare a variety of **process types**, including:
    * Your app’s web server
    * Multiple types of worker processes
    * A singleton process, such as a [clock](https://devcenter.heroku.com/articles/scheduled-jobs-custom-clock-processes)
    * Tasks to run [before a new release is deployed](https://devcenter.heroku.com/articles/release-phase)

    For our app we can write the following command

    ```
web: gunicorn name_of_your_app.wsgi —log-file -
```

    If you are confused about your app name, then just go to wsgi.py file in your project and you will find your app name there.

    For this, you should have gunicorn installed and added to you requirements.txt file

    Installing is super simple. You must have guessed it!

    ```
pip install gunicorn
```

3. **runtime.txt**

    After this make a new text file called runtime.txt and inside it write the python version you are using in the following format

    `python-3.8.1`

    That's all the files we require. Now we have to start editing our settings.py file.

# Create a Heroku app

This is a simple step and can be done in 2 ways, either by command line or through the Heroku Website. 

Let's use the Heroku Website for now.

- After making Heroku Account you will see an option to create a new app
- It will ask you for a name, the name should be unique. After hit and trials, you will be redirected to your app dashboard.
- There are many options to play with here but let's go to the settings tab and there click on Reveal Config Vars
- In the KEY write SECRET_KEY and in VALUE paste the secret key from the settings file and you can change it because only this key will be used.
- That's all for now.
- We will revisit it soon.

# Edit settings.py

There are quite a few changes that should be made in this file. 

Lets' start

First change
```python 
DEBUG = False
```

In the allowed hosts enter the domain of your Heroku app

eg.

```python
ALLOWED_HOSTS = ["your_app_name.herokuapp.com", "127.0.0.1"]
```

Replace the SECRET_KEY variable with the following (assuming that you have setup the secret key in heroku from the previous step)

```python
SECRET_KEY = os.environ.get('SECRET_KEY')
```

What this does is, it gets the SECRET_KEY from the environment. In our case, we can set the secret_key in Heroku and it will provide the key here through environment variables.

# Setup static files

In settings file, you will find 

```python
STATIC_URL = '/static/' 
```

Replace this with the following code

```python
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
```

Basically this will create a folder named static which will hold all the static files such as CSS files.

If your App contains images that you have stored on it or the user has the ability to store then add the following lines 

```python
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
```

This is pretty much the same as the above

There is one more thing you need to do. 

If you have media files then to allow Django to server them you have to add a line to your urls.py file of the project (top-level urls file)

```python
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```

I highly recommend you have a look at this documentation.

[https://docs.djangoproject.com/en/3.1/howto/static-files/](https://docs.djangoproject.com/en/3.1/howto/static-files/)

The last thing you need to serve your static files in production is WhiteNoise

> With a couple of lines of config WhiteNoise allows your web app to serve its own static files, making it a self-contained unit that can be deployed anywhere without relying on nginx, Amazon S3 or any other external service. (Especially useful on Heroku, OpenShift and other PaaS providers.) -WhiteNoise Documentation

Install white noise 

```bash
pip install whitenoise
```

Add it in MIDDLEWARE in settings.py file

```python
MIDDLEWARE = [
  # 'django.middleware.security.SecurityMiddleware',
  'whitenoise.middleware.WhiteNoiseMiddleware',
  # ...
]
```

After this don't forget to run the command which creates the requirements.txt file. Remember?

have a look at the documentation
[http://whitenoise.evans.io/en/stable/](http://whitenoise.evans.io/en/stable/)

So finally we have completed the 2 most important steps for deploying

# Adding Code to Github

Make a new Github Repo and add all of your code in it. 
[Use this post a reference](https://dev.to/ayomide_bajo/pushing-an-existing-repository-to-github-1f68)

After that go to Heroku and under the Deploy tab, you will see an option to connect Github. 

Connect your repo and you can hit the deploy button to deploy your app.

# Using Heroku Postgres

## What is the Need? I am using SQLite already!

The problem is that 

> The Heroku filesystem is ephemeral - that means that any changes to the filesystem whilst the dyno is running only last until that dyno is shut down or restarted. Each dyno boots with a clean copy of the filesystem from the most recent deploy. This is similar to how many container-based systems, such as Docker, operate.
In addition, under normal operations, dynos will restart every day in a process known as "Cycling".

[https://help.heroku.com/K1PPS2WM/why-are-my-file-uploads-missing-deleted](https://help.heroku.com/K1PPS2WM/why-are-my-file-uploads-missing-deleted)

Basically all the data you will store will get delete every 24hrs.

To solve Heroku suggest using either AWS or Postgres. Heroku has made it very simple to use Postgres. 

Let's do this

Go to your app dashboard and in the Resources section search for Postgres. Select it and you will get something like this 

![Check this image](https://dev-to-uploads.s3.amazonaws.com/i/xhg14xt58hctdiwg9gwb.png)

Now go to the settings tab and reveal the config vars

You will see a DATABASE_URL key there. It means that Heroku has added the database and now we have to tell our app to use this database. 

For this, we will be needing another package called dj_database_url. Install it through pip and import it at top of settings.py file 

Now paste the following code below DATABASES in settings file

```python
db_from_env = dj_database_url.config(conn_max_age=600)
DATABASES['default'].update(db_from_env)
```

That's it now your database is setup

Currently, your database is empty and you might want to fill it. 

- Open terminal
- type → `heroku login`
- After the login run the following commands
 
```python
heroku run python manage.py makemigrations
heroku run python manage.py migrate
heroku run python manage.py createsuperuser
```

Now your app is ready to be deployed 

either use 

```python
git push heroku master
```

(after committing the changes) or push it through Github.

___ 

OK, so it's finally done. It is a bit long but quite easy to do because you have to make only some minor changes, nothing too big.

If there is any kind of improvement then please tell me in the comments.

___

## Check Out my other articles
https://dev.to/theshubhagrwl/should-you-track-your-time-4d52

## Visit My Blog
https://theshubhagrwl.hashnode.dev/

## Visit my website and follow me on Blogging and social platforms
http://theshubhagrwl.netlify.app/