Django + Supervisor su Ubuntu server

Supervisor, Django e Gunicorn

Continuando ad interessarmi al mondo Django sono venuto a conoscenza di un interessante sistema da utilizzare nello stack per il deploy di un’app sviluppata con questo framework.

Sto parlando di Supervisor, un sistema client/server per il controllo di processi Unix. Inizialmente nel mio stack avevo utilizzato Upstart, il controllore di processi presente di default su Ubuntu, ma utilizzando la funzione respawn, ossia per ogni processo terminato ne viene lanciato un altro, il sistema si perde il riferimento con il processo lanciato e i comandi di stop non hanno più effetto. Sentendo parlare bene di Supervisor mi sono deciso a provarlo ed effettivamente funziona alla grande!!! E’ possibile conoscere lo stato di tutti i processi registrati in Supervisor oltre ai classici comandi di start, stop e restart dei vari processi attivi.

Supervisor è presente all’interno del repository dei pacchetti Ubuntu, quindi per installarlo è sufficiente il comando:

sudo apt-get install supervisor

Per il primo avvio è necessario digitare:

service supervisor restart

A questo punto possiamo aggiure un nuovo programma, che nel caso di applicazioni Django sarà lo script python per l’avvio di Gunicorn (il server wsgi per Django di cui ho già ampiamente parlato qui), vediamo un esempio:

command = '/opt/APP_VIRTUAL_ENV/bin/gunicorn'
pythonpath = '/SRC/APP/PATH/'
bind = '127.0.0.1:8000'
workers = 3
user = 'CUSTOM_USER'
pid = '/var/run/APP_NAME.pid'
accesslog = '/var/log/gunicorn/APP_NAME/access.log'
errorlog = '/var/log/gunicorn/APP_NAME/error.log'

Ovviamente questo è un mio esempio di script per il lancio di gunicorn relativo ad una app django, ma questo tipo di configurazione è valido per qualsiasi processo che si vuole controllare, basta specificare all’interno di “command” il comando che supervisor deve lanciare e controllare. Io sono solito mettere questo script in una cartella chiamata appunto “script” allo stesso livello dei sorgenti dell’app, ma può essere posizionato in qualunque punto del sistema. Sarà poi il file di configurazione del programma in supervisor a dover sapere dove recuperare lo script appena preparato.

Come dicevo, supervisor viene informato di un comando da lanciare mediante un file (un file per ogni comando) all’interno della cartella /etc/supervisor/conf.d/APP.conf contenente le seguenti linee:

[program:APP_NAME]
command=/opt/APP_VIRTUAL_ENV/bin/gunicorn APP_NAME.wsgi:application -c/SRC/APP/SCRIPT/PATH/gunicorn_config.py
autostart=true
autorestart=true
stderr_logfile=/var/log/gunicorn/APP_NAME/supervisor_stderr.log
stdout_logfile=/var/log/gunicorn/APP_NAME/supervisor_stdout.log

Non sto a spiegare nel dettaglio il significato della prima linea, che è il comando per avviare Gunicorn con la nostra app django tramite lo script precedentemente scritto, mentre la seconda e la terza linea dicono a Supervisor rispettivamente di avviare il comando all’avvio del sistema e di riavviare i processi che vengono terminati in modo non naturale. Le ultime due linee specificano i percorsi dei files di log di Supervisor.

A questo punto dobbiamo dire a Supervisor di leggere la nuova configurazione:

supervisorctl reread

Seguito dal comando per abilitare il nuovo programma:

supervisorctl update

Adesso la nostra app dovrebbe essere avviata!

Potete controllare lo stato di Supervisor con il semplice comando:

supervisorctl status

Per avviare, stoppare o riavviare i processi sono presenti i comandi:

supervisorctl start
supervisorctl stop
supervisorctl restart

Mentre per avviare la console interattiva di Supervisor è sufficiente digitare:

supervisorctl

Non vi resta che scrivere app (Django, Node, ROR o ciò che più preferite) e farne controllare i loro processi da Supervisor!