Published on May 14 2019 in Python cPanel

We show how Django 2 can be run on cPanel server using Passenger Fusion and Python 3.7. Passenger/Python selector of CloudLinux is used.

mod_wsgi is still in cPanel’s experimantal repo and so Passenger is used for Python and Ruby apps in cPanel. We will use the interface added by Cloudlinux to create virtualenv, .htaccess and startup files skeleton. In the example we will use a django subdomain.

Add the subdomain in cPanel and create Python app

We chose document root at /home/user/djangoapps. It will host the application as well as passenger_wsgi.py and manage.py.

Setup Python App

In cPanel - Software - Setup Python App - Setup new application choose

Click Setup

Setup Python App

Install Django and Paste

When the app is added to the list, unfold Modules, add Django 2.x and Paste 3.x, click Add then Upgrade. You can also use Execute command field and run pip install Django Paste or go to cPanel - Terminal and run the commands:

source ~/virtualenv/flaskapp/3.7/bin/activate
pip install --upgrade pip
pip install Django Paste

Setup Python App

Create Django application

In cPanel - Terminal create application by running

source ~/virtualenv/djangoapps/3.7/bin/activate
cd ~/djangoapps
django-admin.py startproject app1 .

Note the space and period ‘.’ after ‘app1’ - it will prevent creating ‘app1/app1’ directories.

Basic configuration of the app

Update ~/djangoapps/app1/settings.py and set

ALLOWED_HOSTS = ['django.yourdomain.com']

Also append at the bottom of the file:

STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

Create the directories and fill them with static resources

cd ~/djangoapps
mkdir -p {media,static}
./manage.py collectstatic
119 static files copied to '~/djangoapps/static'.

Create default database (SQLite) and superuser

./manage.py migrate
./manage.py createsuperuser

Update passenger_wsgi.py

Finally replace content of autogenerated passenger_wsgi.py with below code (note 3 occurrences of our app1).

import os
import sys

#########Accessing the App's Default WSGI##############
import app1.wsgi

application = app1.wsgi.application

######## PASSENGER PATH INFO-FIX INITIALISATIONS#######
cwd = os.getcwd()
sys.path.append(cwd)
#sys.path.append(os.getcwd())
sys.path.append(cwd + '/app1')  #You must add your project here
# Set this to your root
SCRIPT_NAME = os.getcwd()

########  MIDDLEWARE CLASS TO FIX PASSENGER'S URI ISSUES #############
class PassengerPathInfoFix(object):
    """
    Sets PATH_INFO from REQUEST_URI since Passenger doesn't provide it.
    """
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        #IF YOU ARE IN PYTHON 2.7 USE: from urllib import unquote
        from urllib.parse import unquote
        environ['SCRIPT_NAME'] = SCRIPT_NAME

        request_uri = unquote(environ['REQUEST_URI'])
        script_name = unquote(environ.get('SCRIPT_NAME', ''))
        offset = request_uri.startswith(script_name) and len(environ['SCRIPT_NAME']) or 0
        environ['PATH_INFO'] = request_uri[offset:].split('?', 1)[0]
        return self.app(environ, start_response)

###########the redirecting Middleware
application = PassengerPathInfoFix(application)

Access frontend and backend

You can now visit your subdomain and its /admin URI where you can login as superuser.

Setup Python App

Other ways of running Python scripts

mod_wsgi Apache module can be installed from experimental EA4 RPM (ea-apache24-mod_wsgi) provided by cPanel as well as manually installed from source. mod_cgi and its family can be also used - this is an older approach.