Administration Guide

While Turkle can run out of the box using the Django development web server and a SQLite database, we recommend using a scalable database and a production quality WSGI HTTP server. This guide describes the steps of running a production Turkle site.

Topics:

  • Web server
  • Database
  • Cron
  • Email

Configuration changes should be made by creating a turkle_site/local_settings.py file. Configuration changes in this file override the default configuration settings in turkle_site/settings.py. The file turkle_site/example_local_settings.py contains some examples of how to customize local settings.

Production Webserver Configuration

Configuring Static Files

In a production environment, static files should be served by a web server and not by a Django web application. In turkle_site/local_settings.py, you will need to set the STATIC_ROOT directory to the location where you want to store the static files, e.g.:

STATIC_ROOT = "/var/www/example.com/static/"

You should then run the collectstatic management command:

$ python manage.py collectstatic

which will copy all static files for Turkle into the STATIC_ROOT directory.

The Django static files HOWTO provides more details about how Django handles static files in production environments.

Running with Gunicorn

Gunicorn is a Python WSGI HTTP server that can be installed with pip:

pip install gunicorn

Gunicorn can be run from Turkle’s base directory using:

gunicorn --bind 0.0.0.0:8000 turkle_site.wsgi

Common Gunicorn runtime options are available in the Running Gunicorn documentation.

The Gunicorn command above serves Turkle’s web pages on port 8000 but not the static files like CSS and JavaScript. For serious production uses of Turkle, the best option is to use a proxy server (like Apache or nginx) to serve the static files. More details on that below.

If you don’t want to set up a proxy server, you can use Whitenoise to serve the static files. Install it using:

pip install whitenoise

and then enable Whitenoise in turkle_site/local_settings.py by adding the appropriate string to the MIDDLEWARE list:

MIDDLEWARE = (
    'whitenoise.middleware.WhiteNoiseMiddleware',
) + MIDDLEWARE

Note that you need to follow the previous instructions on configuring STATIC_ROOT before running with whitenoise.

Apache as a reverse proxy

To use Apache as the proxy server, enable proxying: a2enmod proxy_http. Then edit the configuration of your site to include the proxy information:

ProxyRequests Off
ProxyPass /static/ !
ProxyPass / http://localhost:5000/
ProxyPassReverse / http://localhost:5000/

Apache will look in its default location for the static directory so you’ll need to create a symbolic link (more convenient) or copy the files (safer). After starting Gunicorn and restarting Apache with the new configuration, you should be able to view the site at http://localhost/ or whatever the appropriate host name is.

Instructions for using Gunicorn with nginx are found on its deploy page. You will still need to configure nginx to serve the static files as we did with Apache.

Emails behind proxy

If your site has been configured for emails, the emails for password resets will use the localhost URL rather than the external URL. To configure this, set this variable in the local_settings.py file:

USE_X_FORWARDED_HOST = True

This will cause Django to pick up the HTTP_X_FORWARDED_HOST header when populating the protocol, domain, and site_name for the emails.

Production Database Configuration

MySQL

First, you need to install the Python mysqlclient library:

pip install mysqlclient

Note that this requires development headers for MySQL and Python to be installed. The method for installing these depends on your operating system.

Second, create a database and database user for Turkle. In the examples below, we are calling the database turkle and the user turkleuser with the password password. Log into the MySQL client and run the following commands:

CREATE DATABASE turkle CHARACTER SET UTF8;
CREATE USER turkleuser@localhost IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON turkle.* TO turkleuser@localhost;
FLUSH PRIVILEGES;

Third, update Turkle’s settings to point at this database:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'turkle',
        'USER': 'turkleuser',
        'PASSWORD': 'password',
        'HOST': 'localhost'
    }
}

The last step is running the Turkle install steps (migrate and createsuperuser).

PostgreSQL

First, you need to install the Python PostgreSQL adapter:

pip install psycopg2

Note that this requires development headers for PostgreSQL and Python to be installed. The method for installing these depends on your operating system.

Second, create a database and database user for Turkle. In the examples below, we are calling the database turkle and the user turkleuser with the password password. Log into the psql client and run the following commands:

CREATE DATABASE turkle;
CREATE USER turkleuser WITH PASSWORD 'password';
ALTER ROLE turkleuser SET client_encoding TO 'utf8';
GRANT ALL PRIVILEGES ON DATABASE turkle TO turkleuser;

Third, update Turkle’s settings to point at this database:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'turkle',
        'USER': 'turkleuser',
        'PASSWORD': 'password',
        'HOST': 'localhost'
    }
}

The last step is running the Turkle install steps (migrate and createsuperuser) described in the “One-time Configuration Steps” section above.

Database Backups

You will likely want to add a cron job that dumps the database each hour or day using the dump command for your database:

@hourly /path/to/my/script.sh

Cron

Task Assignments have expiration dates. The expired assignments are deleted when the expire_assignments command is run. This can be done manually through the administration pages or by running the command:

python manage.py expire_assignments

For production sites, we recommend that you configure a cron job to delete assignments regularly. The docker-config/ directory contains a turkle.crontab file that can be used to periodically run the script using cron. The method for configuring a cron job depends on your operating system.

The Turkle Docker containers are configured to use cron to automatically delete expired Task Assignments.

Email Configuration

Turkle can send password reset emails if your server is configured to deliver emails. By default, the links to the password reset page are hidden. To enable, edit the turkle_site/local_settings.py file and set the variable TURKLE_EMAIL_ENABLED to True. You will need to add a section to turkle_site/local_settings.py for configuring a Mail Transfer Agent (MTA). The turkle_site/example_local_settings.py file contains a (commented out) section with sample settings for configuring an MTA with Django. For more details about configuring an MTA, consult the Django docs.

Logging Configuration

Before running Turkle in a production environment, logging must be configured in the turkle_site/local_settings.py file. There is a sample logging configuration in the turkle_site/example_local_settings.py file if an administrator wants to receive emails if HTTP 500 errors occur.