Can Shared Hosting Run Django? (Yes, via Passenger)
Host a Django website on cPanel from Setup Python App. Point passenger_wsgi.py at your project's WSGI callable, install requirements.txt, set ALLOWED_HOSTS, then run migrate and collectstatic. Restart the application. The domain should show your site, not the sample Python page. Passenger serves it. You do not get a root shell.
cPanel does this with Setup Python App. The screen creates a virtualenv, and Phusion Passenger loads the callable named application from passenger_wsgi.py. You do not open port 8000. Apache or LiteSpeed on the account already listens on ports 80 and 443.
Look under Software for Setup Python App before you upload code. If the icon is missing, that account cannot run Django. On WebJi® the entry Linux shared plan is not a Python runtime. Email support@webji.services and ask for a quoted Python server, or read Python hosting. Panel accounts are on cPanel hosting.
CodeIgniter does not use this screen. It is a PHP framework, so it belongs in a PHP document root, not in Setup Python App.
- One application, one folder, one domain or subdomain.
- The check is your Django page on that domain after a restart, not the sample Python page.
- Passenger stops the process when it is idle. A brochure site or a low-traffic tool fits. A busy API does not.
Step 1: Create the Python App in cPanel
Open Setup Python App and click Create Application. The version, the folder, the URL, and the startup file decide whether the domain reaches Django.
- Choose the Python version your project already runs. Django 5.2 LTS needs Python 3.10 or newer. Django 6.0 needs Python 3.12 or newer. Do not take an older interpreter because it is first in the list.
- Set Application root to a folder that holds manage.py and sits outside public_html, such as djangoapp. A project inside public_html can leave settings.py downloadable.
- Set Application URL to the domain or subdomain that should serve the site. Add a path only when this app is not the whole domain.
- Set the startup file to passenger_wsgi.py and the entry point to application.
- Click Create. The new row should show a status, a restart control, and the command that activates the virtualenv.
Set a Passenger log file on that same form. A blank 500 is usually explained there, not in the browser.

Step 2: Upload Code and Install requirements.txt
Zip the project without the local virtualenv, without __pycache__, and without the laptop SQLite file. Upload it with File Manager or SFTP into the application root, then extract. manage.py has to sit in that root.
In the app configuration files, add requirements.txt and click Run Pip Install. The panel installs into the app virtualenv, not the system Python. Wait for the success message before you migrate.
From Terminal, paste the activation command shown at the top of the app, then run pip install -r requirements.txt. Type deactivate when you finish. A wheel built on your laptop will not run on this server, so install here.
Create the MySQL database Django uses on cPanel
Create the database before migrate. In MySQL Databases, add a database, add a user, and grant that user all privileges on that database only. Copy the password. Confirm the empty database in phpMyAdmin.
In settings.py set ENGINE to django.db.backends.mysql, HOST to localhost, and NAME, USER, and PASSWORD to the values cPanel shows. Those names usually start with the account prefix. Do not upload the SQLite file from your laptop. Two writes at once lock that single file.
If pip stops with "Failed building wheel for mysqlclient", the account cannot compile the MySQL C client. Add PyMySQL to requirements.txt and call pymysql.install_as_MySQLdb() in passenger_wsgi.py before Django imports. Keep the same ENGINE. Store the password as an app environment variable, not in a public repository.
Step 3: Configure WSGI and ALLOWED_HOSTS
Passenger loads the callable named application from passenger_wsgi.py. Replace the sample file so it imports your project, not the demo app.
Set DJANGO_SETTINGS_MODULE to yourproject.settings, then import application from yourproject.wsgi. yourproject is the folder that contains settings.py and wsgi.py. Save that file in the application root.
- ALLOWED_HOSTS lists the bare domain and the www host. Without them Django returns 400 DisallowedHost.
- DEBUG is False on the public site. True prints paths and settings to anyone who triggers an error.
- SECRET_KEY and the database password are environment variables on the app screen. They apply only after Restart.
- On Django 4 or newer, CSRF_TRUSTED_ORIGINS lists https:// and the domain, or form posts are rejected.
Click Restart. Reload the domain in a private window. Your home view, or a Django error page, means the import worked. The sample Python page means the entry point is still the demo.
Step 4: collectstatic and Static URL Mapping
With DEBUG set to False, Django does not serve CSS and JavaScript the way runserver does. Run python manage.py collectstatic --noinput in the activated virtualenv, or run manage.py collectstatic --noinput from Execute python script.
STATIC_ROOT is a real folder, usually BASE_DIR / "staticfiles", and STATIC_URL is /static/. Serve those files with WhiteNoise middleware, or map /static/ to that folder if the host gives you an alias. Restart after either change.
You know it worked when a stylesheet URL returns 200, not 404. Editing a file leaves the old process in memory, so restart before you judge the result.
Run Django migrations and create a superuser in cPanel
From the same virtualenv, run python manage.py migrate, then python manage.py createsuperuser. migrate builds the tables in the MySQL database you created. createsuperuser asks for a username, an email, and a password.
If the script runner cannot see manage.py, pass the full path to that file. When a command fails, read stderr.log in the application root, fix the setting it names, and run the command again.
Open /admin/ on the domain and sign in with that user. A login form means the database connection and the session middleware are both working.
Fix Django 500 errors on cPanel
Change one thing, restart, and reload in a private window. The log line is more useful than a second guess.
| What you see | Cause | Fix |
|---|---|---|
| 500 and a blank page | passenger_wsgi.py imports the wrong project, or a package is missing | Read stderr.log or the Passenger log, fix that line, restart |
| 400 DisallowedHost | ALLOWED_HOSTS omits the domain | Add the bare domain and www, then restart |
| CSS and JavaScript 404 | DEBUG is False and nothing serves STATIC_ROOT | collectstatic, then WhiteNoise or a static map, then restart |
| Failed building wheel for mysqlclient | The account cannot compile the MySQL C client | Switch that dependency to PyMySQL and restart |
| Sample Python page | The entry point is still the demo app | Set the entry point to application and restart |
If the log is empty and the domain still fails, email support@webji.services with the domain, the Python version, and the last log line. Email support is 24/7 in Hindi and English, and the average first reply is under 60 minutes. Do not call the office number for a 500.
When Django on cPanel should move to a VPS
Passenger starts the app when a request arrives and stops it when the app is idle. That fits a brochure site or an internal tool. It does not fit Celery, Django Channels, a websocket that stays open, or a process bound to a port you choose.
Move that project to a VPS server. Install the same Python version, run the app under systemd, and put the web server in front of it. The Django project does not need a rewrite. Picking the server is covered on Django hosting in India.
Frequently Asked Questions
Can I host Django on cPanel shared hosting?
Yes, when Setup Python App is on the account. cPanel creates a virtualenv and Passenger loads passenger_wsgi.py. If that icon is missing, the account is not a Python runtime. On WebJi®, email support@webji.services and ask for a quoted Python server before you upload the project.
How do I deploy Django on cPanel?
Create the app, put the project in the application root outside public_html, install requirements.txt, point passenger_wsgi.py at your WSGI application, set ALLOWED_HOSTS, run migrate and collectstatic, then restart. The domain should show your site, not the sample Python page.
What is Setup Python App in cPanel?
It is the Software screen that creates a Python application: version, application root, URL, startup file, and entry point. For Django the startup file is passenger_wsgi.py and the entry point is application. The panel also runs pip against that app virtualenv.
Why is my Django app showing 500 on cPanel?
Usually passenger_wsgi.py imports the wrong module, or a package from requirements.txt is missing. Open stderr.log in the application root, or the Passenger log on the app, fix the line it names, and restart. A 400 DisallowedHost is ALLOWED_HOSTS, not a 500.
How do I serve static files for Django on cPanel?
Run collectstatic so files land in STATIC_ROOT. With DEBUG set to False, the runserver static handler is off. Add WhiteNoise, or map /static/ to that folder, then restart. A stylesheet URL that returns 200 is the check.
Does cPanel support Python and WSGI?
Yes, through Passenger and Setup Python App, not through a port you choose. The WSGI callable must be named application. You cannot bind port 8000, and a long-running worker such as Celery needs a VPS.

