Deploy Django Site on Qovery for free

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

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. 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.

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

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

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:

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:

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

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

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 & also add it to the requirements.txt file.

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

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.
can be found in your qovery's Environment variables and would be something like QOVERY_POSTGRESQL_XXXXXXXXX_DEFAULT_DATABASE_NAME

Similarly would be something like QOVERY_POSTGRESQL_XXXXXXXXX_LOGIN
would be like QOVERY_POSTGRESQL_XXXXXXXXX_HOST
would be like QOVERY_POSTGRESQL_XXXXXXXXX_PORT

For , 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 with the database password and with the host url.

Now you can open this directory in your terminal/CMD .
and then you can run the command

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

35