[Answer]-Deploying Django – Dreamhost


This is how I do it, with Django 1.5, on DreamHost:

  • A virtualenv dedicated to my project is in ~/virtualenv/myproject

  • My Django project is in ~/projects/myproject, with setup:

    • The database file is in the project root, named sqlite3.db
    • STATIC_ROOT is set to os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', 'static'), that is, the static directory in the project root.
    • When the static files are updated in the project, I have to run python manage.py collectstatic
    • I have per-environment settings in ~/projects/myproject/myproject, named prod_settings.py, beta_settings.py, and so on.
  • My site is in ~/sites/www.myproject.com, the layout inside:

    • myproject — symlink to the Django project
    • sqlite3.db — symlink to the database file in the Django project
    • public/static — symlink to the STATIC_ROOT defined in the Django project
    • tmp/restart.txttouch this file to have Passenger reload the site settings
    • passenger_wsgi.py — the Passenger configuration

Create passenger_wsgi.py like this:

projectname = 'myproject'
virtualenv_root = '/home/jack/virtualenv/' + projectname

import sys
import os

INTERP = os.path.join(virtualenv_root, 'bin', 'python')
if sys.executable != INTERP:
    os.execl(INTERP, INTERP, *sys.argv)

sys.path.append(os.path.join(os.getcwd(), projectname))
os.environ['DJANGO_SETTINGS_MODULE'] = projectname + '.prod_settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Create prod_settings.py like this:

from myproject.settings import *

DEBUG = False

ADMINS = (('My Project', 'info@myproject.com'), )
DATABASES = {}  # Appropriately for your production environment
SECRET_KEY = "..."  # Your secret key
ALLOWED_HOSTS = ["myproject.com", "www.myproject.com"]

For Django 1.4 or earlier, you need to make some minor modifications, but the same idea works. I’ve been using variations of this setup since Django 1.2.

I setup virtualenv like this:

# install pip and virtualenv in my home directory
easy_install --user pip
pip install --user virtualenv

# create a virtualenv dedicated to my django project
mkdir ~/virtualenv
virtualenv --distribute ~/virtualenv/myproject

# activate the virtualenv, install django and all project dependencies
. ~/virtualenv/myproject/bin/activate
cd ~/projects/myproject
pip install -r requirements.txt

Notice that after activating the virtualenv, you don’t need the --user flag anymore when you install packages with pip. When a virtualenv is active, all packages are installed in that virtualenv.

About requirements.txt:

  • Create it in your development like this: pip freeze > requirements.txt
  • Edit it, leave only the packages that your project really really needs. It’s better to remove too much and add back later as needed.

Note that virtualenv is not necessary, but recommended. You can do without by setting INTERP in your passenger_wsgi.py to /usr/bin/python. virtualenv is useful to have multiple Django sites with different dependencies on the same account. It is also useful when you want to upgrade Django for your site, so that you can test the upgrade on beta.myproject.com without disrupting traffic on your main site.

Finally, if you are using shared hosting, DreamHost support encourages using different user accounts for each website, but I don’t know what difference that makes. Be careful with heavy operations, for example large data imports, because if the process uses much memory, it can get killed by DreamHost. The memory ceiling is unspecified, but it’s quite low. So if your site needs to do some heavy operations, you need to make such operations fault tolerant, in order to resume after killed.


Leave a comment