DjangoWeb HostingcPanelPython AppDjango HostingDevelopment GuideShared HostingProduction SetupHow ToTutorial

Django App Hosting on cPanel

cPanel

Deploying a Django project on a shared hosting environment using cPanel (with Python App support) can be a smooth process. Here’s how to do it from start to finish.

Prerequisites

Before we begin, make sure you have:

  • A shared hosting plan with cPanel access
  • Python App support (look for “Setup Python App” in cPanel)
  • Domain or Subdomain ready
  • Your Django project (in a standard structure).
  • Access to File Manager or SSH (optional but helpful).

Step 1: Prepare Your Django Project

Ensure your project follows this structure:

myproject/
    ├── manage.py
    ├── myproject/
   ├── __init__.py
   ├── settings.py
   ├── urls.py
   └── wsgi.py
    └── requirements.txt
Shell

Then:

  1. Generate requirements.txt:
pip freeze > requirements.txt
Shell
  1. Zip your project (excluding venv, .git, __pycache__):
    zip -r myproject.zip myproject/
    Shell

Step 2: Upload Project to cPanel

  1. Go to File Manager in cPanel.
  2. Upload the myproject.zip file to a location like: /home/username/myproject/
  3. Extract the zip file.
  4. Move the extracted folder to your desired location, e.g., /home/username/myproject/ if needed.

Step 3: Create a Python App

  1. Open Setup Python App in cPanel.
  2. Click Create Application and configure.
  • Python version: e.g. 3.11
  • Application root: myproject
  • Application URL: select a domain or subdomain
  • Application startup file: passenger_wsgi.py (cPanel pre-created)
  • Application entry point: application (cPanel pre-created)
  1. Click Create.

Step 4: Create passenger_wsgi.py

  1. Inside your project root (myproject/), create a file named passenger_wsgi.py (most of cPanel provide pre-created file).

  2. Add this content (update myproject to your actual project name):

import sys
import os

project_home = os.path.expanduser('~/myproject')
if project_home not in sys.path:
    sys.path.insert(0, project_home)

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
python

If you’re using a subdirectory (e.g., yourdomain.com/backend), append this to the file:

os.environ['FORCE_SECRET_NAME'] = "/backend"
python

And in settings.py:

FORCE_SCRIPT_NAME = "/backend"
STATIC_URL = "/backend/static/"
MEDIA_URL = "/backend/media/"
python

Step 5: Install Dependencies

  1. In Setup Python App, copy the virtualenv path.
  2. Open cPanel Terminal or SSH:
source /home/username/virtualenv/myproject/3.11/bin/activate
cd ~/myproject/
pip install -r requirements.txt
Shell

No terminal access? Use the Setup Python App interface instead.

  • Go to the Configuration Files section.
  • Add requirements.txt.
  • Click Run Pip Install.

Step 6: Update Django Settings

In myproject/settings.py update the following:

ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']

CORS_ALLOWED_ORIGINS = [
   "https://yourdomain.com",
   "https://www.yourdomain.com",
]

CORS_TRUSTED_ORIGINS = [
   "https://yourdomain.com",
   "https://www.yourdomain.com",
]

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
python

Step 7: Collect Static Files

Run the following in terminal:

python manage.py collectstatic
Shell

Your static files should now be in the staticfiles/ directory.

Step 8: Migrate the Database

python manage.py migrate
Shell

If no terminal access, use the Python App interface:

In the Execute python script section, you can run:

For static files:

-m manage collectstatic --noinput
Shell

For migrations:

-m manage migrate
Shell

Step 9: Restart the App

Back in Setup Python App, click Restart next to your Django app.

Done!

Happy

Visit your domain/subdomain:

you should see your Django project running 🎉.

Troubleshooting

Got a 500 Error?

Check logs here:

/home/username/myproject/stderr.log
Shell

Can’t find Python App option?

Your hosting provider may not support it. Contact them or consider upgrading your plan.

Optional: Subdomain .htaccess Routing (I haven’t tested this).

If you’re skipping FORCE_SCRIPT_NAME setup, you may need a .htaccess file:

RewriteEngine On
RewriteBase /backend/
WSGIScriptAlias /backend /home/username/myproject/passenger_wsgi.py
Shell

Place .htaccess in the subdomain’s root directory.

To Serve Media and Static Files

To make your uploaded media and static files accessible via browser, add the following to your urls.py:

from django.views.static import serve
from django.conf import settings
from django.urls import re_path

urlpatterns = [
    #Media files (user uploads)
    re_path(r"^media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT}),

    #Static files (CSS, JS, images)
    re_path(r"^static/(?P<path>.*)$", serve, {"document_root": settings.STATIC_ROOT}),

    # ... your other URL patterns
]
python

Final Tips

  • Set DEBUG = False in production.
  • Keep your SECRET_KEY safe.
  • Use SQLite for simpler setups or configure MySQL/PostgreSQL via cPanel.

Need Help?

If you get stuck or run into an error, feel free to:

  • Check your error logs (stderr.log)
  • Revisit each step — a small path or typo might cause issues
  • Contact your hosting provider if Python App is not visible
  • Ask the Django community on Stack Overflow or Django Discord

Happy coding!