Supervisor (Linux)#

supervisor is a process control system for Linux, which allows you to monitor and control a number of processes on UNIX-like operating systems. It is particularly useful for managing processes that need to be running continuously, and for monitoring and controlling processes that are running in the background.

Use When#

supervisor is ideal for managing Python web applications that need continuous uptime and robust process control. It’s particularly useful when you need extensive process management, monitoring, log management, and customized control over the start, stop, and restart of application processes.

For detailed understanding and further information, refer to the official Supervisor documentation.

Alternatives#

For different deployment scenarios, consider these alternatives:

  • Docker:

    Ideal for containerized environments, offering isolation and scalability.

  • NGINX Unit:

    A dynamic web and application server, suitable for running and managing multiple applications.

  • systemd:

    A system and service manager, integrated into many Linux distributions for managing system processes.

    Note

    Official documentation coming soon

  • Manually with an ASGI server:

    Direct control by running the application with an ASGI server like Uvicorn, Hypercorn, Daphne, etc.

This resource provides comprehensive guidance on installation, configuration, and usage of supervisor for service management.

Setup#

supervisor uses a config file for defining services. You can read more about the config file in the Supervisor configuration documentation.

Example supervisor config file#
[program:exampleapp]  # Defines the service name.
directory=/opt/exampleapp/src  # Specifies the directory where the service should run.
command=/opt/exampleapp/venv/bin/litestar app.py  # Specifies the command to run the service.
redirect_stderr=true  # Redirects stderr to stdout.
stdout_logfile=/var/log/exampleapp.log  # Specifies the log file to write to.
stdout_logfile_backups=10  # Specifies the number of backups to keep.
autostart=true  # Specifies that the service should start automatically when ``supervisor`` starts.
autorestart=true  # Specifies that the service should restart automatically if it exits unexpectedly.

You can place the above config file in /etc/supervisor/conf.d/exampleapp.conf. After you have created the config file, you will need to reload the supervisor config to load your new service file.

Helpful Commands
Reload supervisor config#
sudo supervisorctl reread
sudo supervisorctl update
Start/Stop/Restart/Status#
sudo supervisorctl start exampleapp
sudo supervisorctl stop exampleapp
sudo supervisorctl restart exampleapp
sudo supervisorctl status exampleapp
View logs#
sudo supervisorctl tail -f exampleapp

Now you are ready to start your application.

  1. Start the service if it’s not already running: sudo supervisorctl start exampleapp.

  2. Ensure it’s operating correctly by checking the output for errors: sudo supervisorctl status exampleapp.

  3. Once confirmed, your Litestar application should be accessible (By default at http://0.0.0.0:8000).

After that, you are done! You can now use supervisor to manage your application. The following sections were written to provide suggestions for making things easier to manage and they are not required.

Suggestions#

Tip

This follows onto the setup above, but provides some suggestions for making things easier to manage.

Aliases#

Create an alias file: /etc/profile.d/exampleapp.sh.

This is where the magic happens to let us simply use exampleapp start instead of sudo supervisorctl start exampleapp.

Alias Examples
Example commands provided by the alias file#
exampleapp start
exampleapp stop
exampleapp restart
exampleapp status
exampleapp watch
Example alias file#
 1exampleapp() {
 2  case $1 in
 3    start)
 4      echo "Starting exampleapp..."
 5      sudo supervisorctl start exampleapp
 6      ;;
 7
 8    stop)
 9      echo "Stopping exampleapp..."
10      sudo supervisorctl stop exampleapp
11      ;;
12
13    restart)
14      echo "Restarting exampleapp..."
15      sudo supervisorctl restart exampleapp
16      ;;
17
18    status)
19      echo "Checking status of exampleapp..."
20      sudo supervisorctl status exampleapp
21      ;;
22
23    watch)
24      echo "Tailing logs for exampleapp..."
25      sudo supervisorctl tail -f exampleapp
26      ;;
27
28    help)
29      cat << EOF
30      Available options:
31        exampleapp start    - Start the exampleapp service
32        exampleapp stop     - Stop the exampleapp service
33        exampleapp restart  - Restart the exampleapp service
34        exampleapp status   - Check the status of the exampleapp service
35        exampleapp watch    - Tail the logs for the exampleapp service
36      EOF
37      ;;
38
39    *)
40      echo "Unknown command: $1"
41      echo "Use 'exampleapp help' for a list of available commands."
42      ;;
43  esac
44}

To activate the alias without restarting your session use source /etc/profile.d/exampleapp.sh. Using the watch command lets you monitor the realtime output of your application.

Update Script#

The exampleapp function can be extended to include an update command, facilitating the complete update process of the application:

Update Script Example
Example update command#
 1exampleapp() {
 2  case $1 in
 3    # ... other cases ... #
 4
 5    update)
 6      echo "Updating exampleapp..."
 7
 8      # Stop the service
 9      echo " > Stopping service..."
10      sudo supervisorctl stop exampleapp
11
12      # Update application files
13      echo " > Pulling latest changes from repository..."
14      cd /opt/exampleapp
15      git fetch --all
16      git reset --hard origin/master
17
18      # Update Supervisor configuration and alias
19      echo " > Updating Supervisor and shell configurations..."
20      sudo ln -sf /opt/exampleapp/server/service.conf /etc/supervisor/conf.d/exampleapp.conf
21      sudo ln -sf /opt/exampleapp/server/alias.sh /etc/profile.d/exampleapp.sh
22      source /etc/profile.d/exampleapp.sh
23
24      # Update Supervisor to apply new configurations
25      echo " > Reloading Supervisor configuration..."
26      sudo supervisorctl reread
27      sudo supervisorctl update
28
29      # Update Python dependencies using requirements.txt
30      # Here you could replace with poetry, pdm, etc., alleviating the need for
31      # a requirements.txt file and virtual environment activation.
32      source venv/bin/activate
33      echo " > Installing updated dependencies..."
34      python3 -m pip install -r requirements.txt
35      deactivate
36
37      # ... other update processes like docs building, cleanup, etc. ... #
38
39      echo "Update process complete."
40
41      # Prompt to start the service
42      read -p "Start the service? (y/n) " -n 1 -r
43      echo
44      if [[ $REPLY =~ ^[Yy]$ ]]
45      then
46          echo " > Starting service..."
47          sudo supervisorctl start exampleapp
48      fi
49      ;;
50
51    # ... #
52  esac
53}

This update process includes the following steps:

  1. Stop the Service: Safely halts the application before making changes.

  2. Git Operations: Ensures the latest code is pulled from the repository.

  3. Configuration Symlinking: Updates supervisor configuration and shell alias to reflect any changes.

  4. Supervisor Reload: Applies new configuration settings to supervisor service.

  5. Dependency Update: Installs or updates Python dependencies as defined in lockfiles or requirements.txt.

  6. User Prompt: Offers a choice to immediately start the service after updating.

Execution#

Run the exampleapp update command to execute this update process. It streamlines the deployment of new code and configuration changes, ensuring a smooth and consistent application update cycle.