Chris Shaw

Chris Shaw

Lead Profile All Articles

I am an ardent software developer and eager lifelong learner of code. My passion is the python language with particular emphasis in the 'django' and  'opencv' packages. I have created this blog to share my e... Read More

Tutorials


Hosting your Django project with a2hosting.

Jan. 28, 2019 Chris Shaw 103 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.

1. Prerequisites

  1. Hosting package
  2. Registered domain
  3. Basic SSH experience

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: 

  • Unlimited Websites
  • Unlimited Databases
  • Unlimited Storage
  • Unlimited Transfer

 

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.

  • Python version: I stick to 3.5 as it is stable and provides reliable results.
  • App Directory: This is the folder un which our app will reside. I recommend you let the app create the folder for you. As I run multiple domains & projects, I use the naming convention domainname_html. This folder will be created in your home directory.
  • App Domain/URI: This is a list of your domains and sub-domains, with your primary selected as a default. 

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:

  • Command for entering the virtual environment: You will need this, so keep it handy.
  • Restart Button: You will use this often to reload the application after making changes.
  • Remove Button: WARNING, do not press this accidently. Pressing it will remove the application WITHOUT CONFIRMATION.

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 username@server.a2hosting.com

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

Look for:

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.

(domain_html:3.5)username@server [~/domain_name]# 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 mysite. 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.

 

Summary:
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.


Related Articles

Tags: django Hosting
blog comments powered by Disqus