Django

From DreamHost

Jump to: navigation, search

Django is a framework for python. In the same way the rails is a framework for ruby. See the official website and the official book for more details. Django can be deployed via FastCGI on dreamhost.

Contents

[edit] Considerations

If Django is crucial to your site, you may wish to consider another host since Dreamhost does not officially support Django. In the past, some users have reported reliablity problems; however, others have had no problems.

Another important consideration is that if you are planning on developing a heavily used application, a shared environment will probably not suffice due to the heavy CPU load. Enable CPU reporting for your user and keep an eye on your usage. Extremely heavy usage (200+ minutes) is an indication that you should look into tuning your site. Any site that severely disrupts service for other users could be disabled without warning.

Yet another important consideration is that as of revision 4724, Django raises an error if you try to use the MySQL backend with a MySQLdb version earlier than 1.2.1p2. It's possible to use the 'mysql_old' backend, but it is officially deprecated, so there's no telling how long this will be an option.

[edit] 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. (It 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.

[edit] 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'd rather use MySQL then just edit the settings appropriately here.
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 += ['/home/myuser/django_src']
sys.path += ['/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
$ chmod +x ~/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 line.
  • Touch the dispatch.fcgi to reload the code
$ touch ~/mydomain.com/dispatch.fcgi

[edit] Troubleshooting

[edit] 500 errors and Incomplete Header in logs

Dreamhost apparently runs a background process to kill zombie processes. This can cause issues for FastCGI dispatchers (like the one needed to get Django working). Because of this, Dreamhost updated their zombie-killer to avoid dispatch.fcgi; in other words, if you don't rename the file mysite.fcgi to dispatch.fcgi your site will not work. The file name is different than the one mentioned on various other tutorials.

You must also use
#!/usr/bin/python2.4
as the first line of dispatch.fcgi. Using #!/usr/bin/env python2.4 confuses the procwatch background process.

[edit] ImportError: No module named mysql.base

Using

DATABASE_ENGINE = 'mysql_old'

in your project's settings.py file resolves this problem.

[edit] AttributeError: type object 'unicode' has no attribute 'decode'

Calling manage.py using Python 2.4 resolves this problem:

$ python2.4 manage.py

[edit] A better way

Mod_fastcgi on apache is, frankly, appalling. There are two alternatives that have been suggested and you can vote on:

[edit] Misc.

  • Ask support to raise your memory limit, as described on Python_FastCGI.
  • A lot of errors can be fixed by updating django and flup to the latest versions through svn.
  • Make sure FastCGI is enabled for your site in the Dreamhost panel.
  • 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.3
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

[edit] 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").

[edit] 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'.)

[edit] Specific Errors

If you are using a FloatField in your model and get a TypeError exception with value "float argument required" when trying to view objects with this field in the admin interface, take a look at this ticket and fix. Dreamhost is using a version of MySQL-Python that is susceptible to this. A fix is to install your own local version of MySQL-python-1.2.2.

[edit] Performance Improvements

Shared environment forces users to use some tricks to improve overall performance of web applications. Django provides many ways to do it:

The latter two can be achieved by placing a specially crafted .htaccess in top static file directories (like media/, appmedia/). The one I use is here:

ExpiresActive on
ExpiresDefault "access plus 15 minutes"
ExpiresByType image/gif "access plus 1 hours"
ExpiresByType image/png "access plus 1 hours"
ExpiresByType image/jpeg "access plus 1 hours"
ExpiresByType image/x-icon "access plus 1 hours"
ExpiresByType application/x-javascript "access plus 15 minutes"
ExpiresByType text/css "access plus 1 hours"

SetOutputFilter DEFLATE
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE\s6 no-gzip
BrowserMatch \bMSIE\s7 !no-gzip !gzip-only-text/html
SetEnvIfNoCase Request_URI \
        \.(?:gif|jpe?g|png|pdf|swf|ipk)$ no-gzip dont-vary
Header append Vary User-Agent env=!dont-vary

Warning! The above file works only for Apache 2.0! If you still use Apache 1.3, please talk to DreamHost support to switch you over to Apache 2.0.

Personal tools