How to run Streamlit reliably in production using supervisor!

KubeBlogs: Run streamlit reliably in production using supervisor!
KubeBlogs: Run streamlit reliably in production using supervisor!

Streamlit is widely used by Python developers for rapid prototyping as well as running real production applications. Have you ever faced a situation where your Streamlit application suddenly stops working? Whether due to crashes or server issues. Most developers run streamlit using tmux or nohup - which work - but when the app crashes - they have no way to know!

Streamlit doesn’t provide a clean way to run reliably - and that’s where supervisor comes in!

In this blog, we’ll explore how Supervisor can monitor your Streamlit app and automatically restart it if it crashes, ensuring minimal downtime and a smoother experience for your users.

We’ll also walk through a real-world scenario with a step-by-step guide on how to set up Supervisor for your Streamlit application. By the end, you’ll know exactly how to configure it to keep your app running reliably and without interruptions.

Why Use Supervisor for Streamlit?

Running a Streamlit app in production often presents challenges:

  • What happens if the app crashes?
  • Who will restart it if you’re unavailable?
  • How can you maintain its availability without constant oversight?

Supervisor addresses these issues by monitoring your application continuously. The moment it detects that the app has stopped, it restarts it automatically, ensuring that your Streamlit app stays online with minimal downtime.


How Does Supervisor Work?

At its core, Supervisor consists of two main components:

  1. supervisord: A daemon that runs in the background and manages processes.
  2. supervisorctl: A command-line tool to interact with and control the processes managed by supervisord.

Supervisor uses configuration files to define how each service or program should behave. For example, you can specify:

  • The command to start the service.
  • Whether it should restart automatically.
  • Where logs should be stored.

Setting Up Supervisor

Getting started with Supervisor is straightforward. Here’s how you can set it up:

1. Install Supervisor

On most Linux systems, you can install Supervisor with:

sudo apt update
sudo apt install supervisor

2. Create a Configuration File

Supervisor uses configuration files to manage services. Let’s say we want to manage a simple application. Here’s how a configuration file might look:

[program:sample_app]
command=/path/to/your/app --option
directory=/path/to/your/app
autostart=true
autorestart=true
stderr_logfile=/var/log/sample_app.err.log
stdout_logfile=/var/log/sample_app.out.log

Save this file in /etc/supervisor/conf.d/ with a .conf extension (e.g., sample_app.conf).

3. Reload Supervisor

After adding the configuration, reload Supervisor to apply the changes:

sudo supervisorctl reread
sudo supervisorctl update

4. Start the Service

Start the managed service with:

sudo supervisorctl start sample_app

A Practical Example:
Managing an Application with Supervisor

Let’s walk through a real example where we used Supervisor to manage a Streamlit app. Here’s what we wanted:

  1. Run the app reliably in production.
  2. Automatically restart it if it crashes.
  3. Monitor its health with a custom script.

Step 1: Supervisor Configuration

We created a configuration file to define how Supervisor should manage the app (Assuming your streamlit code is located in directory /home/ubuntu/app):

[program:streamlit_app]
command=/bin/bash -c "cd /home/ubuntu/app && source venv/bin/activate && source .env && streamlit run main.py --server.port=8501 --server.address=0.0.0.0 --server.fileWatcherType='none'"
directory=/home/ubuntu/app
autostart=true
autorestart=true
stderr_logfile=/var/log/streamlit_app.err.log
stdout_logfile=/var/log/streamlit_app.out.log

Step 2: Health Check Script

To ensure the app was always responsive, we added a health check. This script monitored the app’s /healthz endpoint and restarted it if it stopped responding:

import requests
import os
import time

APP_URL = "http://127.0.0.1:8501/healthz"

while True:
    try:
        response = requests.get(APP_URL, timeout=5)
        if response.status_code != 200:
            os.system("supervisorctl restart streamlit_app")
    except Exception:
        os.system("supervisorctl restart streamlit_app")
    time.sleep(10)

We ran this script alongside Supervisor to ensure the app stayed online. 

Step 3: Logs and Monitoring

Supervisor made it easy to monitor the app. We used the following commands to check logs:

sudo tail -f /var/log/streamlit_app.out.log
sudo tail -f /var/log/streamlit_app.err.log

Conclusion

Supervisor is a powerful yet simple tool for managing processes in production. Whether you’re running a small service or a large-scale application, it can save you time, reduce downtime, and make monitoring easier.

By combining Supervisor with a health check and proper logging, we ensured our app stayed reliable and easy to debug. If you’re managing processes on a server, consider using Supervisor—it’s a best tool for process management.