Skip to main content
Updated: August 9, 2026
Matic Bončina
By Matic BončinaFounder
Proofread & verified
Setup Python App registers a Python web application under your cPanel account. It builds a private virtualenv for the app, then hands the process to Phusion Passenger, which imports your WSGI callable and feeds it requests. You never start a server yourself. The tool is CloudLinux’s Python Selector. Each app picks its own interpreter from the alt-python packages installed on the server, so two apps in one account can run different versions.
Python is included on BONFIRE, BLAZE and INFERMO. SPARK and FLAME don’t come with it, so those plans need an upgrade before Setup Python App appears in cPanel.

Python versions

Twelve interpreters are installed and available to pick from: 3.13.12, 3.12.13, 3.11.15, 3.10.20, 3.9.23, 3.8.20, 3.7.17, 3.6.15, 3.5.9, 3.4.10, 3.3.7, 2.7.18 Take the newest one your dependencies support. Everything below 3.9 is past upstream end of life and is there for old applications that can’t move yet.
The version dropdown starts on 2.7.18. The Selector has no default version configured, so the form opens on the first entry in the list, which is Python 2. Create an app without touching that dropdown and you get a Python 2.7 virtualenv. Change it before you click CREATE.

Set up an app

1

Open Setup Python App

From cPanel home, scroll to Software and click Setup Python App.
The Software section of cPanel home, with Setup Python App in the third row beside Setup Node.js App and Setup Ruby App

cPanel home → Software → Setup Python App

2

Click CREATE APPLICATION

On an account with no apps yet, the page shows WEB APPLICATIONS and NO APPLICATIONS FOUND. Click CREATE APPLICATION to open the form.
3

Fill in the form

Five fields, plus an environment variable panel:
  • Python version: change it off 2.7.18 unless you really want Python 2.
  • Application root: the directory holding your code, relative to your home directory, such as myapp. This is the only mandatory field.
  • Application URL: pick a domain, then add a path if you want one. Leave the path box empty to serve the app at the domain root.
  • Application startup file: the file Passenger imports, usually passenger_wsgi.py. The field starts empty and there is no default, so type it in.
  • Application Entry point: the name of the WSGI callable inside that file. cPanel describes it as “Setup wsgi callable object for your application”. The usual answer is application.
  • Environment variables: click ADD VARIABLE for anything your app reads from the environment.
The create form with the Python version dropdown sitting on 2.7.18, an empty Application root marked as a mandatory field, the Application URL domain picker, and empty Application startup file and Application Entry point fields

Setup Python App → CREATE APPLICATION

4

Click CREATE

The Selector creates the app root, builds the virtualenv, and switches to the management view for the new app. You’ll see the activation command for its virtualenv at the top of that page.

What gets created

Creating an app writes three things into your application root: a public directory, a tmp directory holding restart.txt, and a placeholder passenger_wsgi.py. Replace that placeholder with your own file. The virtualenv lands outside the app root, at ~/virtualenv/<app-root>/<major.minor>/. An app on 3.13.12 gets ~/virtualenv/myapp/3.13/.

Manage an app

Opening an existing app shows the same fields you filled in, now with controls across the top and extra panels below. There is no separate Edit button. The management page is the form, so change a field and click SAVE.
DESTROY leaves your files behind. It removes the Passenger registration and deletes ~/virtualenv/<app-root>/, but the application directory itself, including your code, tmp/, and any log files, stays exactly where it was. Delete it in File Manager if you want it gone.

The Passenger contract

Passenger doesn’t run your file as a script. It imports the file named in Application startup file and looks for the callable named in Application Entry point. With the usual pairing of passenger_wsgi.py and application, that means a top-level name application has to exist. For Flask:
passenger_wsgi.py
For Django:
passenger_wsgi.py
Your code does not start a development server. No app.run(), no manage.py runserver. Passenger owns the process and the socket.

ASGI apps

Passenger speaks WSGI. FastAPI, Starlette and Django Channels are ASGI, so they need a bridge in front of them. a2wsgi provides one:
passenger_wsgi.py
That covers ordinary request and response traffic. WebSockets and long-lived streaming don’t survive the translation, because WSGI has no model for them. If you need those, you need a process listening on its own port, which this tool doesn’t provide. Open a ticket and we’ll talk through the options.

Reference: where things live

The management page prints the exact command for entering the environment from SSH. For an app rooted at myapp on 3.13:

Common issues

The version dropdown opens on 2.7.18 and stays there unless you change it, so an app created in a hurry ends up on Python 2. Check the Python version field on the management page, set the one you wanted, and click SAVE. Reinstall your packages afterwards with Run Pip Install, since the environment your app uses is tied to the interpreter.
The name in Application Entry point has to exist as a top-level name in the file named in Application startup file. If your Flask object is called app, either rename it or alias it: application = app. Check both fields on the management page before you go digging through your code.
The package went into the system Python rather than the app’s virtualenv. Use Run Pip Install from the management page, or activate the environment first in SSH with the command that page prints.
Passenger serves the WSGI application and nothing else, so /static/ isn’t handled for you. Run collectstatic and serve the output as ordinary files. The Deploy Django guide walks through the layout.
Memory is rarely the culprit. Plans that include Python start at 6 GB of RAM on BONFIRE and reach 12 GB on INFERMO, which is comfortably enough for prebuilt wheels like pandas or numpy. The more common trigger is a package with no wheel for the interpreter you chose, which drops pip into a source build. Check which version the app is on first, then send us the pip output if it still won’t install.
Passenger’s documented default gives an application 90 seconds to start before it gives up and logs an error. Slow migrations or heavy imports at module level can run past that. Move that work out of startup, or open a ticket and we’ll look at the boot log with you.

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.