Deploy Django Site on Qovery for free
Published: 2021-09-14 07:29:48

Coding a Django website is pretty simple, but deploying it online could be a tedious & a complicated task for beginners(including me). Hence here is a complete guide on how to host your Django site for free on [Qovery](https://www.qovery.com/)

**Note:** This is basically a guide on how to modify you Django application to make it work on Qovery. For guide on how to make the application & deploy on Qovery check out this guide :
https://hub.qovery.com/guides/tutorial/deploy-django-with-postgresql/

So I'm assuming you have already made your Django project and made a github/gitlab repository & it is working perfectly on your local machine. I'm also assuming that you have a Qovery account & have created an project as well as an environment for the same. (From github/gitlab repository)

I will be taking my TriviaQuiz Django Site for reference.

Here is my initial repository that was working perfectly on my local machine:
https://gitlab.com/rachitkhurana40/trivia-quiz-initial 

## Setting up the Webserver

Qovery basically hosts your application through a docker container and need a webserver to run on. So we can use [gunicorn](https://pypi.org/project/gunicorn/). Its a pretty simple python webserver. 
You just need to install it using pip & add it to your requirements.txt file

Django automatically generates a wsgi.py file that is required by gunicorn to run the server. 
Now the startup command will be 
```
gunicorn <yourprojectname>.wsgi
```

For mine it will be 
```
gunicorn triviaquiz.wsgi
``` 

## Making Dockerfile
Qovery hosts your application through a docker container. So the next thing we need to do is make a Dockerfile

A Dockerfile is just a text document with all the commands required to build your application in a docker container. 

Don't worry you won't need to learn Docker just for hosting. 

You can you my Dockerfile for the same. most probably it will work with your Django Project too. 

```dockerfile
FROM python:3
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
RUN python manage.py makemigrations
RUN python manage.py migrate
RUN python manage.py collectstatic
EXPOSE 8000
CMD ["gunicorn","<yourprojectname>.wsgi","--bind","0.0.0.0:8000"]
```
For my project it is 
```dockerfile
FROM python:3
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
RUN python manage.py makemigrations
RUN python manage.py migrate
RUN python manage.py collectstatic
EXPOSE 8000
CMD ["gunicorn","triviaquiz.wsgi","--bind","0.0.0.0:8000"]
```

**Note:** Dockerfile is doesn't have an extension

## Static Files
Serving static files for the website is important. Otherwise most of your static assets (like css , js files) won't be shown on the site. 

For serving static files we will use [whitenoise](http://whitenoise.evans.io/en/stable/)

You can install it using pip and also add it to your requirements.txt.

After that you just need to add whitenoise (`whitenoise.middleware.WhiteNoiseMiddleware`) to your django middleware in your project's settings.py file. 
**Note:** Add the whitenoise middleware after Django’s SecurityMiddleware( `django.middleware.security.SecurityMiddleware`)
. For eg:

```python
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
```
Notice the whitenoise middleware in 2nd line. 

### Forever-cacheable files and compression support (Optional) 
Just add this to your settings.py:

```python
STATICFILES_STORAGE='whitenoise.storage.CompressedManifestStaticFilesStorage'
```

## Database

The next thing we need to do is change the database from sqlite to Either postgres or Mysql on Qovery. 

You might be wondering why should we do that? The simple answer is the sqlite database resets everytime you deploy your site. 
Since sqlite is just a file, it gets overwritten everytime you make even a small change in your code & deploy it. 



Hence we will be using Postgres database from Qovery. 

First create a postgres database in Qovery
![Make a postgres DB](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8thmhm3mdxtewp00nkdt.png)

After creating, go to its actions and deploy it. 
After deploying it, I would recommend you to restart it , it gets optimised by doing that. 

Next we need to use this database in our Django app. 
For that we need to make some changes in settings.py file. 


By default Django uses sqlite database & has the following code in settings.py file

```python

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

But we will be using Postgres for our app. Hence will need to install [psycopg2](https://pypi.org/project/psycopg2/) & also add it to the requirements.txt file.

After that we need to change the database config in settings.py file to 

```python
DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': os.environ.get('<DBNAME>', 'postgres'),
    'USER': os.environ.get('<DG_LOGIN>', 'postgres'),
    'PASSWORD': os.environ.get('PASS'),
    'HOST': os.environ.get('<DB_HOST>','<host_url>'),
    'PORT': os.environ.get('<DB_PORT>', 5432),
  }
}
```

All the things with <> needs to be modified. 
<DBNAME> can be found in your qovery's Environment variables and would be something like `QOVERY_POSTGRESQL_XXXXXXXXX_DEFAULT_DATABASE_NAME`

Similarly <DG_LOGIN> would be something like `QOVERY_POSTGRESQL_XXXXXXXXX_LOGIN`
<DB_HOST> would be like `QOVERY_POSTGRESQL_XXXXXXXXX_HOST`
<DB_PORT> would be like `QOVERY_POSTGRESQL_XXXXXXXXX_PORT`

For <host_url>, go to your database application in Qovery and then click on Host. It will automatically copy the host url. 


After that you need to go to your database application in Qovery. & then click on show config. And copy your master password. 
Now come back to your application project on Qovery, and make a new environment variable.
Its name should be `PASS` and value should be the password that you copied. 

After replacing all <> with the values, you can push your git code and Qovery will start to deploy your Django applications. And then your website will be up in a few minutes. 


## Creating Superuser
And next thing you might need to do is make a superuser. For that you should use your local machine instead. 
So you can navigate to your directory in which the project is. Otherwise clone your repository and navigate to that
For that you need to create a `.env` file. 
**Note:** It should be `.env` file and not `.env.txt`

The `.env` file should contain the following:

```
QOVERY_POSTGRESQL_XXXXXXXXX_DEFAULT_DATABASE_NAME="postgres"
QOVERY_POSTGRESQL_XXXXXXXXX_LOGIN="postgres"
PASS="<PASS>"
QOVERY_POSTGRESQL_XXXXXXXXX_HOST="<host_url>"
QOVERY_POSTGRESQL_XXXXXXXXX_PORT=5432
```
Here you should replace `QOVERY_POSTGRESQL_XXXXXXXXX_DEFAULT_DATABASE_NAME` etc with the variable names as described a little above, under Database. 

And also replace <PASS> with the database password and <host_url> with the host url. 

Now you can open this directory in your terminal/CMD . 
and then you can run the command 
```bash
python manage.py createsuperuser
```
either in a virtual environment or directly (as per your preference).

After that you can access everything from your Django's admin panel. 

Here is the final repository:
https://github.com/rachit1601/triviaquiz

Here is my site deployed on Qovery:
https://triviaquiz.redcrypt.xyz/

If you have any other problems, you can write in the comments or you can contact me on Discord at `DiluteWater#3149`