| | | | |

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

Overview

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
django-server

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:

127.0.0.1 localhost
100.24.236.230  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.
home/
– 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.
ALLOWED_HOSTS = [‘100.24.236.230’]

Create a STATIC_ROOT and MEDIA_ROOT variables.
MEDIA_ROOT = BASE_DIR / ‘media’
STATIC_ROOT = BASE_DIR / ‘static’

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 0.0.0.0:8000 at the end of the command.

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

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


Security


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
	</Directory>

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

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

	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 

</VirtualHost>

# 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

Permissions

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