Python sites
Run a Python app (WSGI via gunicorn, or ASGI via uvicorn) as a self-healing systemd service — pick the server at launch, tune it later, and let SpipCP install the runtime on the way.
Python is a first-class site type. You launch a Python site the same way you launch any other — pick the type, pick the instance — and SpipCP installs the CPython runtime if it isn't there yet, sets up a virtualenv, writes a starter app, and runs it behind a production server supervised by systemd.
If you've launched a Node site, a Python site works the same way: an app directory, a long-lived process that restarts on failure and survives a reboot, served on its own port with the node edge proxying your domain to it.
Pick your server: gunicorn or uvicorn
Python apps speak one of two protocols, and you choose the matching server when you create the site:
| Server | Protocol | Use it for |
|---|---|---|
| gunicorn | WSGI | Django, Flask — the default |
| uvicorn | ASGI | FastAPI and other async frameworks |
You don't have to get it perfect at launch — you can switch later in the site's Python settings (see
below). The starter app SpipCP writes already serves a 200 under whichever server you picked, so a
fresh site is live immediately; you replace it with your own code (or a git deploy).
Your app lives in /srv/app
Dependencies install into a per-site virtualenv at /srv/app/.venv. When you ship a real app, a
requirements.txt in the app directory is installed automatically — the same way a Node site runs
npm install only when a package.json is present.
The runtime
The Python catalog category installs CPython from the deadsnakes builds. Three lines are offered:
| Version | Status |
|---|---|
| 3.13 | Current — the default |
| 3.12 | Current |
| 3.11 | Security fixes only |
Installing a version lays down the interpreter, the venv module, development headers, pip, and a
compiler toolchain so packages with native extensions build cleanly. You rarely install it by hand —
launching a Python site installs the runtime on the way if the instance doesn't already have it.
Self-healing by default
Your app runs under a systemd unit that restarts on failure and is enabled at boot. If the process crashes, systemd restarts it; if the whole instance reboots, your app comes back with zero manual input. This is verified live before the type is marked stable — the instance is restarted and the app must serve again.
Settings
The Python tab on a site (shown only for Python sites) exposes three tunables:
| Setting | What it does |
|---|---|
| Server | gunicorn (WSGI) ⇄ uvicorn (ASGI). Switching reinstalls the server into the venv and rewrites the systemd unit — make sure your app exposes a matching callable. |
| App module | The module:callable to serve. app:app matches the starter; a real app sets its own, e.g. myproject.wsgi:application (Django) or main:app (FastAPI). |
| Workers | Worker processes. gunicorn forks this many; uvicorn uses it only when greater than 1. A common rule of thumb is 2·cores + 1. |
Save & apply persists the change and relaunches the site so the new configuration actually lands inside the instance — the same process the first launch ran, never a faked in-place edit. The status goes to launching; watch the Deploys tab for the result.
What's not here yet
In-place Python version upgrades of a live site, multiple runtimes in one instance (pyenv/Conda), and a Python "one-click app" catalog are out of scope for now.
→ The full menu: What you can install. · How a type is defined: Blueprints.
Custom customer domains
Let a hosted app serve its own customers on their domains — status.client.com, shop.client.ie — with automatic HTTPS, without anyone adding those domains in SpipCP. One toggle, one CNAME per customer, certificates issued on demand.
Go sites
Point SpipCP at a Go repo and get a single static binary, built and supervised by systemd on its own port — a compile error fails the build, never a broken running site.

