Deploying a Django application to an Apache server is an important step in bringing your web application to a wider audience. Apache is a powerful and widely used web server that provides a stable and secure environment for hosting Django applications among other types of web applications. This guide: How to deploy Django project on an Apache Server, walks you through the process of setting up and deploying a Django project on an Apache server to ensure your application is ready for production.
Facts to keep in mind:
The following have been used in this article. Be sure to adjust to suit your needs.
- Root folder for our project: /home/ubuntu/djangoapp
- The folder where wsgi.py is found at /home/ubuntu/djangoapp/companyweb
- The path to the virtual environment: /home/ubuntu/djangoapp/venv
- Domain name: dtechnologies.co.ke
- The project to be deployed: https://github.com/danielnjama/django-training-project-1.git
Step 1: Install Python, virtualenv and Set up virtualenv
Run the following command to install Python and pip-the Python package manager and the virtual environment
sudo apt update
sudo apt install python3 python3-pip python3.12-venv
python3 --version
Proceed and create the working directory, crete and activate the virtual environment.
mkdir /home/ubuntu/djangoapp
cd /home/ubuntu/djangoapp
python3 -m venv venv #creates virtualenvironment in the specified path.
source venv/bin/activate #activates the virtual environment
Step 2: Set Up and enable mod_wsgi
mod_wsgi is an Apache HTTP server module that allows you to serve Python web applications using the WSGI (Web Server Gateway Interface) specification. WSGI is a standard interface between web servers and Python web applications or frameworks, like Django.
Run the following commands to set up and enable mod_wsgi.
sudo apt update
sudo apt install libapache2-mod-wsgi-py3 apache2
sudo a2enmod wsgi
sudo systemctl restart apache2
Step 3: Upload your project files
This will depend with the method that you use to upload your projects file. The available options are Scp, cloning from a github repo, rsync, wget etc. In this case, I will be pulling the project from github. To ensure we maintain the flow, upload the project files and ensure they are mapped onto the root folder: /home/ubuntu/djangoapp. Adjust this accordingly.
git clone https://github.com/danielnjama/django-training-project-1.git
#This will clone the project in the path: /home/ubuntu/djangoapp/django-training-project-1
#I need these files to be in /home/ubuntu/djangoapp which is my current working directory. To move them one level back, run the following
mv django-training-project-1/* ./
pip install -r requirements.txt #install the dependancies.
python manage.py collectstatic
#Add your domain name or the IP to your allowed host; in your settings.py file. Once fully reployed, be sure to set DEBUG= False.
Step 4: Configure Apache Virtual Host for Django
Configuring an Apache Virtual Host for Django involves setting up a dedicated configuration file within Apache to define how requests to your Django application should be handled and served.
Run the following and add the lines of code provided.
sudo nano /etc/apache2/sites-available/djangoapp.conf
#add the following code adjust to suit your needs
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName dtechnologies.co.ke
ServerAlias www.dtechnologies.co.ke
DocumentRoot /home/ubuntu/djangoapp
Alias /static /home/ubuntu/djangoapp/static
<Directory /home/ubuntu/djangoapp/static>
Require all granted
</Directory>
Alias /media /home/ubuntu/djangoapp/media
<Directory /home/ubuntu/djangoapp/media>
Require all granted
</Directory>
<Directory /home/ubuntu/djangoapp>
Require all granted
</Directory>
<Directory /home/ubuntu/djangoapp/companyweb>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess djangoapp python-home=/home/ubuntu/djangoapp/venv python-path=/home/ubuntu/djangoapp
WSGIProcessGroup djangoapp
WSGIScriptAlias / /home/ubuntu/djangoapp/companyweb/wsgi.py
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Step 4: Enable the New Site and Restart Apache
Run the to following commands:
#cd /etc/apache2/sites-available/ #Not necessary. Shows the path where the virtual host are.
sudo a2ensite djangoapp #Enable the new virtual host
sudo a2dissite 000-default.conf #Disable the default site (optional)
sudo systemctl reload apache2 #Reload Apache to apply the changes
Step 5: Check File and Directory Permissions
Ensure that Apache has read and executed permissions on your project directories. Run the following to give the necessary permissions and ownerships.
sudo chown -R www-data:www-data /home/ubuntu/djangoapp
sudo chown www-data:www-data db.sqlite3
sudo chmod -R 755 /home/ubuntu/djangoapp
sudo chmod 775 /home/ubuntu/djangoapp
sudo chmod 755 /home/ubuntu
sudo chmod 664 db.sqlite3 #If you are using the sqlite3 database.
#Restart apache to apply the changes
sudo systemctl reload apache2
At this stage, your web application should be accessible on http protocal, or through the IP. To secure your web application, proceed with other steps.
Step 6: Configure a database
You have several options when setting up a database for a Django application, including
- SQLite – default
- MySQL – How to Connect a Django Project to MySQL Database
- PostgreSQL – How to Connect a Django Application to PostgreSQL
- Docker container. – A Practical Tutorial for Dockerizing Software Applications
Each option meets different needs and situations. SQLite is lightweight and suitable for development or small applications. MySQL and PostgreSQL are compatible database management systems; While MySQL is known for its performance and scalability, PostgreSQL provides high performance and data integrity. Docker provides a container environment that allows you to package your applications and their dependencies, including libraries, to ensure consistency across environments. Choose the database option that best suits your project needs and integrates with your Django application.
Step 7: Install Let’s Encrypt SSL Certificate
If you configure your web application with a domain name, it’s highly recommended to secure it with SSL. There are options for premium SSL certificates as well as free SSL certificates. In this guide, we make use of Let’s Encrypt, which is a free SSL certificate. If you are to be accessing your web application on an IP, you do not need to configure SSL.
Before you begin the SSL installation, we need to disable WSGIDaemonProcess definition, otherwise, we will get duplicate related errors as this line will be duplicated to the SSL config file. Once the SSL is configured, we need to re-enable this.
sudo nano /etc/apache2/sites-enabled/djangoapp.conf #access the virtualhost config file. Access the line below and comment it out by adding #.:
WSGIDaemonProcess djangoapp python-home=/home/ubuntu/djangoapp/venv python-path=/home/ubuntu/djangoapp
#The updated should look like the following sample.
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName dtechnologies.co.ke
ServerAlias www.dtechnologies.co.ke
DocumentRoot /home/ubuntu/djangoapp
Alias /static /home/ubuntu/djangoapp/static
<Directory /home/ubuntu/djangoapp/static>
Require all granted
</Directory>
Alias /media /home/ubuntu/djangoapp/media
<Directory /home/ubuntu/djangoapp/media>
Require all granted
</Directory>
<Directory /home/ubuntu/djangoapp>
Require all granted
</Directory>
<Directory /home/ubuntu/djangoapp/companyweb>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
# WSGIDaemonProcess djangoapp python-home=/home/ubuntu/djangoapp/venv python-path=/home/ubuntu/djangoapp
WSGIProcessGroup djangoapp
WSGIScriptAlias / /home/ubuntu/djangoapp/companyweb/wsgi.py
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Once the WSGIDaemonProcess definition has been commented out, now proceed and update proceed with the SSL certificate installation. Note that at this stage, the website may not be reachable as the virtual environment is not defined.
- Install Certbot
Install the necessary modules using the commands below.
sudo apt install certbot python3-certbot-apache
- Obtain and install the SSL certificate
To install ssl for my specific domain name, do the following. Replace that with your domain name.
sudo certbot --apache -d dtechnologies.co.ke -d www.dtechnologies.co.ke
Follow the prompts to install the SSL certificate. Once installed, a new virtual host file will be created, containing the SSL certificate configurations. The process does the SSL certificate configurations required, including forcing a HTTPS redirect. Inspect the newly created file, open it, and enable the WSGIDaemonProcess definition by removing the # tag. See sample code. To achieve this, inspect the virtual host files to identify the newly added file.
sudo ls /etc/apache2/sites-enabled/ #note the new file, and open it as illustrated below.
sudo nano /etc/apache2/sites-enabled/djangoapp-le-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName dtechnologies.co.ke
ServerAlias www.dtechnologies.co.ke
DocumentRoot /home/ubuntu/djangoapp
Alias /static /home/ubuntu/djangoapp/static
<Directory /home/ubuntu/djangoapp/static>
Require all granted
</Directory>
Alias /media /home/ubuntu/djangoapp/media
<Directory /home/ubuntu/djangoapp/media>
Require all granted
</Directory>
<Directory /home/ubuntu/djangoapp>
Require all granted
</Directory>
<Directory /home/ubuntu/djangoapp/companyweb>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess djangoapp python-home=/home/ubuntu/djangoapp/venv python-path=/home/ubuntu/djangoapp #activate this line by removing the # we had added
WSGIProcessGroup djangoapp
WSGIScriptAlias / /home/ubuntu/djangoapp/companyweb/wsgi.py
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/dtechnologies.co.ke/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/dtechnologies.co.ke/privkey.pem
</VirtualHost>
</IfModule>
sudo systemctl reload apache2 #restart apache for the new changes to take effect
Common errors during deployment
Permission related errors when:
1. Installing dependancies using pip
2. Running the collectstatic command
Solution for permission related errors: Change file/folder ownerships using the following.
sudo chown -R $USER:$USER /home/ubuntu/djangoapp
sudo chmod -R 755 /home/ubuntu/djangoapp
sudo systemctl reload apache2
Once resolved, refer to step Number 5 to restore the permissions and ownerships and recommended.
3. Admin dashboard static files not working. - copy the admin static files from assets folder to the static folder- Ensure you have run collectstatic command.
From the root directory: cp -r assets/admin/ static/
sudo systemctl reload apache2
In case of errors, inspect the logs by running the following command:
sudo tail -f /var/log/apache2/error.log
Make a donation to support us
Web Hosting and email hosting Packages
Related Content:
- A Practical Tutorial for Dockerizing Software Applications
- How to Connect a Django Project to MySQL Database
- How to Connect a Django Application to PostgreSQL
- How to deploy a Django application on Cpanel
- Deploy a Django Application on EC2 Instance with Nginx
- How to Configure a Docker App to a Domain Name