CherryPy on Rocky Linux 9 (Python + WSGI + Nginx + SSL)

CherryPy is a lightweight yet production-ready Python web framework that includes its own embedded HTTP server. Unlike larger frameworks such as Django or Flask, CherryPy focuses on simplicity, performance, and flexibility, allowing developers to design applications without being tied to predefined patterns. With features like built-in session management, caching, and static file serving, CherryPy is ideal for lightweight web apps, APIs, and embedded Python services.

Running CherryPy on Rocky Linux 9, a community-driven, RHEL-compatible enterprise distribution, provides a secure, stable, and long-term supported foundation. With SELinux enforced by default, systemd 252, OpenSSL 3, and Python 3.9 (with newer versions available via AppStream or EPEL), Rocky Linux is well-suited for deploying CherryPy in production, typically behind Nginx with SSL termination.


Architecture Overview

LayerComponentRole
OSRocky Linux 9RHEL-compatible enterprise base with SELinux enforcement
RuntimePython 3.9+ + venvRuns CherryPy apps in isolated environments
FrameworkCherryPy (WSGI server)Minimalist Python HTTP server and framework
Process ManagersystemdManages CherryPy as a persistent background service
Reverse ProxyNginxTLS termination, routing, caching, and compression
TLSLet’s Encrypt / PKIProvides HTTPS security for public access

Why Use CherryPy?

  • Fast and lightweight – small footprint with a built-in HTTP server.
  • Stable and mature – in production since 2002, actively maintained.
  • Flexible – works with any Python library, ORM, or template engine.
  • Object-oriented – intuitive app structure for clean, maintainable code.
  • Enterprise-grade – integrates smoothly with SELinux, systemd, and Nginx.

CherryPy vs Other Python Frameworks

Feature/CapabilityCherryPyFlaskDjangoFastAPI
ApproachMinimal + WSGIMicroframeworkFull-stackAsync API-first
HTTP serverBuilt-inNeeds WSGI serverNeeds WSGI serverASGI (uvicorn)
ComplexityLowLowHighMedium
Best use caseAPIs, servicesLightweight APIsLarge-scale appsAsync microservices

CherryPy is best suited when you want a simple, fast Python framework without the complexity of full-stack solutions.


Security & Best Practices

  • Always deploy behind Nginx with SSL (HTTPS).
  • Run CherryPy under a dedicated non-root system user.
  • Use Python virtual environments to isolate dependencies.
  • Manage the app with systemd services for uptime and logging.
  • Keep Rocky Linux, Python, and CherryPy patched with security updates.
  • Enforce SELinux policies and secure Nginx with headers (HSTS, CSP, etc.).

Typical Use Cases

  • Hosting REST APIs and microservices.
  • Running internal dashboards or monitoring tools.
  • Embedding a lightweight web server inside Python-based applications.
  • Prototyping apps quickly without heavy frameworks.
  • Deploying secure, production-ready services with SSL.

Step 1: Create a Server Instance on Shape.Host

Start with a clean Rocky Linux 9 server. To create one on Shape.Host:

Log into your Shape.Host dashboard.

Click Create → Instance.

Shape.host Resources dashboard with Create > Instance highlighted.

Choose your preferred data center location.

Shape.host instance form with the data center location selector highlighted.

Pick a plan with at least 2 CPUs, 2 GB RAM, and 20 GB SSD.

Select Rocky Linux 9 (64-bit) as the operating system.

Shape.host instance form with the operating system image selector highlighted.

Click Create Instance.

Shape.host instance form with the Create Instance button highlighted.

Copy the public IP address from the Resources section once the VM is ready.

Shape.host Resources dashboard with the server IP address highlighted.

Step 2: Connect to Your Server

  • Linux/macOS: ssh root@your_server_ip
  • Windows (PuTTY):
    1. Download PuTTY.
    2. Enter your server IP and select SSH.
    3. Click Open and log in with your Shape.Host credentials.

Step 3: Update System and Install Dependencies

dnf update
dnf install python3 python3-pip nginx

Updates system packages and installs Python 3, pip, and Nginx.

Terminal showing DNF/YUM package management commands and output.
Terminal showing Python environment or package installation output.

Enable and check Nginx:

systemctl enable --now nginx
systemctl status nginx

Starts Nginx immediately and enables it on boot.

Terminal showing systemd service management commands or output.

Step 4: Create a Dedicated User and Application Directory

groupadd -r cherrypy
useradd -r -g cherrypy -s /sbin/nologin -M cherrypy
mkdir -p /opt/myapp

Creates a restricted system user cherrypy and an application directory.


Step 5: Set Up Virtual Environment and Install CherryPy

python3 -m venv /opt/myapp/venv
/opt/myapp/venv/bin/pip install --upgrade pip
/opt/myapp/venv/bin/pip install cherrypy

Creates a Python virtual environment, upgrades pip, and installs CherryPy.

Terminal showing Linux user account management commands.

Step 6: Create the CherryPy Application

cat >/opt/myapp/app.py <<'PY'
import cherrypy

class App:
    @cherrypy.expose
    def index(self):
        return "Hello from CherryPy behind Nginx (Rocky Linux 9)!"

def main():
    cherrypy.config.update({
        "server.socket_host": "127.0.0.1",
        "server.socket_port": 8000,
        "engine.autoreload.on": False
    })
    cherrypy.quickstart(App(), "/")

if __name__ == "__main__":
    main()
PY

This app responds with a simple message when visited.

Set correct permissions:

chown -R cherrypy:cherrypy /opt/myapp
Terminal showing file ownership or permission commands.

Step 7: Test the Application Manually

runuser -u cherrypy -- /opt/myapp/venv/bin/python /opt/myapp/app.py &
sleep 1
curl -v http://127.0.0.1:8000/ || true
pkill -f /opt/myapp/app.py || true

Starts the app temporarily, checks if it responds, then stops it.

Terminal showing CherryPy application startup messages.

Step 8: Create a systemd Service

cat >/etc/systemd/system/cherrypy.service <<'UNIT'
[Unit]
Description=CherryPy WSGI App
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=cherrypy
Group=cherrypy
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/venv/bin/python -u /opt/myapp/app.py
Environment=PATH=/opt/myapp/venv/bin
Environment=HOME=/opt/myapp
Restart=always
RestartSec=2
StandardOutput=journal
StandardError=journal
UMask=0022
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target
UNIT

Reload and start the service:

systemctl daemon-reload
systemctl enable cherrypy
systemctl restart cherrypy
systemctl status cherrypy --no-pager -l
Terminal showing systemd service management commands or output.

Verify it’s listening:

ss -tlnp | grep ':8000' || true
curl -v http://127.0.0.1:8000/ || true
Terminal showing HTTP response headers from a curl request.

Step 9: Configure Nginx Reverse Proxy

cat >/etc/nginx/conf.d/myapp.conf <<'NGINX'
server {
    listen 80;
    server_name rockylinux-tutorials.shape.host;  # change this

    client_max_body_size 20M;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Connection "";
        proxy_read_timeout 300;
    }

    access_log /var/log/nginx/myapp_access.log;
    error_log  /var/log/nginx/myapp_error.log;
}
NGINX

Check and reload Nginx:

nginx -t
systemctl reload nginx
Terminal showing systemd service management commands or output.

Step 10: Enable SSL with Let’s Encrypt

Enable required repos and install Certbot:

dnf install 'dnf-command(config-manager)'
dnf config-manager --set-enabled crb
dnf install epel-release
dnf install certbot python3-certbot-nginx
Terminal showing DNF/YUM package management commands and output.

Request SSL certificate:

certbot --nginx -d rockylinux-tutorials.shape.host
Terminal showing Certbot certificate commands and messages.

Now open:

https://rockylinux-tutorials.shape.host

You should see:
Hello from CherryPy behind Nginx (Rocky Linux 9)!

Browser displaying the CherryPy greeting behind Nginx on Rocky Linux 9.

You’ve successfully deployed CherryPy on Rocky Linux 9 with systemd and Nginx as a reverse proxy, secured by Let’s Encrypt SSL. This setup is lightweight, secure, and production-ready.

For scalable and reliable hosting, consider running your apps on Shape.Host Linux SSD VPS — optimized for performance and easy management.