__|__
-------O-------
o´ `o
Django on Joyent Shared Machine with Apache and FastCGI
Monday, 29 November 2010
This is how I managed to deploy a site powered by Django (1.2.3) on my shared hosting account at Joyent.
Replace USERNAME with your Joyent account username, WWW.DOMAIN.TLD with the domain name where you will be using Django and SERVER with the name of your server at Joyent (use lowercase).
SSH into your server
Open a Terminal window and SSH into your Joyent machine:
ssh USERNAME@SERVER.joyent.us
Folders
Go to the domain name where your Django site will be located and create folders to store your Django stuff, then go into the /local/ folder:
cd domains/WWW.DOMAIN.TLD
mkdir local
mkdir local/django_projects
cd local
Download Django
Download Django with Subversion and change the name of the folder to django_trunk:
svn co http://code.djangoproject.com/svn/django/trunk/
mv trunk django_trunk
Admin media
- Create a media folder inside your web public folder:
mkdir /users/home/USERNAME/domains/WWW.DOMAIN.TLD/web/public/media - Create a symbolic link named ‘admin’ linking to the admin/media folder in your Django installation folder:
ln -s /users/home/USERNAME/domains/WWW.DOMAIN.TLD/local/django_trunk/django/contrib/admin/media ~/domains/WWW.DOMAIN.TLD/web/public/media/admin
Upload your Django project to the server
You can do this with version control or by uploading your MYPROJECT folder into the /django_projects/ folder with SFTP. Your project will then be found at /users/home/USERNAME/domains/WWW.DOMAIN.TLD/local/django_projects/MYPROJECT.
I won’t explain how to create a Django project as this is already covered in many places. For example, if you follow these Django quickstart instructions on your computer and then put the resulting ‘AcmeIntranet’ folder into /users/home/USERNAME/domains/WWW.DOMAIN.TLD/local/django_projects/AcmeIntranet it should just work, especially if you use SQLite as the database. Don't forget to point your paths in settings.py to the appropriate ones for your server.
MYPROJECT.fcgi
Put the following code in a file called MYPROJECT.fcgi at /users/home/USERNAME/domains/WWW.DOMAIN.TLD/web/public/mysite.fcgi:
#!/usr/local/bin/python
import sys, os
# Add a custom Python path.
sys.path.insert(0, "/usr/local/bin/python")
sys.path.insert(0, "/users/home/USERNAME/domains/WWW.DOMAIN.TLD/local/django_trunk")
sys.path.insert(0, "/users/home/USERNAME/domains/WWW.DOMAIN.TLD/local/django_projects")
# Switch to the directory of your project. (Optional.)
os.chdir("/users/home/USERNAME/domains/WWW.DOMAIN.TLD/local/django_projects/mysite")
# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "mysite.settings"
os.environ['PYTHON_EGG_CACHE'] = "/users/home/USERNAME/tmp"
# Start FCGI
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false", maxchildren="2", maxspare="2", minspare="1")
.htaccess
Create a file called .htaccess, put the following inside it and save it to your web root at /users/home/USERNAME/domains/WWW.DOMAIN.TLD/web/public/.htaccess:
AddHandler fcgid-script .fcgi # http://stackoverflow.com/questions/2617489/fcgi-htaccess-handler/2617527#2617527
# AddHandler fastcgi-script .fcgi
RewriteEngine On
# RewriteRule ^/(media.*)$ /$1 [QSA,L,PT] # Must learn to serve static media with Nginx or another webserver eventually
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
PYTHONPATH
- Add the following to the bottom of a file called .bashrc at /users/home/USERNAME/.bashrc (note the $HOME variable at the beginning of the PYTHONPATH that is defined in this file)
PYTHONPATH=$HOME/domains/WWW.DOMAIN.TLD/local/django_trunk:$HOME/lib/python2.6/site-packages export PYTHONPATH - Add the following to the bottom of a file called .profile at /users/home/USERNAME/.profile (note that the PYTHONPATH does NOT have a $HOME variable. It is the full path.
PYTHONPATH=/users/home/USERNAME/domains/WWW.DOMAIN.TLD/local/django_trunk:/usr/local/lib/python2.6/site-packages export PYTHONPATH
Touch and GO!
Whenever you change any Python code in django_projects/MYPROJECT you need to touch the MYPROJECT.fcgi file so Apache restarts your application for you. Go to WWW.DOMAIN.TLD in a browser and you should see your application running, or at the very least a Django error message!
Future improvements (to do)
- Virtualenv - Ideally I would like to get the above running in an isolated Python environment using virtualenv.
- Nginx - Serving the site with Nginx would be best, especially media files.
Thanks to Mamash, Linda and Jacques at Joyent and also to Evan Carmi for their help.
__|__
-------O-------
o´ `o