Think. Create. Reiterate

How to easily deploy a Wagtail website

Server setup

Please note that this tutorial targets deployment on Ubuntu servers. You can probably use most of the content of this tutorial on other systems as well, but the terminal commands here are written with ubuntu in mind.

The solution will be using Apache 2 as the web server with mod_wsgi to host the Python application. I will provide you with a template for an Apache VirtualHost configuration that takes for granted you have installed your Python packages in a virtual environment created by virtualenv.

Install Python and Apache

We will be working with Python 2.7 (The newest version of Wagtail is incompatible with Python 2.6).

$ sudo apt-get install build-essential python-setuptools python-dev apache2 wget

We will be using Apache 2 as our webserver. Next up, we have to figure out which kind of multiprocessing our Apache installation supports. This is done by looking at the value returned by:

$ dpkg -l|grep apache2

If this command returns apache2-mpm-worker you have to install apache2-threaded-dev  else if it returns apache2-mpm-prefork you need to install apache2-prefork-dev.

$ sudo apt-get install apache2-threaded-dev

Wagtail supports multiple image formats in its CRM backend. By installing the following libraries, the server will support JPEG, PNG and FreeType.

$ sudo apt-get install libjpeg-dev libfreetype6-dev zlib1g-dev libtiff-dev

Installing mod_wsgi

The following section will describe how to configure the Apache server. First, we need to install mod_wsgi. mod_wsgi is an Apache module which can host any type of Python application (that supports Python WSGI) and is maintained by Graham Dumpleton. 

Download a stable release from mod_wsgi's official Github repo and install the downloaded package.

$ wget
$ tar xzf mod_wsgi-4.4.21.tar.gz
$ cd mod_wsgi-4.4.21
$ ./configure
$ make
$ sudo make install

When mod_wsgi has been installed, we need to configure Apache to load the newly installed mod:

# Create the file wsgi.load:
$ sudo echo "LoadModule wsgi_module /usr/lib/apache2/modules/" > /etc/apache2/mods-available/wsgi.load
$ sudo a2enmod wsgi # enable the mod

Configuring the website

Next we have to tell Apache to load our Django/Wagtail website and stop serving its default Hello world webpage

$ cd /etc/apache2/sites-available
$ sudo a2dissite default  # stop serving the default page
$ sudo touch website.conf # our new website configuration

The new website.conf file will contain the Apache configuration. 

Apache configuration template

This is the default template I'm using in my projects. Note that this template requires you to specify a username. The given username should own the web process. In addition, you need to provide a project name by your own choosing.

<VirtualHost *:80>
      ServerName                # your domain name
      ServerAlias *
      Define project_name     some_project_name #
      Define user             the_username      # who owns the project? /home/the_username/..
      Define project_path     /... # Absolute path to the directory containing
      Define wsgi_path        /... # Absolute path to the directory containing
      Define environment_path /... # Absolute path to the virtual python environment
      WSGIDaemonProcess ${user}-${project_name} user=${user} group=${user} processes=1 threads=1 python-eggs=/tmp/python-eggs/ python-path=${project_path}:${environment_path}/lib/python2.7/site-packages
      WSGIProcessGroup ${user}-${project_name}

      WSGIScriptAlias / ${wsgi_path}/

      <Directory ${project_path}>
             Require all granted             

      Alias /static ${project_path}/static
      <Directory ${project_path}/static>
             Require all granted
             SetHandler None
             FileETag none
             Options FollowSymLinks

      Alias /media ${project_path}/media
      <Directory ${project_path}/media>
             Require all granted
             SetHandler None
             FileETag none
             Options FollowSymLinks
             ErrorDocument 404 /error404

      ErrorLog /var/log/apache2/${user}-${project_name}-error.log
      LogLevel info
      CustomLog /var/log/apache2/${user}-${project_name}-access.log combined

After you've specified the configurations and updated the content of the website.conf file:

$ sudo a2ensite website.conf
$ sudo service apache2 restart

Python PIP and Virtualenv

I advocate that you use virtual environments for your Python projects. In web development, when hosting multiple sites on a single server, each site should  definitively have its own virtual Python environment.

This is very easy to set up with PIP and Virtualenv.

$ sudo easy_install pip
$ sudo -H pip install virtualenv

When installing new Python modules or executing your scripts, activate the virtual environment in the console by:

$ virtualenv name_of_environment          # create an environment
$ source name_of_environment/bin/activate # The environment has been activated
$ pip install Wagtail                      # Install Python module into the virtual environment

Happy deployment!