Installing Django in Raspbian

This is a guide to installing the following toolchain on a Raspberry Pi running Raspbian Jessie Lite:

  • Lastest version of Python (3.5.2 at time of writing)
  • Apache 2 (latest version packaged in Jessie)
  • PostgreSQL (latest version packaged in Jessie)
  • mod_wsgi (4.5.7 at time of writing)
  • Django (1.10 at time of writing)
  • Python virtual environment

It is intended as a guide to getting everything installed and configured, not as a tutorial in actually using Python, Django etc. The above toolchain is suitable for a fairly heavy duty production environment.

This guide assumes that you already understand how to code in Python and are comfortable with the command line and shell scripts. It also assumes you already know about Python virtual environments and pip. If not, a bit of reading would be recommended 😉

A summary of the steps:

  1. Build and install the latest version of Python
  2. Install Postgres
  3. Install Apache web server
  4. Build and install mod_wsgi
  5. Configure Apache to use mod_wsgi
  6. Configure Apache to serve your Django project
  7. Create a virtual environment for your Django project
  8. Start a Django project, ready for writing your project or following a tutorial

Build and install Python 3.5
The following shell script will build and install the latest version of Python for you (3.5.2 at time of writing):-

#!/bin/sh
RELEASE=3.5.2

# install dependencies
sudo apt-get install libbz2-dev liblzma-dev libsqlite3-dev libncurses5-dev libgdbm-dev zlib1g-dev libreadline-dev libssl-dev tk-dev

# download and build Python
mkdir ~/python3
cd ~/python3
wget https://www.python.org/ftp/python/$RELEASE/Python-$RELEASE.tar.xz
tar xvf Python-$RELEASE.tar.xz
cd Python-$RELEASE
./configure
make
sudo make install
sudo rm -rf ~/python3/Python-$RELEASE
cd ~

Install PostgreSQL DBMS
For this tutorial, we are using the PostgreSQL DBMS. You could quite happily use MySQL or SQLite instead if you prefer.

sudo apt-get install postgresql postgresql-server-dev-all

Install Apache web server

sudo apt-get install apache2 apache2-dev

Install mod_wsgi
Mod_wsgi is an apache module that enables the use of Python’s WSGI (web server gateway interface). In other words it lets you run Python scripts under Apache web server.

The following shell script will build and install mod_wsgi that uses the latest version of Python that you have just installed:-

RELEASE=4.5.7
wget https://github.com/GrahamDumpleton/mod_wsgi/archive/$RELEASE.tar.gz
mv $RELEASE.tar.gz mod_wsgi-$RELEASE.tar.gz
tar xvfz mod_wsgi-$RELEASE.tar.gz
cd mod_wsgi-$RELEASE
./configure --with-python=/usr/local/bin/python3
make
sudo make install
cd ..
rm -rf mod_wsgi-$RELEASE

Configure Apache to use mod_wsgi
The following shell script will add the configuration and restart Apache:-

sudo cat > /etc/apache2/mods-available/mod_wsgi.load << EOF
LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so
EOF
sudo a2enmod mod_wsgi
sudo service apache2 stop
sudo service apache2 start

Configure Apache to serve your Django project
Here we assume your Django project is called ‘mysite’ and runs on the server ‘yourhost.yourdomain’. Substitute these values with more suitable values to match your project.

Create the file /etc/apache2/sites-available/mysite.conf :-

<VirtualHost *:80>
   ServerName yourhost.yourdomain
   DocumentRoot "/var/www/mysite"
   CustomLog /var/log/apache2/mysite_access.log combined
   ErrorLog /var/log/apache2/mysite_error.log

   alias /static/ /var/www/mysite/static/
   alias /media/ /var/www/mysite/media/
   alias /favicon.ico /var/www/mysite/static/favicon.ico
   alias /robots.txt /var/www/mysite/static/robots.txt
   WSGIScriptAlias / /var/www/mysite/myproject/wsgi.py

   WSGIDaemonProcess yourhost.yourdomain python-path=/var/www/mysite:/var/www/mysite/mysite:/var/www/mysite/env/lib/python3.5/site-packages
   WSGIProcessGroup yourhost.yourdomain
</VirtualHost>

Enable it with the command:

sudo a2ensite mysite
sudo service apache2 reload

Make sure there is an entry for yourhost.yourdomain in /etc/hosts
This makes sure that things still work if the DNS stops working for whatever reason. It is also faster than DNS lookups. If you are running behind a NAT router, make sure you enter your internal IP address here, not your external IP address.

sudo nano /etc/hosts

Create a directory to hold your project
Here, we create the directory under /var/www where websites normally live. The file permissions must allow suitable access by the apache user as well as write access by yourself.

sudo mkdir /var/www/mysite
sudo chown myuser:mygroup /var/www/mysite
ln -s /var/www/mysite ~/mysite

Create a virtual environment containing your Django project
Python Virtual environments are a Good Thing (TM). They allow you to control the dependencies of your project in an independent manner from any other projects you have installed. This way, you can allow different versions of Django and other Python modules for each project. If you have a device-wide installation of Python modules, it could break some of your sites when your do an upgrade command!

cd ~/mysite
pyvenv-3.5 env

Switch to your virtual environment and upgrade pip:

. env/bin/activate
pip install --upgrade pip

From this point onwards, we assume everything you do is within this virtual environment.


Create a basic requirements.txt file containing a list of the Python modules used by your Django project:

Django==1.10.*
psycopg2~=2.6

Install these Python modules in your virtual environment:

pip install -r requirements.txt

Create a Postgres user and database for your project
Note that the following shell script will delete your database and database user if it already exists! It is a good idea to have a separate user for each individual project – this way if your website is compromised, it can only affect one project.

#!/bin/sh
sudo -u postgres psql << EOF
drop database if exists mysite;
drop user if exists myuser;
create user myuser with password 'secr3t';
create database mysite with owner myuser;
EOF

Start a Django project

django-admin startproject myproject .
mkdir static

Edit the file myproject/settings.py and change the database settings to something along these lines:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mysite',
        'USER': 'myuser',
        'PASSWORD': 'secr3t',
        'HOST': 'localhost',
    }
}

Also add/change the following settings:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

If you now go to your web browser and load your site, you should get the initial Django ‘It Worked!’ page.

At this point, it is probably a good idea to put your Django project into a source code repository, such as git. This is outside the scope of this guide.

From this point onwards, you are on your own. You may want to follow one of the many Django tutorials that are around – Google is your friend 🙂

Here you go for starters:
https://docs.djangoproject.com/en/1.10/intro/tutorial01/