Jan. 28, 2019 Chris Shaw 114 views
Moving you django project from a local development environment to the open internet can be a daunting task, especially when you have a tight budget. There are free options with pythonanywhere and Heroku and probably others. For my first 'live' project, I used pythonanywhere for a while, but found it limiting. I wanted the freedom and the budget prices that shared servers offer, that I had gotten used to developing wordpress and other php based websites.
After Googling and reading reviews on hosting django projects on shared servers, two names came up repeatedly with good reviews; A2 Hosting and Digital Ocean. While Digital Ocean appeared to be more suitable, I did not have the budget, so went with A2 Hosting and signed up for two years of their 'Swift webhosting' product and immediately started on a long and steep learning curve.
Now, I can confidently start a new django project on my A2 Server and have then framework up and running in under 15 minutes, but this has not always been the case. It took me many months to get to this stage. I will describe my steps exactly and hopefully if you follow them, you will have the same success, stress-free.
A little obvious, you will need a hosting package and a primary domain. I suggest a package that supports multiple websites / domains and multiple databases. In this example, I am using the 'Swift' package from A2 Hosting which, at the time of writing, offers:
2. Setup the Python App
We are going to start in our cPanel. Once logged in, we can find the 'Setup Python App' option under 'Software' by simply typing 'python' into the search box at the top of the page. Click on this option to open.
We are presented with a simple form to start the new python application.
After clicking setup, we now have our new application listed. It is possible to install python modules from here as well as run commands, but I do not recommend it as you do not get the verbose feedback that you get from the command line.
What is important here is:
Congratulations, your python app is created and ready to start installing django. You can test it by opening up you domain in a browser.
3. Install django using the shell
We are now ready to install django from the command line. You will need the SSH details provided by our host. Hosting sites tend to not use the default port 22, so follow their instructions carefully.
ssh -p 7822 firstname.lastname@example.org
And you will be prompted for your password.
Once in, you need to activate your virtual environment using the command provided when you set up your app.
username@server [~]# source /home/username/virtualenv/domain_html/3.5/bin/activate (domain_html:3.5)username@server [~]#
Obviously, as you are in your home directory, you can drop the
/home/username/ from the above command. I have left it for simplicity sake.
You can now install django and other requirements using pip as you would in your local environment.
(domain_html:3.5)username@server [~]#pip install django
This will install the latest stable version. For information on installing a specific version, you can read the official docs.
4. Start a new project
If we change directory into the folder created when we created the python application and have a look at its contents, we will see something like this:
Leave these exactly as they are. We will be replacing passenger_wsgi.py later.
The official docs for starting a new project can be read here. In summary, to start the new django project, run the following command:
(domain_html:3.5)username@server [~/domain_html]# django-admin startproject mysite .
Please note the important . (period) at the end. This will create the project in the current folder instead of a new subfolder. This is very important. Our folder structure should now look familar, along the following lines:
domain_html/ manage.py mysite/ __init__.py settings.py urls.py wsgi.py passenger_wsgi.py public/ tmp/
5. Edit settings.py
At this stage, just to get the project running as an example, so the only change we are going to make to our settings.py file, is to put our domain in the allowed hosts. I prefer to use vim.
(domain_html:3.5)username@server [~/domain_name]# vim mysite/settings.py
ALLOWED_HOSTS = 
And insert your domain:
ALLOWED_HOSTS = ['domain.com']
Save your changes by writing and exiting.
6. Replace passenger_wsgi.py
Hosting sites use Phusion Passenger to serve ruby, python and nodejs websites. Unfortunately, django does not play well with Phusion Passenger when it comes to paths. It took me a lot of time to find a solution as the internet is littered with fixes, mostly for older versions of python and django. This is solution that I finally found and I have used it successfully with python 3.5 and django versions 1.10, 1.11, 2.0, 2.1.
I have created a gist on Github of the working passenger_wsgi.py that I use. Let us first rename the existing file.
mv passenger_wsgi.py passenger_wsgi_original.py
Next, fetch the replacement file using wget:
(domain_html:3.5)username@server [~/domain_name]# wget https://gist.githubusercontent.com/cjshaw1976/13af52c51868c92baa0c712de51f9014/raw/7c38a80c66ae87c589ef57bc3009bd36582386fc/passenger_wsgi.py
We only have to make two small changes to this new file, to accommodate our project. Open the file to edit:
(domain_html:3.5)username@server [~/domain_name]# passenger_wsgi.py
Near the end, replace the two occurrences of
projectname with the actual project name, in this example
. Write the changes and exit. We are now ready to restart the application and test.
7. Restart and test
To restart the application, we use the 'Setup Python App' in our cPannel again. Simply click the 'Restart' button on the app we created earlier. Once restarted, a green banner will flash up 'Appliciation Successfully Restarted'. If we open the domain in our browser, we should see the django welcome screen.
Getting django working on a shared server is possible. Unfortunately, there wont be much support from the hosting provider. Just sheer determination will get you started. Don't give up and share your experiences in the comment section. In the near future, I will be writing about hooking your application up with the providers MySQL or PostgreSQL databases, handling static files on a shared server and the Phusion screen of death.