Deploying Django application with Gunicorn, Apache, and MySQL on Ubuntu Server

Deploying a Django application is a crucial step in taking your web project from development to production. While Django’s built-in development server is great for testing and debugging, it’s not suitable for handling the demands of a live production environment. To ensure your Django application can handle real-world traffic and serve as a reliable, performant, and secure web application, you’ll need to set up a production-ready server stack.

In this guide, we’ll walk you through the process of deploying a Django application on an Ubuntu server using Gunicorn as the application server, Apache as the reverse proxy server, and MySQL as the database management system. This stack is a popular choice for deploying Django applications due to its stability, scalability, and security features.

Setting up the software

1. Update Ubuntu software repository

2. Install

i. apache2 – Serve our website

ii. mysql-server and libmysqlclient-dev – For database

iii. Python 3

iv. ufw – Firewall for our system

v. virtualenv – Virtual environment for our django application

  Clone your django repo

Installing Python libraries

1. Create virtual env (e.g env)

2. Activate virtualenv

3. Install project dependencies and packages

4. Install mysql client for python

5. Install gunicorn to interact with our python code

6. Install white noise to serve our static files

Setting up the firewall

We’ll disable access to the server on all ports except 8000 and OpenSSH for now. Later on, we’ll remove this and give access to all the ports that Apache needs.

Setting up database

1. Install mysql and setup the root password

2. Create a database and a user for the application.

Setting up the Django project

In your project folder, modify the file

1. Include the newly created database access configurations.

2. Include the IP address of your server and domain name (if any) in the allowed hosts.

3. Include CORS_ALLOWED_ORIGINS, CSRF_TRUSTED_ORIGINS, and CORS_ORIGIN_WHITELIST if you have a domain name set already.

4. In your installed apps, include ‘whitenoise.runserver_nostatic’ just above ‘django.contrib.staticfiles’.

5. In your MIDDLEWARE, include ‘whitenoise.middleware.WhiteNoiseMiddleware’ just below, ‘’.

6. Make database migrations to create all the required tables in the new database and collect all static files to a static folder under the django_project directory.

7. Run the development server to check whether everything is working fine.

Setting up Gunicorn

1. Test gunicorn with django by running the following command inside the django project folder

2. Test the app in your browser on the server ip while mapping the port <server ip>:8000 e.g . (Notice that you can access static files because we set up whotenoise.)

3. Kill gunicorn and exit the virtual environment.

4. Lets daemonize the gunicorn

i. Open a new gunicorn.service file using any text editor your comfortable with.

5. Create a script to start the server

i. Create in your virtualenv bin directory

ii. Edit the file as follows:

iii. Make the file executable

iv. Enable the daemon

vi. If something goes wrong, run

If you make any changes to your Django application, reload the gunicorn service

Setting up the Apache server

1. Create a new site file for apache

2. Copy the following lines with appropriate modifications

3. Enable the necessary Apache modules.

4. Enable the newly registered site.

5. Restart apache

6. allow access to apache ports through ufw

If everything works fine, you should be able to access your Django application on <server ip> or <domain name (if you registered one)>

 Setting up SSLs for our domain

1. To set up SSL/TLS certificates for a domain (e.g.,, We’re going to  use Certbot (a tool for obtaining and renewing Let’s Encrypt SSL certificates)

2. Register a new apache site to enable SSLs.

3. Enable new site

4. Reload apache

Congratulations, You can now access your site with SSL enabled in your browser.