Alex’s posterous

 
Filed under

bluehost

 

Getting Django working on bluehost

I did this a few months ago, and it turns out there were a few tricks involved. Firstly, bluehost don't really support Django yet, their provided version of Python is only 2.3, and Subversion isn't installed. Their hosting has been otherwise brilliant, though, and for around $8 a month I am getting unlimited traffic, disk space, addon domains and about 100 mysql and postgresql databases. But I digress...

Here's an outline of what I did:

  1. Install Python
  2. Install Subversion
  3. Check out and install Django from source
  4. Install MySQLdb
  5. Get Apache to work with Django
  6. Put your Django code under Subversion control
  7. Next steps: a real Django app

I made (varying amounts of) use of these resources: [1] [2] [3].

Note: these steps require you to have SSH access into your box - see the bluehost support site or your cPanel for details on getting this enabled. It also assumes you know how to connect to your box via SSH using your terminal (if Linux) or with something like PuTTy (Windows).

1. Install Python

Wonder over to the Python download page, and copy the URL to the compressed tarball for your version of choice (at the time of writing, I would recommend the latest 2.5 release as this works well with Python mysqldb).

SSH into your box, and make a 'src' directory just inside your home dir:
mkdir src

Download and unzip the source:
cd src
wget http://python.org/ftp/python/2.5.2/Python-2.5.2.tgz
tar xzf Python-2.5.2.tgz

Install Python to your home directory. We're going to run everything out of your home dir instead of using the default (older) Python that bluehost have installed. To do this, we need to tweak the the install script slightly:
cd Python-2.5.2
./configure --prefix="$HOME"
make
make install

Get your shell running the new Python. To do this, we need to edit your '.bash_profile' located in your home directory. Open it up with vim:
cd
vim .bash_profile Use the arrow keys to move around, and press i to insert. Make sure these two export statements look as follows:
export PATH=$HOME/bin:${PATH}:$HOME/django_src/django/bin
export PYTHONPATH=$HOME/django_src:$HOME/django_projects Save by pressing Escape then type ':wq' to write and quit the editor. If you make any mistakes, pressing Escape then typing ':q!' will quit without saving.

Reload your shell, and run the python interpreter:
source ~/.bash_profile
python If all goes well you should see "Python 2.5.2" at the top. Quit the interpreter with Ctrl+d.

2. Install Subversion

Subversion is really handy for keeping your software up-to-date, not to mention acting as a great source code repository. Luckily, tabruyn.com has written a good how-to guide for bluehost!

Follow his step #2, but note that the libraries such as apr, apr-util, neon, and subversion itself, have since had new releases. Find the URLs to the new releases, and use the new directories / filenames as appropriate. When installed correctly, running 'svn' in the terminal will give the message 'Type 'svn help' for usage.'

3. Checkout latest Django from source

Now that we've got subversion installed, we can easily check out the development version of Django (2 lines):
cd
svn co http://code.djangoproject.com/svn/django/trunk/ django_src Let that run, and it'll download the latest source. To keep it up-to-date with the very latest changes all we have to do is run 'svn update' from within the ~/django_src/ folder at a later time. Note that in step 1 we already set your shell's PYTHONPATH to include this folder: Python can now import and run Django!

 

4. Install MySQLdb

Assuming you're going to use MySQL (bluehost's database of choice), you'll need the MySQLdb Python wrapper in order to talk to your databases. You can grab the latest tar.gz, unzip, and run 'setup.py install' to get it installed, or use the Python .egg version if you prefer.

5. Get Apache to work with Django

We're going to run Django through the fast-cgi protocol, because that's what bluehost allows for. Firstly, we need to install the handy fast-cgi Python extension flup. Download and install the latest version (currently flup-1.0.1) (5 lines):
cd ~/src
wget http://www.saddi.com/software/flup/dist/flup-1.0.1.tar.gz
tar -xzf flup-1.0.1.tar.gz
cd flup-1.0.1
python setup.py install This should install the '/flup-1.0.1-py2.5.egg' package inside your '~/lib/python2.5/site-packages' directory.

Note: flup 1.01 installation may require a slightly later version of setuptools (thanks to EricClemmons for spotting this):
cd src
wget http://pypi.python.org/packages/2.5/s/setuptools/setuptools-0.6c9-py2.5.egg
python setuptools-0.6c9-py2.5.egg

Now, create a Django project in your ~/django_projects directory:
cd ~/django_projects
django-admin.py startproject mysite This will create the folder '~/django_projects/mysite' – and note that this, like 'django_src', is already in your PYTHONPATH so you should have no problems importing the project.

Now - you need to decide if you want your entire site running through Django, or just a sub-folder. If you want your entire site Django-ified, create the following file in your root directory, making sure to edit the first line as appropriate to point to your home directory. Use vim for this, you can paste it in and ':wq' to save the file.

django.fcgi (8 lines):
#!/home/USER/bin/python
import sys, os
sys.path.insert(0,"/home/USER/django_src")
sys.path.insert(0,"/home/USER/django_projects")
from flup.server.fcgi import WSGIServer
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
from django.core.handlers.wsgi import WSGIHandler
WSGIServer(WSGIHandler()).run() ^ Make sure to replace 'mysite' with the name of the project you've created in django_projects, and 'USER' with your bluehost username. Save the file as 'django.fcgi' and make it executable:
chmod a+x django.fcgi

Now, you need to tell apache to run requests using django.fcgi by creating the appropriate .htaccess file depending on whether you're running this in a subfolder, or at site root:

.htaccess (if site root):
AddHandler fcgid-script .fcgi
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^(media/.*)$ - [L]
RewriteRule ^(adminmedia/.*)$ - [L]
RewriteCond %{REQUEST_URI} !(django.fcgi)
RewriteRule ^(.*)$ django.fcgi/$1 [L]

.htaccess (if in a subdirectory):
AddHandler fcgid-script .fcgi
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^(adminmedia/.*)$ - [L]
RewriteRule ^(django\.fcgi/.*)$ - [L]
RewriteRule ^(.*)$ /subdirectoryname/django.fcgi/$1 [L] ^ replace subdirectoryname as appropriate

The above rules basically tell certain requests to pass straight through, allowing certain folders or elements to act as normal static website directories (e.g. 'media' and 'adminmedia'), and sets everything else to be run through django.fcgi.

To set up the 'adminmedia' directory correctly – allowing your site to get at the css and js files bundled with the Django admin, you'll need to create a symbolic link to it, adding in the subdomain if appropriate here (all one line):
ln -s $HOME/django_src/django/contrib/admin/media $HOME/www/mysite/adminmedia

Right, time to check if it's all worked! Visit your site root (or subdomain) and you should see the generic 'it worked!' Django page in lovely pastel shades. If you're seeing the contents of django.fcgi then you've not made it executable.

6. Put your Django code under Subversion control

I've got Subversion set up so that when I commit changes to the repository it automatically updates my project code in django_projects -- and therefore changes the site in real-time. Probably not suitable for a production server, but that's just how I roll ;)

Firstly, create a directory for your svn repositories to live in:
cd
mkdir svn
cd svn Then make a repo for your current django project:
svnadmin create --fs-type fsfs myproject
chmod -R 755 myproject

You can now import existing Django project code – for revision 0 – (again, one line here):
svn import /home/USER/django_projects/myproject file:///home/USER/svn/myproject --message="Importing initial code" Your django code is now stored safely in your svn repository. Now, the trick here is to DELETE (yes, you read that right) your django project directory, and check it out from svn:
cd ~/django_projects
rm -rf mysite
svn checkout file:///home/USER/svn/myproject /home/USER/django_projects/myproject

You'll now have checked out your own code from the repo. To update the production code (the stuff living in django_projects) you can just cd into the project directory and run 'svn update'. Exciting stuff, eh!

Note: If you're running Windows, you can follow the rest of tabruyn's tutorial (step #5 onwards) to get your local machine checking out + committing properly to your bluehost box. I've yet not done it on a linux box so I can't advise here.

Optional: If you want, like me, to update the production code in django_projects with each commit (instead of manually running 'svn update') you can set up a Subversion post-commit hook. Jump to the 'hooks' folder inside your svn repo:
cd ~/svn/myproject/hooks Make a copy of the post-commit template, and save it as an executable file named 'post-commit':
cp post-commit.tmpl post-commit
chmod a+x post-commit

Now edit the post-commit file in vim and comment in (make the first character of the line a '#') the commit-email.pl and log-commit.py lines. At the bottom, insert your own line:
/home/USER/bin/svn update /home/USER/django_projectsl/mysite This will run subversion after a commit, telling it to check the latest version of your project out from the repository.

7. Next steps: a real Django app

To get Django working with mysql, you'll need to create a database for the project, and assign a specific mysql user to the database with all permissions. You can do this using the 'MySQL Databases' wizard in your cPanel. Or by hand using your terminal. You then need to tell django what db engine to use.

Settings.py:
DATABASE_ENGINE = 'mysql' DATABASE_NAME = 'USER_mydb' DATABASE_USER = 'USER_mydbuser' DATABASE_PASSWORD = 'mydbpassword' DATABASE_HOST = '' # blank DATABASE_PORT = '' # blank ^ use your own details as appropriate.

You'll now be able to initialise real django apps from inside your project folder:
./manage.py startapp myapp

Note, this creates a new subfolder folder and various .py files needed by Django for that app. This new addition won't be under subversion control, so you'll have to import the project again to add it to svn (see step #6).

Important: When changes are made to the Django code, they will not be instantly updated whilst the django.fcgi process is still running. To see the changes, you need to kill the fast-cgi process which will force it to re-read your code. Manually killing the process is fairly tedious, so luckily I've found a handy bash script which will do the work for me. I have it saved as 'k' within my project directory (7 lines):
#!/bin/sh
# PYTHON SCRIPT PROCESS KILLER by GBO v0.1
# This script will look for all the lines containing $SOFTWARENAME in the process list, and close them
SOFTWARENAME='django.fcgi' # This is case insensitive
JOBPRESENT=$(ps -ef | grep -i $SOFTWARENAME | grep -v grep)
echo $JOBPRESENT
ps -ef | grep -i $SOFTWARENAME | grep -v grep | awk '{print $2}' | xargs kill Be sure to chmod a+x the file, then you can reload your code by running './k' from the terminal.

Filed under  //   bluehost   django   python  

Comments [1]