In the previous article of our guide we prepared our Raspberry Pi for remote management using ssh. We are going to continue explaining how to deploy a Django application using virtualenv to create an isolated environment, gunicorn as a web server, nginx as a reverse proxy, and supervisord for managing the gunicorn and application process.

Without further do, let’s get started.

Preparing the dependencies

First of all, we are going to create the user that will handle all our web services. We will call it web, assign it a good password and then we will install the tools that we are going to use to deploy and manage our applications.

As we disabled root access through ssh, we must start by logging into our Raspberry Pi using user the user we created:

ssh [user]@192.168.1.23

Next, we have to gain superuser privileges to add the new user and be able to install new packages:

suuseradd -m -g users -G wheel -s /bin/bash web
passwd web

Note that instead of using su, you can install and configure the sudo program to handle root access with unprivileged users.

Installing the virtual environment

Now we are going to install virtualenv. Using this tool we can create an isolated environment that will hold their own versions of different applications without polluting the rest of the system. This way, if we had a conflict with the last version of python or if we need some specific dependencies for one app or another, we can simply install it on our virtual environment.

To install virtualenv we can follow different procedures, but I recommend to install it via pacman. We will also install pip as a package manager for different python modules. Make sure that you install the version for python2 of all packages, as at the time of this writing Django still not work with python3+.

pacman -S python2 python2-virtualenv python2-pip

Once virtualenv is installed, we will log as our web user and create the virtual environment where we will put the application. I may suggest that you name the environment after the application, that way it would be way easier to find it.

virtualenv2 [path/name_of_our_environment]

When that’s done (it may take a while) we will enter the environment using the command source. When you are finished working in the virtual environment, be sure of deactivate it with the deactivate command.

source /path/to/our/environment/bin/activate

Now, we are going to install Django in this virtual environment using pip.

pip install django

If everthing worked, you should be able to start a django project while inside the virtualenv. You can test it by executing:

Then you can open your browser and enter your Raspberry Pi IP address followed by a colon and the port number in the navigation bar. For example, 192.168.1.23:8000. You should now see the ‘It worked!’ Django screen.

Installing gunicorn and making it work with nginx

For serving the application, we are going to use gunicorn. Gunicorn is a Python WSGI HTTP Server for UNIX, and it will ease the deployment of Django.

First, we must install it. From inside the virtualenv run the following command:

pip install gunicorn

Now you can test it running this command from the root of our Django app:

gunicorn_django --bind=0.0.0.0:8888

If you can access the ‘It worked!’ page in your browser, you should be ready to go. We would need further configuration to properly deploy it, but first, we are going to deactivate the virtualenv and install nginx:

deactivatesupacman -S nginx

We want nginx to serve as the reverse proxy of gunicorn, that is, it will serve as an intermediary, balancing the load and allowing us to have various web servers inside the same machine. We can configure it in the /etc/nginx/nginx.conf as follows:

Nevertheless, if we restart now our Raspberry Pi, nginx will autostart but we also need gunicorn online, and we also may want to add some additional parameters to the later, so first of all, we are going to create a shell script that will serve as a wrapper to start gunicorn from outside a virtualenv:

Supervisord

Supervisord is a handy tool to manage running processes. We will use it to execute our deploy.sh script at boot or stopping/restarting it whenever we want it. Install it with:

pacman -S supervisor

There is extensive documentation on the official page regarding the configuration of Supervisord, but for starters, you can start by creating a configuration file in /etc/supervisord.conf with the following content: