# Deploying your Django App

In this article, I will be walking you through how you can deploy your django and DRF(Django Rest Framework) app. A little heads up, this is more of a "pre-deployment" article. This includes steps that you'll go through when deploying on most platforms. There are links to deploy on specific platforms at the end of the article. Also, you should be familiar with git and Github/Gitlab.

Below is a list of steps to successfully set up your django project for deployment:

1. Environment Variables
    
2. Gitignore
    
3. Debug and allowed hosts
    
4. Secrect key
    
5. Static files
    
6. Gunicorn
    
7. Requirements file
    
8. Git & Github
    

First things first, we'll need to open our text editor and terminal. Now navigate to your project folder and activate your virtual environment. Let's begin!

**NB:** All single line code snippets are to be executed in your command line

## Environment Variables

Before pushing our code to github, we don't want every single thing in our project leaving our PC. An example of such is the secret key for our app. To curb this we'll make use of a .env file to store all of our application's vital info.

`pip install environs~=8.0.0`

`touch .env`

Then in the settings.py file add

```plaintext
from environs import Env # new
env = Env() # new
env.read_env
```

## Gitignore

We do not want git to track all our files like .env and our local database. To take care of that we make use of a .gitignore file.

`touch .gitignore`

Open .gitignore in your text editor and add the following files

```plaintext
.env
__pycache__/
db.sqlite3
.DS_Store # Mac only
```

## Debug and Allowed hosts

It is vital that we set debug to false when moving to production and limit allowed hosts to prevent unauthorized access to our application.

In the settings.py file, update

```plaintext
DEBUG = env.bool(“DEBUG”, default=false)
ALLOWED_HOSTS = [‘.herokuapp.com’, ‘localhost’, ‘127.0.0.1’]
```

In the .env file add

```plaintext
export DEBUG=True
```

## Secret Key

This is a very important info we don't want leaving our PC. Hence, we'll add it to our .env file

In the settings.py file you should see something like this

```plaintext
SECRET_KEY  =  '(-e%3z3yp5qsirfl6_+9=ko#!r6%0am8=^x9a))p2)3y-24g%*'
```

In the .env file add

```plaintext
export SECRET_KEY=(-e%3z3yp5qsirfl6_+9=ko#!r6%0am8=^x9a))p2)3y-24g%*
```

Notice that there's no quotation mark and space when adding it to the .env file. Also, each secret key is unique to a django project so don't expect this secret key to match with yours.

Now in the settings.py file, update

```plaintext
SECRET_KEY = env.str(“SECRET_KEY”)
```

## Databases

We need to configure our database because while the default(sqlite3) is okay for local development, it's not sufficient for production. When deploying to Heroku, our app is automatically assigned a free PostgresSQL database. So we just need to configure our app to use sqlite3 locally.

In your settings.py file, update

```plaintext
DATABASES = {
"default": env.dj_db_url("DATABASE_URL")
}
```

Add this to the .env file

```plaintext
export DATABASE_URL=sqlite:///db.sqlite3
```

Then install the dj-database-url to utilize the DATABASE\_URL environment variable to configure your Django application

`pip install dj-database-url`

Then we need to install Psycopg, a database adapter that lets our Python app talk to the PostgreSQL database.

`pip install psycopg2-binary~=2.8.5`

## Static files

You can skip this if you're deploying a DRF app as it doesn't include any static file. If you're using django on the other hand, we have something extra to configure. We are doing this because django doesn't support serving static files in production itself

`pip install whitenoise~=5.1.0`

Then we need to add the configurations for whitenoise in our settings.py file

```plaintext
INSTALLED_APPS = [
...
'whitenoise.runserver_nostatic', 		# new
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',			 # new
...
]
STATIC_URL = '/static/'
STATICFILES_DIRS = [str(BASE_DIR.joinpath('static'))] 		# new
STATIC_ROOT = str(BASE_DIR.joinpath('staticfiles'))		    # new
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' 	# new
```

Then make directories for our static files

```plaintext
#Run each line one by one in your command line/terminal
mkdir static
mkdir static/css
mkdir static/js
mkdir static/images
```

Then run the collectstatic command for the first time to compile all the static file directories and files into one self-contained unit suitable for deployment.

`python manage.py collectstatic`

As a final step, in order for our templates to display any static files, they must be loaded in. So add {% load static %} to the top of the base.html file.

```plaintext
{% load static %}
<html>
…
```

## Gunicorn

We need to install gunicorn as the production web server

`pip install gunicorn~=19.9.0`

## Requirements File

This lets heroku know what dependencies are needed for our app so it can be installed. First run `pip freeze > requirments.txt` to create a requirements.txt file that contains all our app's dependencies.

## Git & Github

I'm assuming you're conversant with git and github by now. Just commit your latest changes and push it to your online repo on Github or Gitlab. If you don't know how to do that you can check out this [article](https://docs.github.com/en/github/importing-your-projects-to-github/importing-source-code-to-github/adding-an-existing-project-to-github-using-the-command-line#adding-a-project-to-github-without-github-cli).

## Deploy on Specific Platforms

At this point, we have covered most of the steps you'll need to deploy your app. Whatever is left is platform-specific, and I have covered a few of them. Please click on one of the links below to continue your deployment on any platform of your choice.

* [Deploy on Railway](https://blog.acel.cyou/deploying-your-django-app-on-railway)
    
* [Deploy on Heroku](https://blog.acel.cyou/deploying-your-django-app-on-heroku)
