Installing Django on Shared Hosting (Site5)

This article is a related to my previously posted article about installing Django, an advanced Web framework for perfectionists, on your own computer. Now we will learn how to install Django on a shared hosting account, using Site5 and fastcgi as an example. Depending on your host, you may or may not have to request additional privileges from the support team in order to execute some of these commands.

Note: Django requires at least Python 2.3. Newer versions of Python are preferred.

Note: This HOWTO assumes familiarity with the UNIX/Linux command line.

Note: If the wget command doesn't work for you (as in you don't have permission to run it), you might try curl [url] -O instead. That's a -O as in upper-case o.

Install Python

Site5 (and many other shared hosting providers that offer SSH access) already has Python installed, but you will want to have your own copy so you can install various tools without affecting other users. So go ahead and download virtual python:

mkdir ~/downloads
cd ~/downloads
wget http://peak.telecommunity.com/dist/virtual-python.py

Virtual Python will make a local copy of the installed Python in your home directory. Now you want to make sure you execute this next command with the newest version of Python available on your host. For example, Site5 offers both Python 2.3.4 and Python 2.4.3. We want to use Python 2.4.3. To verify the version of your Python, execute the following command:

python -V

If that displays Python 2.3.x or anything earlier, try using python2.4 -V or python2.5 -V instead. Whichever command renders the most recent version of Python is the one you should use in place of python in the next command. Since python -V currently displays Python 2.4.3 on my Site5 sandbox, I will execute the following command:

python ~/downloads/virtual-python.py

Again, this is just making a local copy of the Python installation that you used to run the virtual-python.py script. Your local installation is likely in ~/lib/python2.4/ (version could vary).

Make Your Local Python Be Default

To reduce confusion and hassle, let's give our new local installation of Python precedence over the system-wide Python. To do that, open up your ~/.bashrc and make sure it contains a line similar to this:

export PATH=$HOME/bin:$PATH

If you're unfamiliar with UNIX-based text editors such as vi, here is what you would type to use vi to make the appropriate changes:

  • vi ~/.bashrc to edit the file
  • go to the end of the file by using the down arrow key or the j key
  • hit o (the letter) to tell vi you want to start typing stuff on the next line
  • type export PATH=$HOME/bin:$PATH
  • hit the escape key
  • type :x to save the changes and quit. Don't forget the : at the beginning. Alternatively, you can type :wq, which works exactly the same as :x.

Once you've made the appropriate changes to ~/.bashrc, you need to make those changes take effect in your current SSH session:

source ~/.bashrc

Now we should verify that our changes actually took place. Type the following command:

which python

If they output of that command is not something like ~/bin/python or /home/[your username]/bin/python, something probably didn't work. If that's the case, you can try again, or simply remember to use ~/bin/python instead of python throughout the rest of this HOWTO.

Install Python's setuptools

Now we should install Python's setuptools to make our lives easier down the road.

cd ~/downloads
wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py

This gives us access to a script called easy_install, which makes it easy to install many useful Python tools. We will use this a bit later.

Download Django

Let's now download the most recent development version of Django. SSH into your account and execute the following commands (all commands shall be executed on your host).

svn co http://code.djangoproject.com/svn/django/trunk ~/downloads/django-trunk

Now we should make a symlink (or shortcut) to Django and put it somewhere on the Python Path. A sure-fire place is your ~/lib/python2.4/site-packages/ directory (again, that location could vary from host to host):

ln -s ~/downloads/django-trunk/django ~/lib/python2.4/site-packages
ln -s ~/downloads/django-trunk/django/bin/django-admin.py ~/bin

Now verify that Django is installed and working by executing the following command:

python -c "import django; print django.get_version()"

That command should return something like 1.0-final-SVN-8964. If you got something like that, you're good to move onto the next section. If, however, you get something more along the lines of...

Traceback (most recent call last):
    File "<string>", line 1, in ?
ImportError: No module named django

...then your Django installation didn't work. If this is the case, make sure that you have a ~/downloads/django-trunk/django directory, and also verify that ~/lib/python2.4/site-packages actually exists.

Installing Dependencies

In order for your Django projects to become useful, we need to install some other packages: PIL (Python Imaging Library, required if you want to use Django's ImageField), MySQL-python (a MySQL database driver for Python), and flup (a utility for fastcgi-powered sites).

easy_install -f http://www.pythonware.com/products/pil/ Imaging
easy_install mysql-python
easy_install flup

Sometimes, using easy_install to install PIL doesn't go over too well because of your (lack of) permissions. To circumvent this situation, you can always download the actual PIL source code and install it manually.

cd ~/downloads
wget http://effbot.org/downloads/Imaging-1.1.6.tar.gz
tar zxf Imaging-1.1.6.tar.gz
cd Imaging-1.1.6
ln -s ~/downloads/Imaging-1.1.6/PIL ~/lib/python2.4/site-packages

And to verify, you can try this command:

python -c "import PIL"

If that doesn't return anything, you're good to go. If it says something about "ImportError: No module named PIL", it didn't work. In that case, you have to come up with some other way of installing PIL.

Setting Up A Django Project

Let's attempt to setup a sample Django project.

mkdir -p ~/projects/django
cd ~/projects/django
django-admin.py startproject mysite
cd mysite
mkdir media templates

If that works, then you should be good to do the rest of your Django development on your server. If not, make sure that ~/downloads/django-trunk/django/bin/django-admin.py exists and that it has a functioning symlink (shortcut) in ~/bin. If not, you'll have to make adjustments according to your setup. Your directory structure should look something like:

  • projects
    • django
      • mysite
        • media
        • templates
        • __init__.py
        • manage.py
        • settings.py
        • urls.py

Making A Django Project Live

Now we need to make your Django project accessible from the Web. On Site5, I generally use either a subdomain or a brand new domain when setting up a Django project. If you plan on having other projects accessible on the same hosting account, I recommend you do the same. Let's assume you setup a subdomain such as mysite.mydomain.com. On Site5, you would go to ~/public_html/mysite for the next few commands. This could differ from host to host, so I won't go into much more detail than that.

Once you're in the proper place, you need to setup a few things: two symlinks, a django.fcgi, and a custom .htaccess file. Let's begin with the symlinks.

ln -s ~/projects/django/mysite/media ~/public_html/mysite/static
ln -s ~/lib/python2.4/site-packages/django/contrib/admin/media ~/public_html/mysite/media

This just makes it so you can have your media files (CSS, images, javascripts, etc) in a different location than in your public_html.

Now for the django.fcgi. This file is what tells the webserver to execute your Django project.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/home/[your username]/bin/python
import sys, os

# Add a custom Python path.
sys.path.insert(0, "/home/[your username]/projects/django")

# Switch to the directory of your project. (Optional.)
os.chdir("/home/[your username]/projects/django/mysite")

# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "mysite.settings"

from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")

And finally, the .htaccess file:

1
2
3
4
5
6
RewriteEngine On
RewriteBase /
RewriteRule ^(media/.*)$ - [L]
RewriteRule ^(static/.*)$ - [L]
RewriteCond %{REQUEST_URI} !(django.fcgi)
RewriteRule ^(.*)$ django.fcgi/$1 [L]

The .htaccess file makes it so that requests to http://mysite.mydomain.com/ are properly directed to your Django project. So, now you should have a directory structure that something that looks like this:

  • public_html
    • mysite
      • media
      • static
      • .htaccess
      • django.fcgi

If that looks good, go ahead and make the django.fcgi executable and non-writable by others:

chmod 755 ~/public_html/mysite/django.fcgi

After that, head over to http://mysite.mydomain.com/ (obviously, replace the mydomain accordingly). If you see a page that says you've successfully setup your Django site, you're good to go!

Afterthoughts

I've noticed that I need to "restart" my Django sites on Site5 any time I change the .py files. There are a couple methods of doing this. One includes killing off all of your python processes (killall ~/bin/python) and the other simply updates the timestamp on your django.fcgi (touch ~/public_html/mysite/django.fcgi). I find the former to be more destructive and unreliable than the latter. So, my advice is to use the touch method unless it doesn't work, in which case you can try the killall method.

Good luck!

Meta

Published: Sept. 4, 2008

Author: Josh VanderLinden

Comments: 14

Word Count: 1,342

Next: Dexpot

Previous: Django 1.0 Final!!

Bookmark and Share

Filed Under

Django, How To, Internet, Open Source, Programming, and Python

Article Links

  1. Step-by-Step: Installing Django
  2. Django | The Web framework for perfectionists with deadlines
  3. Site5 - Web Hosting for Webmasters

Comments

Gravatar for None
jdbaker
Thanks for the good post on site5/django...

1 question...

I'm trying to get it to work on the root of the domain http://mydomain.com/

If I hit http://mydomain.com/django.fcgi it works and I see the django 'congrats' page...

but If I hit the root http://mydomain.com - I get a '403 forbidden'

my htaccess:
RewriteEngine On
RewriteBase /
RewriteRule ^(media/.*)$ - [L]
RewriteRule ^(static/.*)$ - [L]
RewriteCond %{REQUEST_URI} !(django.fcgi)
RewriteRule ^(.*)$ django.fcgi/$1 [L]

any suggestions... ?
Thanks
19 Sept. 2008 at 7:47 a.m.
Gravatar for codekoala
wheaties
@jdbaker: My best guess is to check the permissions on your django.fcgi script. Make sure it's executable across the board. If it's already executable and you would like some one-on-one assistance to figure it out, just let me know. I can get in touch and post the solution here when we figure it out.
19 Sept. 2008 at 3:38 p.m.
Gravatar for None
logos
Thanks for great how-to for django on shared hostings. but i got a problem when i tried to

django-admin.py startproject ***

it gives error like

from django.core import management
ImportError: No module named django.core

i tried to adding virtual-python/lib/python2.4/site-packages/django and my project folder to PYTHONPATH bu it did not worked for me still the same error. python is working on do u have any idea about this error.
30 Dec. 2008 at 1:12 p.m.
Gravatar for codekoala
wheaties
@logos: it looks like Django isn't actually available on your PYTHONPATH. Were you able to successfully run this command?

python -c "import django; print django.get_version()"
30 Dec. 2008 at 4:29 p.m.
Gravatar for None
logos
python -c "import django; print django.get_version()"
yes it worked out but i couldnot startproject. anyway its just a my curiosity because i changed my development environment, because nearly none of the hosting companies serves with fast-cgi or mod_python. and i have already paid one year membership, it really sucks :(

but here what u have done is awesome, and unique, u cant find any article about this topic, thnx again...
10 Jan. 2009 at 1:31 p.m.
Gravatar for None
trutane
Josh: Excellent article. I'm also a Site5 user who'd like to experiment with Django. I ran into the same problem reported by jdbaker, only I get a 403 regardless for how I attempt to access my site (with or without django.fcgi in the URL) so it's not an issue with the .htaccess file, and the permissions of the fcgi are good to go (755).

I suspect the trouble is related to FastCGI itself. I attempted to run a "Hello World" style fcgi script located in the top-level of my public_html, and I get the same 403 with it. Here's my hello.fcgi script:

#!/home//bin/python

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()


It works fine on the command-line (as does my django.fcgi), so it seems to my like the server doesn't know how to handle *any* fcgi script. Probably something that the site admins need to configure, eh?

Another question: I've come across a number of django/fastCGI docs that mention a fcgi.py file and claim that it needs to be located in the same dir as django.fcgi. Yet you don't mention it. I've put it in my directory, without any effect so I assume it is now obsolete, right?

Cheers
17 Jan. 2009 at 12:34 a.m.
Gravatar for codekoala
wheaties
trutane: I'm glad you found this document to be useful! It's very strange that you are running into this problem as well.

I have also seen several tutorials that mention the fcgi.py script. At one point I could have told you why I didn't need it for this tutorial, but that was a long time ago and I've forgotten what the significance was. Sorry.
17 Jan. 2009 at 8:24 a.m.
Gravatar for None
trutane
Good news: I was able to solve my problem by putting the fcgi script within a cgi-bin subdirectory. Site5 has apparently configured apache to permit executable scripts only within a cgi-bin dir (pretty typical setup).

So my directory structure is now this (you'll have to parse the HTML mentally to get the structure since these comments don't render them, it appears):


mysite

media
static
.htaccess
cgi-bin

django.fcgi




I also changed the last line of the .htaccess file to point to the django.fcgi within the cgi-bin subdir:

RewriteRule ^(.*)$ cgi-bin/django.fcgi/$1 [L]

Btw, the URL you give in the article for downloading PIL should be this:
http://effbot.org/media/downloads/Imaging-1.1.6.tar.gz

(The easy_install of PIL didn't work for me, so I had to do it manually, as you noted.)

Cheers.
18 Jan. 2009 at 3:56 p.m.
Gravatar for None
JJPR
Any idea?

TypeError at /
__init__() got an unexpected keyword argument 'maxlength'Request Method: GET
Request URL: http://www.lgewow.com/
Exception Type: TypeError
Exception Value: __init__() got an unexpected keyword argument 'maxlength'
Exception Location: /home/lgewow/public_html/sinc_lg_wow/content/models.py in Product, line 14
Python Executable: /home/lgewow/bin/python
Python Version: 2.4.3
Python Path: ['/home/lgewow/public_html/', '/home/lgewow/public_html', '/usr/local/lib/python2.4/site-packages/MySQL_python-1.2.2-py2.4-linux-i686.egg', '/home/lgewow/lib/python2.4/site-packages/setuptools-0.6c9-py2.4.egg', '/home/lgewow/lib/python2.4/site-packages/flup-1.0.1-py2.4.egg', '/home/lgewow/lib/python24.zip', '/home/lgewow/lib/python2.4', '/home/lgewow/lib/python2.4/plat-linux2', '/home/lgewow/lib/python2.4/lib-tk', '/home/lgewow/lib/python2.4/lib-dynload', '/home/lgewow/lib/python2.4/site-packages']
21 May 2009 at 10:20 a.m.
Gravatar for codekoala
Josh VanderLinden
@JJPR, it looks like you're using an app that expects an older version of Django. Try replacing `maxlength` with `max_length` in your content/models.py on line 14.
21 May 2009 at 10:23 a.m.
Gravatar for None
JJPR
Thank you Josh,
Now i have the following error:

AttributeError at /
'SessionManager' object has no attribute 'get_new_session_key'Request Method: GET
Request URL: http://www.lgewow.com/
Exception Type: AttributeError
Exception Value: 'SessionManager' object has no attribute 'get_new_session_key'
Exception Location: /home/lgewow/public_html/sinc_lg_wow/content/views.py in index, line 22
Python Executable: /home/lgewow/bin/python
Python Version: 2.4.3
Python Path: ['/home/lgewow/public_html/', '/home/lgewow/public_html', '/usr/local/lib/python2.4/site-packages/MySQL_python-1.2.2-py2.4-linux-i686.egg', '/home/lgewow/lib/python2.4/site-packages/setuptools-0.6c9-py2.4.egg', '/home/lgewow/lib/python2.4/site-packages/flup-1.0.1-py2.4.egg', '/home/lgewow/lib/python24.zip', '/home/lgewow/lib/python2.4', '/home/lgewow/lib/python2.4/plat-linux2', '/home/lgewow/lib/python2.4/lib-tk', '/home/lgewow/lib/python2.4/lib-dynload', '/home/lgewow/lib/python2.4/site-packages']
21 May 2009 at 10:56 a.m.
Gravatar for codekoala
Josh VanderLinden
@JJPR, I'm not sure if there's a function such as "get_new_session_key" in Django... I haven't done a whole lot of work with sessions in Django. If you're just trying to get the current session key, you might change what I'm assuming is `Session.objects.get_new_session_key()` to `request.session.session_key` on line 22 of your content/views.py file.
21 May 2009 at 11:01 a.m.
Gravatar for None
JJPR
Thanks again Josh! You help me so much!
I have now an issue about the swfobject... maybe because the path.

:S
21 May 2009 at 11:43 a.m.
Gravatar for codekoala
Josh VanderLinden
@JJPR, glad to help. I'm afraid I won't be of much use with the swfobject problems. I've never used it. You're still free to post about it here--perhaps it won't be as related to swfobject as it seems, or maybe someone else will chime in.
21 May 2009 at 11:45 a.m.

Post a Comment

:  
:  
:  
:  
:  

About Me

My name is Josh VanderLinden. I'm a developer, and I have a passion for technology. I dream in code.

I use Linux, Kate, Java, Python, Django, databases, Photoshop, and Firefox.

About This Site

CodeKoala.com was developed using Django and Python, and it's bursting at the seams with love.

You're one of 8 active visitors. Two are viewing this very page.

Recently Finished
Books I'm Reading

None at this time.

I have read approximately 7,874 pages since September 1, 2008.

Books I Plan To Read