Django is a web app framework for Python (similar to Rails for Ruby). It implements common web app features so you don't have to write that code. Dreamhost is a web host that offers cheap but reliable web servers. Their shared hosting plan is $11 a month, and provides more than enough disk space and bandwidth for personal sites.
(If you'd like to help Invent with Python, use this link to sign up for Dreamhost.)
I wanted to create a Django web app for my https://turtleappstore.com site to let others share Minecraft code projects for ComputerCraft. The process took some time to figure out, so I documented it here. Note that this tutorial is specific to Dreamhost, Django 1.10.6, and Python 3.6. The steps may vary if you use different versions or web hosts.
After you have purchased a shared hosting plan from Dreamhost, go to https://panel.dreamhost.com/ and log into your Dreamhost account. This tutorial assumes you have also registered for a domain name. From the sidebar, click Domains > Manage Domains, then click the Edit link next to the domain name you want to host the Django app. In this tutorial, I will be using example.turtleappstore.com for the domain name. Replace this with your domain name in any commands in this tutorial.
You will see the configuration details for this domain name. Make sure that the Passenger (Ruby/NodeJS/Python apps only) checkbox is checked. This will also make the web directory end with
public, such as
/home/username/example.turtleappstore.com/public. The page will look like this:
Aside: If you have multiple domain names with Dreamhost, I recommend creating a separate user for each one. (From the sidebar, click Users > Manage Users.) If the account or site is hacked, it will only affect that single domain instead of possibly all of your domains.
The user account that manages this domain name must have "shell access". From the sidebar, click Users > Manage Users, then click the Edit link next to the user. Next to User Type, select "Shell user". This will allow you to SSH into the shared hosting server that the web server is running on.
SSH into the Server
Using an SSH program (such as Putty on Windows, or the SSH program on Mac/Linux). Connect to your server (in my case,
example.turtleappstore.com) using your shell user's username and password (not the Dreamhost username/password you used for https://panel.dreamhost.com/.)
Download and Install Python 3.6.0
Enter the following commands (not the
[server]$ part, that's the shell prompt):
[server]$ cd ~ [server]$ cd example.turtleappstore.com/ [server]$ mkdir tmp [server]$ cd tmp [server]$ wget https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tgz [server]$ tar zxvf Python-3.6.0.tgz [server]$ cd Python-3.6.0 [server]$ ./configure --prefix=$HOME/opt/python-3.6.0 [server]$ make [server]$ make install
Some of these commands will take a few minutes to run and output a lot of text. You shouldn't encounter any error messages, but if you do you'll need to figure out what is causing them. Try googling the error message to see if others have encountered it and described the solution.
export PATH=$HOME/opt/python-3.6.0/bin:$PATH to the bottom of your
~/.bash_profile files so that when your web server runs Python, it runs the Python 3.6.0 program you just installed and not Dreamhost's default Python (which is 2.7, as of 2017/03/14). Use a text editor such as vi or vim to do this.
Then run the following to set the system path in your current SSH session (or logout and log back in):
[server]$ source ~/.bash_profile
pip3 will use the Python you just installed by running the following and checking their output:
[server]$ which python3 /home/your_username/opt/python-3.6.0/bin/python3 [server]$ which pip3 /home/your_username/opt/python-3.6.0/bin/pip3
With Python installed, you can now delete the temporary install files by running the following:
[server]]$ rm ~/example.turtleappstore.com/tmp/* -rf
Download and Install Virtualenv
Virtualenv is a tool to keep installed modules separate for separate projects. This way, if you are working on one Python project that requires Django 1.10.6 and another that requires Django 1.3, you won't be constantly installing and uninstalling Django modules as you work on them. Virtual environments are a good idea to have.
Run the following to install the virtualenv Python module:
[server]$ pip3 install virtualenv
Confirm that virtualenv was installed by running the following and checking the output:
[server]$ which virtualenv /home/[username]/opt/python-3.6.0/bin/virtualenv
According to the venv documentation, in Python 3.6 you don't use
pyenv but instead
python3 -m venv to prevent confusion as to which Python interpreter the virtual environment will be based on.
Next, create a virtual environment for your project. I'll call mine
[server]$ python3 -m venv ~/tas_venv
From now on, before you install/unintall Python modules or run any Django scripts such as manage.py, you will need to make sure the virtual environment for your web app project is activated. Run the following:
[server]$ source ~/tas_venv/bin/activate (tas_venv) [server]$
You'll see the
(tas_venv) prompt come up. To exit the virtual environment, just run
Download and Install Django
tas_venv (or whatever you named it) virtual environment set up, install Django by running this:
(tas_venv) [server]$ pip3 install django==1.10.6
You can verify Django installed properly from the Python interactive shell:
(tas_venv) [server]$ python3 Python 3.6.0 (default, Mar 14 2017, 18:13:54) [GCC 4.6.3] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import django >>> django.VERSION (1, 10, 6, 'final', 0)
Create the Django project for your site. I'm going to name mine tasproject:
(tas_venv) [server]$ cd ~/example.turtleappstore.com/ (tas_venv) [server]$ python3 ~/tas_venv/bin/django-admin.py startproject tasproject
Setup Passenger & Django
To finish setting up your site, create a file passenger_wsgi.py in the root of your website directory using a text editor. Add the following to it:
import sys, os cwd = os.getcwd() sys.path.append(cwd) sys.path.append(cwd + '/tasproject') INTERP = os.path.expanduser("~/tas_venv/bin/python3") if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) sys.path.insert(0,'$HOME/tas_venv/bin') sys.path.insert(0,'$HOME/tas_venv/lib/python3.6/site-packages/django') sys.path.insert(0,'$HOME/tas_venv/lib/python3.6/site-packages') os.environ['DJANGO_SETTINGS_MODULE'] = "tasproject.settings" from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
(tas_venv is the name of the virtual environment, while tasproject is the name of the Django project.)
Also add the following line to the ~/example.turtleappstore.com/tasproject/tasproject/settings.py file:
STATIC_ROOT = os.path.dirname(BASE_DIR) + '/static/'
Passenger causes Django to handle web server requests. However, I've been having problems getting static files to work correctly on Dreamhost, so I use the
public folder to server all static files by placing a
static subfolder under the
public folder. I'll update this blog post if I figure out a way to get static files to work properly through Django. Note that Dreamhost will check the
public folder first for URL requests, and then check Django's urls.py file next.
Finally, create a restart.txt file to cause Passenger to reload your passenger_wsgi.py script:
[server]$ touch ~/example.turtleappstore.com/tmp/restart.txt
At this point, you should be able to open example.turtleappstore.com in a web browser and see Django's default "It worked!" page. Whenever you make a change, you need to re-touch the restart.txt file for Passenger to pick up the changes. Note that Passenger will handle all requests made to the example.turtleappstore.com. You can now start creating apps and working on your Django project as you normally would.