As a huge believer in the Nigerian Tech space sustainability, I always encourage the use of Nigeria-owned technology. That is the reason I always recommend Whogohost to anyone who asks what hosting platform should they use. As long as you’re using PHP or JavaScript, you’re good to go. I got to use the platform myself when I learnt they can host a Python project. So, I headed to the official documentation on their knowledge base and got to work. Here’s the problem, even though I followed each step carefully, my app didn’t work. The Google search results on “deploying Python on cpanel” didn’t work either – still do not understand why. After a couple of days on it, I finally got the app to work. Pending the time they update their documentation with the suggestions, here’s a guide to deploying your Python App (I used Django) on Whogohost and the possible reasons your application is not running.
To use this guide, I assume you:
- have your Python web project locally or on Git,
- have access to your Whogohost control panel,
- can create Python apps from your cpanel,
- have your required packages in requirements.txt
Step One: Request for Jailed SSH Access
Just like it says on the documentation, you have to request for SSH access. A quick chat with their customer service agent will get that done. For me, it took less than five minutes. How do you know if you’ve been granted access? You will find ‘Terminal‘ in Advanced options.
Step Two: Move your files to the File Manager
If for any reason, you didn’t get access immediately, you can continue with this next step while waiting. There are a number of ways to get your files to the file manager. You can do it via FTP, a simple upload, or git clone into your public_html folder. Note that your Python files cannot be in the pubic_html file directly, you have to put them in a subfolder.
To upload the file:
- zip your project folder,
- navigate to your public_html folder,
- upload,
- then extract the uploaded zipped file. You should have something like /home/username/public_html/djangoproject
To clone from git, you need to have been granted the SSH access.
- open the terminal,
- cd into your public_html folder –
c
d public_html - then git clone /path/to/your/git/repo
Note that there’s a method where you can connect your GitHub’s repo to the control panel. This is NOT THAT METHOD. I might cover it later.
Step Three: Create the Python application
- Choose the Python version used in your project
- Supply the application root; this is the directory you uploaded. It will take the form
public_html/djangoproject
. You can add the prefix/home/username/
as seen in the image below, it doesn’t change anything. - Provide the application URL. It could be the root domain or a subdomain you’ve initially created.
Here’s where things start changing. Unlike stated in the documentation, the application startup file is not the wsgi.py
file that was came with your project. Instead, its a passenger file that will be automatically created after this setup. Your application startup file should be passenger_wsgi.py
- Your application entry point still remains application
- For the log file, simply click on the example provided and paste into the input box. I noticed that if you gave another name for the log, it would still log into the passengar.log file.
- Click on Create
Step Four: Install your requirements & run Python commands
After creating your application, you need to install your specified packages. If you feel more comfortable using the terminal like me, you can copy the terminal codes at the top of the page, open your cpanel’s terminal, paste and run. This command will activate the virtualenv and cd into your project folder. From there, you can pip install -r requirements.txt
and other necessary scripts you need to run.
But let’s stick with the GUI. For the configuration files, enter the path to your requirements.txt file and run Pip Install. If you need to newly create your database or migrate some changes to it, supply the path to execute the script. It will look like manage.py migrate
or with the full path /home/username/djangoproject/manage.py migrate
NOTE: If the control panel cannot find your specified file path, it will let you know. Do not forget to have specified the right database connection settings in your settings.py. If you haven’t, you can simply edit the file in your File Manager, save changes and execute the scripts again. You cannot run manage.py runserver, because that is done automatically by the control panel.
Step Five: Edit your passenger_wsgi.py
In the documentation, the next step is to restart your application. You can do that to see the outcome. You would get a file not found response as shown below. To fix this, you need to change the auto-generated content of the application startup file.
If you checked your logs/passengar.log file, you would see the error:
App 13103 output: /opt/passenger-5.3.7-13.el7.cloudlinux/src/helper-scripts/wsgi-loader.py:26: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
App 13103 output: import sys, os, io, re, imp, threading, signal, traceback, socket, select, struct, logging, errno
As stated in the log, the passenger_wsgi.py file uses an outdated imp module to import your project’s wsgi file. To fix this, edit passenger_wsgi.py from your file manager. It looks like this:
import imp
import os
import sys
sys.path.insert(0, os.path.dirname(__file__))
wsgi = imp.load_source('wsgi', 'public_html/djangoproject/djangoproject/wsgi.py')
application = wsgi.application
The imp module that was used in lines 1, 5 and 6 caused this error. Change the content of the file to:
from djangoproject.wsgi import application
#replace djangoproject with the actual name of your app
# OR
# you can leave lines 2,3 and 5 too. so you'll have:
# import os
# import sys
# from djangoproject.wsgi import application
# sys.path.insert(0, os.path.dirname(__file__))
Save the file and go back to your created app. When you refresh your app at this point, you would see no changes. That is because you turned DEBUG off in your settings.py. ALWAYS TURN OFF DEBUG ON PRODUCTION, unless you’re still testing the app. The DEBUG response will expose the details of your application.
Step Six: Restart your application
DO NOT USE THE RESTART BUTTON
For an unknown reason, each time you hit Restart, the passenger_wsgi.py is recreated. It, therefore, overwrites your changes and you’re back to the original content. Instead of restarting, STOP APP and START APP. Open your project, and you should be good to go.
Other Errors that might occur
An undefined error: You could get an error page, stating that something went wrong with your passenger file. It will come with an error code. Open your passengar.log file, and see the details. It could be issues in your settings.py file or syntax errors while editing some of your files.
Your static files returned 404: If you are using Django, the static file settings will be different from what you use on your localhost, Heroku, or PythonAnywhere. Your generated staticfiles has to be in the public_html folder, and you have to specify its relative path for it to be found. Let’s say you have your static files in /home/username/public_html/djangoproject/static
Your static settings will be:
STATIC_URL = '/staticfiles/'
STATIC_ROOT = '/home/username/public_html/staticfiles'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
Go back to your terminal and run: python manage.py collectstatic
or return to your Python application and run /path/to/manage.py collectstatic
in the Execute Python Script section.
Save the app, stop the app and start. If you use the restart option directly, you would need to edit your passenger_wsgi.py file one more time.
And that’s it! I hope this is helpful, and saves you from the stress bugs give at times.
Happy Coding!