Installing Django on a Raspberry Pi

This tutorial walks through the steps to install Django on a Raspberry pi. The Raspberry Pi I am using is running Occidentalis, which is a variant of Raspbian maintained by the people at adafruit. This tutorial should work exactly the same for Raspbian, as well as any other Debian derived flavor of linux.


Prerequisites

This tutorial begins with a freshly imaged Raspberry Pi with ssh enabled.

Update your system

$ sudo apt-get update
$ sudo apt-get upgrade

Install vim

$ sudo apt-get install vim

Download and run DjangoPi

DjangoPi is a project by a developer named phalt that is a script to install most of the things we need to get django running on the pi. All of this can be done manually, but phalt provides us with a big shortcut to getting up and running. The github page for the project is available here for reference.


$ git clone https://github.com/phalt/DjangoPi.git
$ cd DjangoPi
$ sudo ./setup.sh
$ sudo reboot

Start your Django Project

$ django-admin.py startproject project_name_here
$ cd project_name_here
$ python manage.py syncdb

The first time you run syncdb on a new django install, you have to setup and configure your auth system. Follow the prompts to create an admin user

Test your Django Server

Start up your django test server with the following command:

$ python manage.py runserver

Now that the server is running, switch to a new tty either by creating another ssh connection or pressing ctrl+f2 locally, install lynx, and verify that your django page is being served.

$ sudo apt-get install lynx
$ lynx http://127.0.0.1:8000

Kill the test server by pressing ctrl+c

Install and configure supervisor

$ sudo apt-get install supervisor
$ sudo vim /etc/supervisor/conf.d/gunicorn.conf

Add the following to the gunicorn.conf file, changing the paths for python and gunicorn to be where you installed them and test_project_name to be replaced by the name of your django project:

[program:gunicorn]
command = /home/pi/bin/python /home/pi/bin/gunicorn test_project_name.wsgi:application
directory = /home/pi/test_project_name
user = pi
autostart = true
autorestart = true
stdout_logfile = /var/log/supervisor/gunicorn.log
stderr_logfile = /var/log/supervisor/gunicorn_err.log

Save the file and quit vim. Restart supervisor to have it grab the changes

$ sudo supervisorctl reread
$ sudo supervisorctl update
$ sudo supervisorctl status

Setup the static and media directories

$ sudo mkdir /var/www /var/www/static /var/www/media
$ sudo chown -R pi:www-data /var/www

Add the static and media directories to django

$ vim settings.py

At the bottom of the file, add the following:

MEDIA_ROOT = '/var/www/media/'
MEDIA_URL = '/media/'
STATIC_ROOT = '/var/www/static/'
STATIC_URL = '/static/'

Install the static files for the admin

$ python manage.py collectstatic

Setup nginx

$ cd /etc/nginx/sites-available/
$ sudo vim test_project_name

Tell nginx that gunicorn is available as an upstream server at 127.0.0.1:8000

upstream gunicorn {
    server 127.0.0.1:8000;
}

# define an nginx server at port 80
server {
    # listen on port 80
    listen 80;

    # look in this directory for files to serve
    root /var/www/;

    # keep logs in these files
    access_log /var/log/nginx/django_project_name_access.log;
    error_log /var/log/nginx/django_project_name_error.log;

    client_max_body_size 0;

    # Attempt to serve files first, then pass the request up to Gunicorn
    try_files $uri @gunicorn;

    # define rules for gunicorn
    location @gunicorn {
        client_max_body_size 0;
        proxy_pass http://gunicorn;
        proxy_redirect off;
        proxy_read_timeout 5m;

        # make sure these HTTP headers are set properly
        proxy_set_header Host            $host;
        proxy_set_header X-Real-IP       $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Write the file and quit vim

$ cd /etc/nginx/sites-enabled
$ sudo ln -s ../sites-available/test_project_name
$ sudo rm default

Restart nginx for the changes to take effect

$ sudo service nginx restart

Test

You should now be able to hit the django web server running on your rapsberry pi from other computers on the network. Reboot, and make sure everything comes up as expected, and you're good to go