Django FastCGI

From DreamHost

Jump to: navigation, search
The instructions provided in this article or section are considered advanced.

You are expected to be knowledgeable in the UNIX shell.
Support for these instructions is not available from DreamHost tech support.
Server changes may cause this to break. Be prepared to troubleshoot this yourself if this happens.
We seriously aren't kidding about this.

These instructions detail how to set up Django using FastCGI. Note that Dreamhost now recommends the use of Passenger WSGI for setting up Django applications, as detailed in the how-to at Django, as this approach is easier to set up and creates applications that run faster.

Contents

Prerequisites

  • FastCGI must be enabled for the site on which you intend to run Django.
  • Enable SSH access and request the default bash shell.
  • You'll need to use Subversion to download the latest version of Django's source code. (Subversion should be installed by default. Use the command 'which svn' to ensure that Subversion is already installed.)
  • Make sure that your web site works without Django and you can navigate subdirectories and see files without any problems. If you are getting the "503 Service Temporarily Unavailable" error, please read Referer Gotcha before using Django.

Setup

These instructions are based in part on Jeff Croft's article. It is assumed that you have a hosted domain such as www.mydomain.com and can create a subdomain to host media files. These instructions should work just as well if you'd rather install Django on a subdomain.

We will use the following for username, domain, and project. These should be replaced with your own details.

username = myuser
domain = mydomain.com
media domain = media.mydomain.com
project = myproject
  • Enable 'FastCGI Support' on mydomain.com in the Dreamhost control panel (Domains -> Manage Domains -> Web Hosting Column, Edit -> Fast CGI Support?)
  • Create a media subdomain in Dreamhost control panel, media.mydomain.com
  • Create a directory in your home directory to contain your Django projects:
$ mkdir django_projects
  • Download the latest Django source code
$ svn co http://code.djangoproject.com/svn/django/trunk/ django_src

Note: If you have previously followed the Python documentation you can run the following and not have to add anything to the PATH or follow the next 2 steps.

easy_install django_src
  • Otherwise, without easy_install, edit .bash_profile to add Django to your path and python path
export PATH=$PATH:$HOME/django_src/django/bin
export PYTHONPATH=$PYTHONPATH:$HOME/django_src:$HOME/django_projects
  • Reload .bash_profile
$ source .bash_profile
  • Link admin_media to your media domain from the Django source code
$ ln -s $HOME/django_src/django/contrib/admin/media $HOME/media.mydomain.com/admin_media
  • Start a new project in django_projects
$ cd django_projects
$ django-admin.py startproject myproject
$ chmod 600 myproject/settings.py
  • Edit ~/django_projects/myproject/settings.py. SQLite is perfectly usable for test sites. If you would rather use MySQL then just edit the settings appropriately here. (For MySQL, in case your DreamHost server does not have it already, you will also have to download and [easy_]install the MySQL-Python module, or else you will see error messages)
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = '/home/myuser/django_projects/myproject/myproject.db'
TIME_ZONE = 'US/Pacific'
MEDIA_ROOT = '/home/myuser/media.mydomain.com/'
MEDIA_URL = 'http://media.mydomain.com/'
ADMIN_MEDIA_PREFIX = 'http://media.mydomain.com/admin_media/'
Add django.contrib.admin to INSTALLED_APPS
  • Change to webroot directory for mydomain.com and download fcgi.py
$ cd ~/mydomain.com
$ wget http://svn.saddi.com/py-lib/trunk/fcgi.py
  • Edit ~/mydomain.com/dispatch.fcgi
#!/usr/bin/python2.4
import sys
sys.path.insert(1, '/home/myuser/django_src')
sys.path.insert(1, '/home/myuser/django_projects')
from fcgi import WSGIServer
from django.core.handlers.wsgi import WSGIHandler
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
WSGIServer(WSGIHandler()).run()
  • Make ~/mydomain.com/dispatch.fcgi and ~/mydomain.com/fcgi.py executable. It is important to make sure that they are not group writable, otherwise some dreamhost servers will not be able to run the scripts.
$ chmod 755 ~/mydomain.com/dispatch.fcgi ~/mydomain.com/fcgi.py
  • Edit ~/mydomain.com/.htaccess
RewriteEngine On
RewriteBase /
RewriteRule ^(dispatch\.fcgi/.*)$ - [L]
RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]
  • Initialize the DB for your project and create an admin user
$ ~/django_projects/myproject/manage.py syncdb
  • Load http://www.mydomain.com/ in a browser and you should see the "It worked!" page.
  • Edit ~/django_projects/myproject/urls.py and uncomment the admin lines.
  • Touch the dispatch.fcgi to reload the code
$ touch ~/mydomain.com/dispatch.fcgi

Troubleshooting

Run dispatch.fcgi from the commandline

It may help to find the cause of problems by manually running dispatch.fcgi from the commandline.

./dispatch.fcgi

Django should output its HTML to your shell. You can safely ignore "WSGIServer: missing FastCGI param" errors.

AttributeError: type object 'unicode' has no attribute 'decode'

This error may appear if your server defaults to Python 2.3 or earlier. Explicitly running manage.py with Python 2.4 resolves this problem:

$ python2.4 manage.py

Misc.

  • A lot of errors can be fixed by updating django and flup to the latest versions through svn.
  • Double-check your usernames, passwords, database names, and hostnames in the settings file.
  • Verify that FastCGI is working. Create a file named hello.fcgi with the following text.
#!/usr/bin/python2.4
from flup.server.fcgi import WSGIServer
def test_app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    yield 'Hello, world!\n'

WSGIServer(test_app).run()

Make sure to set the correct permissions.

chmod 755 hello.fcgi
  • NOTE: For this to work, you'll still need to load up your environment (I.E. that pythonpath you'll be setting in the tutorials below). Just to verify fastcgi works, just copy the "flup" directory from your django_src (or wherever you decide to store that) over to the directory you're testing from.

Then try to load http://django.mydomain.com/hello.fcgi.

  • Once you've proven that FastCGI is working, check your sys.path settings in dispatch.fcgi. Make sure you added the directory that contains "django", and not the django directory itself! In other words, put /home/username/django_src in your sys.path, not /home/username/django_src/django.
  • If you make changes to the code, such as working through the official tutorials, and they don't seem to work, make sure to kill any existing python processes and reload the page.
pkill python
  • Also, in addition to killing the python processes, you also have to tell FastCGI that a file/code has been changed. This is pretty simple, just reupload dispatch.fcgi, or edit the file, so that the timestamp on the file will change. When Apache sees the file has been updated, it will restart your Django application for you. You can use the touch command to update the file's timestamp. Just go to the site directory, where you placed your dispatch.fcgi file and use the touch command:
touch dispatch.fcgi

mod_rewrite

To be able to login and actually use the django admin pages you will need to set up a mod_rewrite rule in your .htaccess file.

If you want everything to be run by dispatch.fcgi, you can use the following set of rewrite rules. Order is important!

RewriteEngine On
RewriteBase /
RewriteRule ^(media/.*)$ - [L]
RewriteRule ^(appmedia/.*)$ - [L]
RewriteRule ^(dispatch\.fcgi/.*)$ - [L]
RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]

All directories and files not managed by Django, should go before the last line. E.g., if you want to use Analog 6.0 web stats application (supplied by DreamHost), you should add following three lines before Django instruction (taken from Mod_rewrite):

RewriteCond %{REQUEST_URI} ^/stats/(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^/failed_auth.html$
RewriteRule ^.*$ - [L]

For example, if you want to add favicon.ico, which can be actually located in appmedia/favicon.ico:

RewriteRule ^(favicon\.ico)$ appmedia/favicon.ico [L]

And so on.

1st part of rewrite rule is a regex pattern to be matched. 2nd part is a replacement ("-" means don't rewrite the url). 3rd part is a command ("L" means "last" => "this is the last rule, quit rewriting after successful application of this rule").

Media Files

For the admin pages to be able to access the correct CSS and JavaScript files, you'll need to set up a media directory.

ln -s $HOME/django_src/django/contrib/admin/media $HOME/django.mydomain.com/admin_media

Now surfing to http://django.myproject.com/media/ should give you a directory listing:

css
img
js

(It is possible to rename the effective name of the media directory for the admin app through a conf setting. This will be required if you decide that you want your own media in a subdirectory named 'media'.)

Helpful Links

Personal tools