Skip to main content
The cPanel Setup Python App tool registers a Python WSGI app under your account, builds a virtualenv, and hands the running process to Phusion Passenger. CloudLinux ships Python interpreters as alt-python packages. Each app picks its own version, and the virtualenv lives separate from the system Python.

Available versions

Available versions vary by host. Typical rotation:
  • Python 3.11. Active.
  • Python 3.10. Maintained.
  • Python 3.9. Older, still common for legacy apps.
Older alt-python (3.7, 3.8, 2.7) may be available for compatibility. Avoid Python 2 for anything new.

Set up an app

1

Open Setup Python App

From cPanel home, scroll to Software and click Setup Python App.
Setup Python App tool icon

cPanel home → Software → Setup Python App

2

Click Create Application

On an empty account, you land on a list page with a + Create Application button.
3

Fill in the form

  • Python version: pick from the dropdown.
  • Application root: directory under your home, e.g. myapp. Created if it doesn’t exist.
  • Application URL: domain dropdown plus optional path. Use / for the root or /api for a sub-path.
  • Application startup file: defaults to passenger_wsgi.py. Leave it as that unless you have a reason.
  • Application Entry point: dotted path plus callable, format module:callable. For Django: <project>.wsgi:application. For Flask: <module>:app.
  • Passenger log file: optional. Useful for catching boot errors.
4

Save

Click Create. Passenger starts the app in the background.

Manage an app

The Configuration files field accepts paths like requirements.txt (relative to the application root). The Environment variables editor sits below the buttons.

The Passenger contract

Passenger expects a WSGI callable named application. Your passenger_wsgi.py either defines it directly or imports it from your app. For Flask:
passenger_wsgi.py
For Django:
passenger_wsgi.py
Your code does not run a development server. No app.run(), no manage.py runserver.
Calling app.run() (Flask) or runserver (Django) inside a Passenger-managed app makes Passenger see no application and return a 500 with passenger_wsgi.py did not provide an "application" callable. Remove the call.

ASGI apps

Native ASGI (FastAPI, Starlette, Channels) needs a WSGI shim. The common bridge is asgiref.WsgiToAsgi reversed, but Passenger’s WSGI mode does not handle WebSockets or HTTP/2 streaming over ASGI. For a sync FastAPI subset, wrap with a2wsgi:
passenger_wsgi.py
For real WebSockets, run Daphne or Uvicorn outside the Selector.

Reference: where things live

From SSH, activate manually:

Common issues

passenger_wsgi.py doesn’t expose a top-level name application. Either rename your callable to application, or alias it: application = app.
The package was installed against the system Python, not the per-app virtualenv. Run Pip Install from the cPanel UI, or activate the env in SSH first: source ~/virtualenv/<app>/<ver>/bin/activate.
Passenger only serves the WSGI app. Run manage.py collectstatic and serve /static/ directly from Apache. Add to .htaccess:
PMEM is ~1 GB. Heavy compiled wheels can OOM. Use prebuilt wheels (the default for pandas / numpy on linux x86_64), avoid --no-binary, and consider installing one package at a time.
Default Passenger startup timeout is 60 seconds. Long migrations or heavy INSTALLED_APPS initialization can exceed it. Bump the timeout in .htaccess:

Recipes

Deploy Django

Django app, virtualenv, static files.

Deploy Flask

Flask service via passenger_wsgi.py.

Need a hand?

Open a ticket

Best for anything that needs an account check or a config change on our end.

Live chat

Faster for quick questions during business hours.