Deploying An Existing Django Application to AWS Ubuntu with Apache

by | October 5, 2019

Django is an excellent web framework that allows for excellent integration of geospatial data with other database functionality. The built-in development server is excellent during the development phase and is exceptionally easy to configure, but cannot handle concurrent connections and therefore cannot be used in a production environment.

Apache is one of the most commonly used HTTP servers and is available for almost any web server platform you could imagine. However, to get it running properly with a Django application requires a bit of configuration.

Environment

  • Ubuntu Server 18.04 (In this case, installed on an Amazon Lightsail instance but this is not important)
  • Python 3.6
  • Django 2.2.6.0
  • Apache 2.4

Copying Django Project to AWS

You can skip this section if you are using a different web host.

Configure FTP access with Filezilla

The best way to upload files to your AWS server is to use an FTP client. There are numerous different FTP clients but you will have to use an SSH key pair to configure them properly.

To download the private SSH key (*.pem) file you will need to go to your AWS Lightsail account page and create a new SSH key or download the default one.

Once you have downloaded your SSH key to a safe location on your computer open Filezlla and go the the “Site Manager” and create a new site.

You will need to set the protocol to SFTP and the host is your AWS public IP.

Change the logon type to “Key File”. AWS uses a default username of ubuntu for Lightsail instances running Ubuntu server.

Select the keyfile and click “Connect”.

Uploading to your Ubuntu Server

Once you have connected you will see the root folder structure of your Ubuntu installation in the Filezilla application.

Since the owner of all the folders in this root directory are limited to the root user, you will have to allow remote connections (temporarily) to upload data to a folder. This tutorial will use the \data\ folder for our Django application.

Launch the terminal for your Lightsail installation either using an SSH client or by using the built-in terminal in the AWS dashboard.

Change directories to the root by typing:

cd /

Then use the ls command to see the root folder structure.

To change the permissions on a folder use:

chmod  777 /yourfolder

This will allow you to upload to that folder in Filezilla

Once this is done, just copy and paste your entire Django project folder into the desired place on your server in Filezilla.

Preparing your system

Ensure you have Python 3.6 (or your preferred version of Python 3) installed on your server with the appropriate pip package. To install Python 3.6 type:

sudo apt install python3

You will also need to install pip, apache2 and in the case of Django mod_wgsi. You can do so in one fell swoop by using the command:

sudo apt install python3-pip apache2 libapache2-mod-wsgi-py3

Configuring a virtual environment

It is good practice to use virtual environments with Python projects to prevent conflicts between packages and to keep the base interpreter from getting corrupted.

First you must install the virtualenv package for Python3 by typing:

sudo pip3 install virtualenv

Navigate to the folder where you have saved your Django files and create a virtual environment folder inside this folder by typing:

virtualenv yourprojectenv 

 

Where you can replace “yourprojectenv” with whatever name you wish, in this case the name “myprojectenv” was used.

Activate this environment using:

source yourprojectenv/bin/activate

 

The name of the virtual environment will show up before the user string on the terminal line in parentheses (myprojectenv) to indicate you have activated the environment.

Installing required packages inside your virtual environment

When you create a virtual environment you are creating a blank Python environment inside that folder. This does not inherit any packages or modules installed in the primary Python interpreter with the exception of PIP.

At the very minimum a Django project requires the Django module to be installed. However, as projects get more complex it is necessary to keep track of all the different dependencies your project requires so you can install them in your virtualenv.

With the virtual environment active use PIP to install any dependencies your project requires.

Keep in mind that within the virtual environment you must use the python and pip commands and not the python3 and pip3 commands even if you are running a Python 3.x installation.

Leave the virtualenv running.

Preparing your project

Migrations

Assuming you are still in the virtual environment and you are in the project root you will need to run makemigrations and migrate on your Django project

If this is the first time you run this you will see that new migrations are in fact made and applied unlike the example above where I ran this previously.

Static Files

You will also need to collect the static files by running manage.py collectstatic.

This moves your static files into the appropriate static folder on the server.

Testing your application with the built-in development server.

Configuring AWS to allow external connections to port 8000

In order for the development server to be accessed externally port 8000 must be opened for your AWS instance. To do this, click on the three dots beside your Lightsail instance and select “Manage”.

Then select the “Networking” tab and add a new firewall passthrough for TCP port 8000.

Changing the settings to allow for your server to run on a different IP or domain name.

In order for Django to connect it must be allowed to operate from your AWS public ip address or the domain name you have pointing to it. To do this use the Nano text editor to make the following changes to your settings.py file.

sudo nano settings.py

Under the ALLOWED_HOSTS add whatever addresses you need to the list.

Use Ctrl+X to close the settings file and save when it asks using the same file name.

Running the dev server

Finally we can test that the application works by using the runserver command and telling it to run on 0.0.0.0:8000 to indicate that this will be accessible externally.

python manage.py runserver 0.0.0.0:8000

Once the server is running you should be able to access the site by typing in the server IP address with port 8000 behind it.

Eg. gasportal.silverspringenergy.com:8000

If it is running, great! Shut down the dev server by using ctrl+C and then deactivate the virtualenv by simply typing

deactivate

Configuring Apache

We must first configure the virtual host file to pass the client connections to the Django project in the appropriate format. This is where the mod_wsgi module comes into play and is honestly the most confusing part of this process.

If you have installed Apache using the method outlined at the beginning of this tutorial you can simply type

sudo nano /etc/apache2/sites-available/000-default.conf

Between the <Virtualhost> and </Virtualhost> tags you need to add the following to your conf file:

Alias /static /djangoprojectrootfolder/pathtostaticfolder

<Directory /djangoprojectrootfolder/pathtostaticfolder>

Require all granted
</Directory>

<Directory /djangoprojectrootfolder/folderwherewsgiexists>

<Files wsgi.py>

Require all granted
</Files>

</Directory>

WSGIDaemonProcess arbitrary_name_of_project python-home=/pathtoprojectvirtualenv/ python-path=/djangoprojectrootfolder
WSGIProcessGroup arbitrary_name_of_project
WSGIScriptAlias / /djangoprojectrootfolder/folderwherewsgiexists/wsgi.py

Where:

djangoprojectrootfolder == the folder where your Django project root is

pathtostaticfolder == the folder where your static folder is

folderwherewsgiexists == the folder where wsgi.py exists

arbitrary_name_of_project == the name you want your project to have in this Apache configuration

Optional config for if you have used a non-standard folder as I have

Use Nano to edit the apache2.conf file

sudo nano /etc/apache2/apache2.conf

add the following to the bottom of the file just before all the commented lines:

<Directory /djangoprojectrootfolder>

Require all granted

</Directory>

Not doing this will result in the default apache config page launching even after you have run your server.

Setting permissions and getting started

If using an sqlite based web application

Change the access permissions of the project db.sqlite3 file to 664

chmod 664 /djangoproject/db.sqlite3

and change its ownership to the Apache group (www-data)

sudo chown :www-data /djangoproject/db.sqlite3

Setting folder ownership

You will also need to grant www-data ownership of your project folder and any folder where you have user uploads or other files being created by Django.

sudo chown :www-data /djangoproject

sudo chown :www-data /uploadfolder

Restarting the Apache service

Finally we restart the Apache service and you should be able to see your site by going to its address!

sudo service apache2 restart 

All done. Enjoy your site!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.