Ipswitch
← All writing

The cPanel Python selector leaves your app broken in two silent ways

Both produce the same blank 500, and neither is in the docs. Here is how to tell them apart and fix them.

I deploy a Next.js frontend and a FastAPI backend on a Safaricom Cloud cPanel account: 1 GB RAM, 1 CPU core and a 500 MB disk. The frontend runs under Passenger as a Node app. The backend runs under the same Passenger as a Python app, mounted at /api through cPanel’s Setup Python App.

Creating that Python app leaves it broken. The selector does two things wrong, and the error page you get is identical for both: 500 — Web application could not be started. Here is each one, and what fixes it.

1. The selector forgets to say what kind of app it is

Setting up the app writes PassengerAppRoot, PassengerBaseURI and PassengerPython into public_html/api/.htaccess. It does not write PassengerAppType or PassengerStartupFile.

Apache therefore inherits those two settings from the .htaccess one level up, the frontend’s, which says PassengerAppType node and PassengerStartupFile server.js. Passenger then tries to start your Python backend as a Node app.

Append these two lines to the backend’s .htaccess:

PassengerAppType wsgi
PassengerStartupFile passenger_wsgi.py

The value is wsgi, not python. python is not a valid Passenger app type. It is silently ignored, which leaves the inherited node in place and looks exactly like the fix did nothing.

2. The selector overwrites your entry file with a stub that loads itself

After you create the app, check passenger_wsgi.py. The selector replaces it with its own placeholder, which contains this line:

wsgi = imp.load_source('wsgi', 'passenger_wsgi.py')   # loads itself, forever

It imports the file it is already running. Restore your real passenger_wsgi.py over it, then touch tmp/restart.txt in the app root so Passenger reloads.

How to tell it is working

Put a health route on the backend and call it through the public URL. Mine is /api/health, which returns {"status":"ok"}. If that comes back, both fixes took.

How to see the real error

The 500 page itself tells you nothing. In the Python app’s settings, set Passenger log file to a path in your home directory, such as /home/<user>/logs/passenger.log. The actual startup failure is written there.

One more trap

Run Pip Install is greyed out until a requirements file is registered. In Detected configuration files, type requirements.txt into the “Add another file and press enter” box first, then it enables.

Why this is worth writing down

Two unrelated faults with identical symptoms is the worst case for debugging: fixing one changes nothing you can see, so you assume it did not work and undo it. Treat a blank 500 on a fresh cPanel Python app as two suspects, check both, and read the Passenger log before touching anything else.

Written from the deployment notes of Chama Cha Mimi na Wewe, which runs on exactly this setup.