Charlie El Awbery

Configuring a Python app for Passenger wsgi in cPanel


June 6, 2020 |  Categories:   tech   python   django   deployment   tutorials  

vintage passenger cars

Vintage passenger cars © Olivier Le Queinec | Dreamstime.com

This is the fourth post in Deploying Django, a step-by-step guide to deployment for individuals building personal or small Django web projects. If you are unsure whether the deployment method in this tutorial is suitable for you and you want to understand the options better, Deploying a Django app explains what you need to know to make that choice. At this point you have your Django project uploaded to the server and you have its settings configured appropriately for production. You may also have a MySQL database set up for your app to use on the server. Next you will write a passenger_wsgi.py file so that Passenger can run your app, then you'll register the app with Passenger in cPanel.


Configure Passenger wsgi for your Django app

IMPORTANT! Move Django's wsgi.py file from your management app to the top level of your Django project. (You could use the cPanel file manager or mv in your ssh session.) The wsgi.py file must be right at the top level, in your Django project folder, alongside mange.py, so that Passenger can find it straight away when it looks in your domain name directory. Passenger will not automatically look into nested directories lower in your Django project. In the wsgi.py file, rename your application variable from application to app:

import os from django.core.wsgi import get_wsgi_application # application variable named 'app' so that there's no confusion # when passenger_wsgi imports this for its application variable app = get_wsgi_application() # This path is now set in passenger_wsgi.py: # os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'charliedemo.settings')

This is to avoid confusion when you import the app variable into the passenger_wsgi.py file and assign it to another variable named 'application' in that file. The environment variable set by Django in wsgi.py is no longer needed in this file. It will be assigned in passenger_wsgi.py so remove it or comment it out. The relevant line is commented out in the code above. Django's automatically generated wsgi.py files include a detailed docstring. The sentence "It exposes the WSGI callable as a module-level variable named application" in the docstring will no longer apply, so delete it to avoid any confusion later. Next, create a passsenger_wsgi.py file at the top level of your project, alongside wsgi.py and manage.py. It must be called passenger_wsgi.py as this is the file name that Passenger is configured to recognize. Write the following code into passenger_wsgi.py The following paragraphs explain how to customize this code for your app.

import sys, os # Passenger on cPanel runs the default python, which is python 2 # so the first thing we do is force a switch to python3 in the virtualenv INTERP = "/home/user/DjangoProjectName/env/bin/python3" # sys.executable is the path of the running Python # Check to see that the correct Python version is running. The first # time this runs, it won't be! Second time round, it should be. # First argument to os.execl is the program to execute (INTERP); # the second argument is the first part of the arguments to it, which # is the full path to the executable itself. # sys.argv is the rest of the arguments originally passed to the INTERP program. if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) # The arguments to setdefault must match the configuration in the main() function in your manage.py file environ=os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.productionsettings') # Import the app variable from your Django project wsgi file from wsgi import app application = app

The INTERP variable is the exact path to your app’s installation of Python 3 inside the remote virtual environment that you set up in step 1 of this guide. The if clause tells Passenger that it should run the app on the Python version you used to write your app. (The if clause above is telling Passenger: "if the Python path you are set up for isn’t exactly the same as this one I told you about earlier, then swap it out, but keep the rest of the arguments for how to execute the program the same.") The environ variable tells Passenger to use Django settings and where to find your app settings. Make sure that you customize the second argument to os.environ.setdefault appropriately. The code above assumes that your app, called 'myapp,' is at the same level as the passenger_wsgi.py file and that your settings file for the app, called 'productionsettings.py', is stored at the top level of your app. That’s the app configuration process complete. Now you can register your app with Passenger.


Register your Django app with Passenger in cPanel

Return to the cPanel homepage and in the software section find the application manager.

app mgr image not showing

Click on Application Manager and then +Register Application:

app reg image not showing

app reg fields image not showing

Each app registration with Passenger is per Django project. So if you have several Django apps inside the same project you only need to register the project with Passenger. For that reason, use your Django project name in the Application Name field so that you have no confusion later about what Passenger regards as your app. Your domain name should show as a choice in the drop-down menu for Deployment Domain, so long as you already associated it with the path to your home directory. (Do this in the Domains section of cPanel if you didn't yet set it up. You don’t need a slash at the end of the domain name.) In the Application Path section, the path to your application's source code directory is the path from (not including) your home directory to the folder where you keep your passenger_wsgi.py file. Include that folder but not the filename itself. The path will look something like /projectname. It doesn't need to have a slash after it. Select production environment and click the deploy button. You should now see your Django project listed as a registered app in the Application Manager. Here’s an example:

demo image not showing

example image not showing

You can see in the cPanel file manager that the Django Project is called demo; the app that loads the demo view is called demoapp. The Application Name registered with Passenger is demo, the top level Django project name. The second level directory, also called demo as per Django naming conventions, contains settings and configuration files. This directory, sometimes called the configuration app, is not directly relevant for the cPanel app registration with Passenger but it's worth mentioning because the duplicate name can cause confusion. The structure here replicates a simple file structure used in many Django tutorials, to make the process as accessible as possible for learners. Now that you have completed the wsgi configuration for Passenger and registered your app, test your newly-deployed site by opening it in a browser. If you created an empty string url path in your Django project urls.py file, test using only your domain name first. Otherwise test using the url paths you added to urls.py in your Django app. The final page in this series covers some common problems that occur in deployment and how you might go about troubleshooting if this doesn't work first time around. *** Could you follow this tutorial? How could it be better? I'm grateful for suggestions, please DM me @_awbery_on Twitter with feedback. Thank you!