Service Management Using Supervisor

Mohammed AbuAisha
6 min readOct 15, 2020
Supervisor Process Management

As R&D Software Engineer at Cloudify.co I started to add support for running Cloudify services using Supervisor in order to run Cloudify using non-privilege containers for better security, providing light weight containers, alternative for SystemD and be more cloud native.

In this blog I’m going to focus on the following:

  1. What is Supervisor ?
  2. Supervisor Components.
  3. Supervisor Installation.
  4. Controlling Program using Supervisor.
  5. Controlling Supervisor using XML-RPC interface.

What is Supervisor ?

Supervisor is a client/server system that allows its users to control a number of processes on UNIX-like operating systems.

http://www.supervisord.org/introduction.html

Supervisor Logo
  1. Written entirely in Python.
  2. Simpler than rc & systemd.
  3. Easy to configure using INI-style config format.
  4. Easy to control processes using command line & web interface.
  5. Supervisor invokes subprocesses using fork/exec without demonizing them.
  6. Easy to extend and control using the exposed XML-RPC interface.
  7. Portable across UNIX-like environments Linux, Mac OS X, Solaris, and FreeBSD

Supervisor Components

As we mentioned before, Supervisor is a client/server system where mainly has the following components:

  1. supervisord: The server side that controls/manages processes
  2. supervisorctl: The client side that communicates with supervisord demon.
  3. Web Server: Simple web UI console similar to supervisorctl that can be accessed on http://localhost:9001/
  4. XML-RPC Interface: XMP-RPC interface served by the same web server of the web UI console which allows to integrate supervisor with other applications.

Supervisor Installation

In order to setup and install Supervisor, the following requirements must be met:

  1. UNIX-like Operating System (Linux, Mac OS X, Solaris, FreeBSD)
  2. Python 3 (3.4 or later) or Python 2 version 2.7.X

One of the most common ways to download & install Supervisor is to use pip (Python Package Installer) that helps to download it from pypi and install it on the system.

So let’s start and install Supervisor using pip.

  1. Create python virtualenv to install Supervisor inside it. I’m going to use venv command supported by python3

2. Running the above command, will generate a virtualenv on the current directory. Now its time to activate that env “supervisor-env

3. After the virtualenv get activated. Let’s install supervisor from pypi by running “pip install supervisor==4.2.1” as the latest version when writing this blog was 4.2.1

4. Validate that both supervisord & supervisorctl are installed by running help commands

Controlling Program using Supervisor

I created a simple “Hello World” web application using Flask framework running by Gunicorn HTTP server in order to control Web server using Supervisor.

The https://github.com/mabuaisha/supervisord-on-action contains python source code and Supervisor configuration required to run and control the Gunicorn process

The repository contains 4 main items:

  1. simple_app: This directory contains the Flask web app and wsgi module.
  2. app.conf: Represents the configuration file required to work with Supervisor and to control Gunicorn
  3. parse.py: Simple parser that communicate with supervisor over XML-RPC
  4. requirement.txt: Requirement file contains Python packages to install.

The focus here will be on the Supervisor configuration file where it is written as INI-style format and organized as sections.

  1. [supervisord] Section: Global settings related to the supervisord process contains configuration of logs, users, environment variables settings and much more. Full list of available settings are explained in details on supervisord doc section
  2. [supervisorctl] Section: The configuration related for the supervisorctl interactive shell program where it mainly contains basic configuration like (server url, username, password, ..etc) in order to communicate with supervisord process. More details about this section can be found on supervisorctl doc section
  3. [unix_http_server] Section: The configuration related for HTTP server that listens on a UNIX domain socket that contains basic configuration (file socket, username, password, ..etc). More details about this section are available on Unix HTTP server doc section
  4. [inet_http_server] Section: The configuration related for HTTP server that listens on a TCP (internet) socket that contains basic configuration like (port, username, password). More details about this section are available on INET HTTP server doc section
  5. [program:x] Section: This is configuration for the program that is going to be managed by Supervisor where X represents the name of that program where we can have multiple program sections on the configuration file. It mainly contains information related to the command need to be invoked, logs, environment variables and much more. More details about this section are available on Program doc section.

There are other sections available for Supervisor which I’m not going to cover on this blog.

Now back again to our “Hello World” Flask web app. In order to use that application and integrate it with Supervisor, do the following:

  1. Clone the repository git clone https://github.com/mabuaisha/supervisord-on-action.git
  2. Move supervisord-on-action to /opt
  3. Make sure that you are using the same virtualenv we used before supervisor-env
  4. Install required python packages for the app pip install -r requirement.tx

Everything is ready now to start running the supervisord process

We run the main process for supervisord by specifying the location of configuration file (app.conf) and from the logs we can see that the gunicorn program is running and start listening on port 5000.

On the other hand, we can use the supervisorctl command to query about the status of all services managed by supervisord where configuration file for supervisor is specified to the command

We can also control services using other actions supported by the client (restart, stop, start, ..etc)

So thats good so far, let’s move to the next part and interact with supervisor over XML-RPC calls.

Controlling Supervisor using XML-RPC interface

As part of the supervisord-on-action repository, I implemented a simple command line app which allows to communicate with supervisor to run simple actions (start/stop) services.

The snippet code illustrated below shows the built-in python packages (socket, xmlrpc, http, argparse) were used in order to accomplish this task.

This would be useful in case you have an application that consists of multiple services and you want to check the overall health status of your application and then expose the result over REST API endpoint.

To Recap, the main goal of this blog is to show the usage of supervisor with your application. All the shared code, configuration and the way we installed supervisor was for demo purposes and not recommended for production usage. On the next coming blog I’m going to talk about the usage of supervisor with Non-Privilege Container and Kubernetes deployment.

--

--

Mohammed AbuAisha

Software Development Engineer with +10 years experience, Python developer, interested in DevOps & Cloud Computing