Handle your processes with supervisord -- a process control system

The Supervisord system is providing easy methods to control your processes. However if you are using some modern linux distribution (like Ubuntu 16.10 or CentOS 7) maybe the better way for you will be using the Systemd.

Overview

This article is shows how to install and configure supervisord for manage your applications and workers.

Supervisord is provide managment apportunity for create and control yours apps. All manipulations I will make on CentOS 6.7 with base and epel repos.

Installation

At the time of article writing in package supervisor-2.1-9.el6 had a bug with unix socket opening so I show how to install it from pip.
Lets install pip first and supervisord then.

Install pip

yum install python-setuptools  
easy_install pip  

The supervisord package from pip is conflict with mild pip package so we should delete it and re-install with yum.

pip uninstall meld3  
yum install python-meld3.x86_64  

Now we can install and make base configuration for supervisord.

Install and configure supervisord

pip install supervisor  
cat << EOF > /etc/supervisord.conf  
[unix_http_server]
file=/var/tmp/supervisor.sock  
chmod=0700  
chown=root:root  
[supervisord]
logfile=/var/log/supervisor/supervisord.log  
logfile_maxbytes=0  
logfile_backups=0  
loglevel=debug  
pidfile=/var/run/supervisord.pid  
nodaemon=false  
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface  
[supervisorctl]
serverurl=unix:///var/tmp/supervisor.sock  
[include]
files = /etc/supervisord.d/*.conf  
EOF  
Init script

Besides I need to create init script for supervisord because pip does not provide it. I've used default init script from supervisord package from CentOS repos (do not forget save all copyrights).

cat << EOF > /etc/init.d/supervisord  
#!/bin/bash
#
# supervisord This scripts turns supervisord on
#
# Author: Mike McGrath <mmcgrath@redhat.com> (based off yumupdatesd)
#
# chkconfig: - 95 04
#
# description: supervisor is a process control utility. It has a web based
# xmlrpc interface as well as a few other nifty features.
# processname: supervisord
# config: /etc/supervisord.conf
# pidfile: /var/run/supervisord.pid
#

# source function library
. /etc/rc.d/init.d/functions

RETVAL=0

start() {  
  echo -n $"Starting supervisord: "
  daemon supervisord
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && touch /var/lock/subsys/supervisord
}

stop() {  
  echo -n $"Stopping supervisord: "
  killproc supervisord
  echo
  [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/supervisord
}

restart() {  
  stop
  start
}

case "$1" in  
  start)
    start
  ;;
  stop) 
    stop
  ;;
  restart|force-reload|reload)
    restart
  ;;
  condrestart)
    [ -f /var/lock/subsys/supervisord ] && restart
  ;;
  status)
    status supervisord
    RETVAL=$?
  ;;
  *)
    echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"
    exit 1
esac

exit $RETVAL  
EOF  
Enable supervisord service

Also we need to configure supervisord service start-on-boot and start it.

chkconfig --add supervisord  
chkconfig supervisord on  
service supervisord start  

Configuration

The Supervisord is now configured and running, we just need to create some workers.

Worker configuration

I'm strongly not recommend to run any of your application from root -- create some new user account for this purpose.

[[ ! -d /etc/supervisord.d ]] && mkdir /etc/supervisord.d
cat << EOF > /etc/supervisord.d/myapp.conf  
[program:myapp-web-app]
command=/usr/bin/python /var/www/example.com/run.py  
numprocs=1  
user=myapp_user  
stdout_logfile=/var/log/supervisor/myapp-web-app/stdout.log  
stderr_logfile=/var/log/supervisor/myapp-web-app/stderr.log  
stdout_logfile_backups=0  
stderr_logfile_backups=0  
stdout_logfile_maxbytes=0  
stderr_logfile_maxbytes=0  
autostart=true  
autorestart=true  
startsecs=3  
startretries=3  
stopwaitsecs=120  
exitcodes=0  
EOF  
useradd -d /var/www/example.com -M -s /sbin/nologin myapp_user  
mkdir /var/log/supervisor/myapp-web-app  
supervisorctl update  
supervisorctl start myapp-web-app  

Configure process group

Also you can configure process group -- it means that you can start several similarly processes as one worker.

For example:

cat << EOF > /etc/supervisord.d/myapp.conf  
[program:myapp-web-app]
command=/usr/bin/python /var/www/example.com/run.py  
numprocs=10  
user=myapp_user  
stdout_logfile=/var/log/supervisor/myapp-web-app/stdout.log  
stderr_logfile=/var/log/supervisor/myapp-web-app/stderr.log  
stdout_logfile_backups=0  
stderr_logfile_backups=0  
stdout_logfile_maxbytes=0  
stderr_logfile_maxbytes=0  
autostart=true  
autorestart=true  
startsecs=3  
startretries=3  
stopwaitsecs=120  
exitcodes=0  
EOF  
supervisorctl update  
# start process group
supervisorctl start myapp-web-app:*  

Pride specific environment

You can set specific environment to yours workers process. For example my Node.JS installation located at /usr/local/node directory but my application is required node. Solution is provide a valid path to node binary with environment option.

cat << EOF > /etc/supervisord.d/myapp.conf  
[program:myapp-web-app]
command=/usr/bin/python /var/www/example.com/run.py  
numprocs=10  
user=myapp_user  
stdout_logfile=/var/log/supervisor/myapp-web-app/stdout.log  
stderr_logfile=/var/log/supervisor/myapp-web-app/stderr.log  
environment=PATH=/usr/local/node/bin:%(ENV_PATH)s;NODE_ENV=production  
stdout_logfile_backups=0  
stderr_logfile_backups=0  
stdout_logfile_maxbytes=0  
stderr_logfile_maxbytes=0  
autostart=true  
autorestart=true  
startsecs=3  
startretries=3  
stopwaitsecs=120  
exitcodes=0  
EOF  
supervisorctl update  
# start process group
supervisorctl start myapp-web-app:*  

Lets see a little close to environment line: its provide two variables -- PATH and NODE_ENV.

The first one is just usual PATH but with appending old PATH too via %(ENV_PATH)s options.

The second one is NODE_ENV -- just a node environment (e.g. production or test).

Summary

We have completed the installation and configuration of supervisord service also we configure example worker for it. You can add any numbers of workers and any number of processes per worker.