Setting up a Django project on Dreamhost shared hosting
I’ve been with Dreamhost for years, and their basic shared hosting is surprisingly capable. But their documentation for getting Python projects running is really out of date.
So here are the notes I kept when I set up a new Django project on my Dreamhost shared hosting account earlier this week. Maybe they might help someone else in the future!
If you want to follow along, you’ll need to be fairly comfortable with the terminal / command line, Python, and Django.
Create a domain and a database via the Dreamhost admin panel
- Log into panel.dreamhost.com
- Go to Domains > Manage Domains and either add a new domain, or add hosting to an existing domain:
- For “Run this domain under the user”, opt to create a new user
- Tick the “Remove WWW” checkbox
- Tick the “HTTPS” checkbox
- Tick the “Passenger” checkbox
- Once the domain and user have been created, make sure to take a note of the user’s randomly-generated password – you’ll need to enter it when SSH’ing in for the first time.
- Go to Users > Manage Users, press the “Edit” button next to the user that was just created, and then:
- Tick the “Shell user” checkbox
- Tick the “Disallow FTP” checkbox
- Go to Goodies > MySQL and create a new MySQL database:
- For the “First User”, opt to create a new user
- Make a note of the password you pick – you’ll need to add it to your Django project’s
settings.py
later
SSH into the new domain
If I were doing this setup from a Linux PC, I’d be able to run ssh-copy-id
. But I’m on a Mac, so I have to copy and paste my key into authorized_keys
by hand:
-
Open up a terminal, and copy your public key to the clipboard:
$ pbcopy < ~/.ssh/id_rsa.pub
-
SSH in as the new user, and set up passwordless login:
$ ssh newuser@myproject.example.com [dreamhost]$ mkdir .ssh [dreamhost]$ chmod 700 .ssh [dreamhost]$ touch .ssh/authorized_keys [dreamhost]$ chmod 600 .ssh/authorized_keys [dreamhost]$ nano .ssh/authorized_keys
- Paste in the public key you copied, then save and exit (
ctrl-O, ctrl-W
). - End the SSH session (
ctrl-D
) and SSH back in, to check the passwordless login works.
Set up a new Python virtualenv
-
Once you’ve SSHed into the server, create a virtualenv (imaginatively named “env” here):
[dreamhost]$ cd ~/myproject.example.com/ [dreamhost]$ virtualenv env
-
Activate the virtualenv, and install the django and mysql-python packages:
[dreamhost]$ cd ~/myproject.example.com/ [dreamhost]$ . env/bin/activate (env)[dreamhost]$ pip install django mysql-python
Eventually, you’ll probably want to include these packages in a
requirements.txt
file that gets pip-installed automatically into the virtual environment by whatever deployment system you decide to use.
Set up a new a Django project
-
Create a new Django project (named “myproject” here):
(env)[dreamhost]$ django-admin startproject myproject
-
Edit
my-project/my-project/settings.py
to and set the database details:DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'my_dreamhost_database_name', 'USER': 'my_dreamhost_database_user', 'PASSWORD': 'my_dreamhost_database_password', 'HOST': 'mysql.example.com', 'PORT': 3306, } }
-
Add this after the
STATIC_URL
line at the end of the file:STATIC_ROOT = os.path.dirname(BASE_DIR) + '/public/static/'
-
Create a
static
directory:(env)[dreamhost]$ mkdir -p public/static
-
Finish setting up your Django project:
(env)[dreamhost]$ python myproject/manage.py collectstatic (env)[dreamhost]$ python myproject/manage.py migrate (env)[dreamhost]$ python myproject/manage.py createsuperuser
Tell Dreamhost to serve your Django project via WSGI
-
Create a
passenger_wsgi.py
file that runs your Django application when visitors request pages at your domain.(env)[dreamhost]$ nano ~/myproject.example.com/passenger_wsgi.py
And put this into it:
import os import sys cwd = os.getcwd() env_dir = os.path.join(cwd, 'env') project_dir = os.path.join(cwd, 'myproject') # Use the python executable from inside our virtualenv # https://help.dreamhost.com/hc/en-us/articles/215769548 INTERP = os.path.join(env_dir, 'bin', 'python') if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) # Add virtualenv packages to the start of the path sys.path.insert(0, os.path.join(env_dir, 'bin')) sys.path.insert(0, os.path.join(env_dir, 'lib', 'python2.7', 'site-packages')) sys.path.insert(0, os.path.join(env_dir, 'lib', 'python2.7', 'site-packages', 'django')) # Add brickwatch django project to the *end* of the path # (so it will be checked last). sys.path.append(project_dir) # Set environment variables for django to use os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings' from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
-
Set up a
restart.txt
file (Dreamhost’s approved way of restarting the Passenger process that routes requests to your Django project):(env)[dreamhost]$ mkdir ~/myproject.example.com/tmp (env)[dreamhost]$ touch ~/myproject.example.com/tmp/restart.txt
- When you visit
myproject.example.com
in a web browser you should see an “It worked! Congratulations on your first Django-powered page.” message from Django. - Visit
myproject.example.com/admin
and check that the page looks right. If the page is missing its CSS styles, then yourSTATIC_ROOT
and/orSTATIC_URL
haven’t been set up properly. - Remember, if you make any changes to
passenger_wsgi.py
, you need totouch tmp/restart.txt
(as above) to notify the Passenger process that it needs to load your new settings.