Overview

We are running a number of things for the nightowl webserver.

As a main webserver we run Nginx. This receives and handles all the initial http(s) requests.

Nginx with fastcgi is used to handle php (with php5-fpm)

gunicorn in combination with virtualenv is used to handle python wsgi webapplications. Each application runs on it's own socket. Nginx delegates all the requests to those applications using a reverse proxy (the request comes in at nginx on port 80 or 443, but nginx sends it on to another port on the same machine (127.0.0.1) where gunicorn is listening).

circus is used to start the gunicorn apps, handle logging and restart them if necessary.

Webapplications we are running:

drupal with mysql for nightowl.foundationu.com

taiga (with gunicorn/circus behind nginx) and postgresql as database

rfid management application (with gunicorn/circus behind nginx) and mysql as database

Installing Circus

Install circus with 'pip install circus' (not inside a virtualenv). When running on a systemd linux distro (like debian and centos), create a systemd unit as documented on The circus website (forget about the upstart part, that is for ubuntu). But be sure to change /usr to /usr/local in the circus.service file (because we installed using pip). Make sure you create the /etc/circus/ folder.

For information on running (monitoring) gunicorn (python wsgi) applications with circus, see The gunicorn with circus docs and the taiga docs on circus.

Running a Flask application with circus and gunicorn

Create a virtualenv (probably somewhere in a virtualhost folder under /srv/www/vhosts/<yourappdomain>. Make sure you have gunicorn installed in your virtual env, and also all other dependencies for your flask app.

Add the following to /etc/circus/circus.ini making sure you change all references to your application (in the example in /srv/www/vhosts/rfid_test_nightowl_foundationu_com/inventory/) and virtualenv and it's python library folder (here /srv/www/vhosts/rfid_test_nightowl_foundationu_com/inventory/venv/ and /srv/www/vhosts/rfid_test_nightowl_foundationu_com/inventory/venv/lib/python3.4/ respectively).

Also make sure you change the name of the app (here rfid). Lastly make sure the port number (8001 in this case) is unique. Choose a unique port number (starting form 8001) for each application and change both the nginx and circus config accordingly.

[watcher:rfid]
working_dir = /srv/www/vhosts/rfid_test_nightowl_foundationu_com/inventory/
cmd = gunicorn
args = -b 127.0.0.1:8001 app
uid = www-data
numprocesses = 1
autostart = true
[env:rfid]
PATH = /srv/www/vhosts/rfid_test_nightowl_foundationu_com/inventory/venv/bin/:$PATH
TERM=rxvt-256color
SHELL=/bin/bash
USER=www-data
LANG=en_US.UTF-8
HOME= /srv/www/vhosts/rfid_test_nightowl_foundationu_com/
PYTHONPATH=/srv/www/vhosts/rfid_test_nightowl_foundationu_com/inventory/venv/lib/python3.4/site-packages:/srv/www/vhosts/rfid_test_nightowl_foundationu_com/inventory/

Setting up nginx to reverse-proxy a python wsgi (gunicorn) application

Follow the basic setup from Digital Ocean but instead of using “http://unix:” for the proxy pass directive, use http://127.0.0.1:<portnumber> as you configured in circus.ini.