| | | | |

How to deploy a Django App to a Linux Server – Part #1


This article will document the steps required for hosting a Python Django application on a Linux Server. I will be using Apache and mod-wsgi as our web server.
Additionally, I will be hosting the app on a Linux Ubuntu server.

SSH into your Linux instance.

It is always a good idea to update your system.

sudo apt-get update
sudo apt update

Set a Hostname:

ubuntu@ip-172-31-51-190:~$ sudo hostnamectl set-hostname django-server
ubuntu@ip-172-31-51-190:~$ hostname

Set the Hostname in the hostname in the host file:

ubuntu@ip-172-31-51-190:~$ sudo nano /etc/hosts

Change the file to include the new hostname: localhost  django-server

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Copy the Django Project files over to your /home/[user] directory.
Example. /home/ubuntu/django_project

Create a Python Virtual Environment in the django_project directory.

ubuntu@django-server:~$ sudo apt-get install python3-venv
ubuntu@django-server:~$ python3 -m venv /django_project/venv

Your file structure should look something like this.
– ubuntu/
– – django_project/
– – – venv
– – – manage.py
– – – …

Installing all pip requirements.
On your local / development machine, enable your venv.
Export the dependent libraries using the following command.

pip freeze > requirements.txt

Upload this requirements.txt file to your server, in the main project directory (same level as venv and manage.py)

Activate the Virtual Environment:

ubuntu@django-server:~$ cd django_project/
ubuntu@django-server:~/django_project$ source venv/bin/activate
(venv) ubuntu@django-server:~/django_project$

Now we can run pip to install the dependent packages from the requirements.txt file:

(venv) ubuntu@django-server:~/django_project$ sudo apt-get install python3-pip
(venv) ubuntu@django-server:~/django_project$ pip3 install -r requirements.txt

Configuring the Django Settings.py File:

(venv) ubuntu@django-server:~/django_project$ sudo nano django_project/settings.py

Add the public IP address of the server to ALLOWED_HOSTS.

Create a STATIC_ROOT and MEDIA_ROOT variables.

Execute the Collect Static command.
This step is required in the production environment.

(venv) ubuntu@django-server:~/django_project$ python3 manage.py collectstatic
133 static files copied to '/home/ubuntu/django_project/static'.

Testing our Django Application:
Running the Django server in production is similar to running it in the development environment – we only need to include at the end of the command.

(venv) ubuntu@django-server:~/django_project$ python3 manage.py runserver

You can now access your Django app using the public IP of your server on port 8000.


Ensure that you have allowed access through post 8000.
On AWS, I have the following inbound rules set on the security group.

If you are not using AWS, you can set your firewall rules by installing UFW.

sudo apt-get install ufw 
sudo ufw default allow outgoing
sudo ufw default deny incoming
sudo ufw allow ssh
sudo ufw allow http/tcp
sudo ufw allow 8000
sudo ufw enable

Setting up the Apache Web Server & WSGI

(venv) ubuntu@django-server:~$ sudo apt-get install apache2
(venv) ubuntu@django-server:~$ sudo apt-get install libapache2-mod-wsgi-py3

Edit the Apache configuration files:
Navigate to the sites-available directory and copy the default configuration file.

(venv) ubuntu@django-server:~$ cd /etc/apache2/sites-available/
(venv) ubuntu@django-server:/etc/apache2/sites-available$ sudo cp 000-default.conf django-project.conf
(venv) ubuntu@django-server:/etc/apache2/sites-available$ sudo nano django-project.conf
<VirtualHost *:80>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	#ServerName www.example.com

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf

	Alias /static /home/ubuntu/django_project/static
	<Directory /home/ubuntu/django_project/static>
		Require all granted

	Alias /media /home/ubuntu/django_project/media
	<Directory /home/ubuntu/django_project/media>
		Require all granted

	<Directory /home/ubuntu/django_project/django_project>
		<Files wsgi.py>
			Require all granted

	WSGIScriptAlias / /home/ubuntu/django_project/django_project/wsgi.py
	WSGIDaemonProcess django_app python-path=/home/ubuntu/django_project python-home=/home/ubuntu/django_project/venv
	WSGIProcessGroup django_app 


# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Enable the Apache site:

(venv) ubuntu@django-server:/etc/apache2/sites-available$ sudo a2ensite django-project.conf

Disable the default site configuration.

(venv) ubuntu@django-server:/etc/apache2/sites-available$ sudo a2dissite 000-default.conf


(venv) ubuntu@django-server:~$ sudo chown :www-data django_project/
(venv) ubuntu@django-server:~$ sudo chown :www-data django_project/db.sqlite3
(venv) ubuntu@django-server:~$ sudo chmod 664 django_project/db.sqlite3
(venv) ubuntu@django-server:~$ sudo chown -R :www-data django_project/media/
(venv) ubuntu@django-server:~$ sudo chmod -R 775 django_project/media
sudo service apache2 restart

Similar Posts

Leave a Reply

Your email address will not be published.