Django and Cherokee server
Check out the new site at https://rkblog.dev.
14 July 2008
Comments
Cherokee is a very fast, flexible, and lightweight Web server. It is implemented entirely in C, and has no dependencies beyond a standard C library :grin:. It is quite popular among debian and gnome users.Django with Cherokee and SCGI
We will configure cherokee to server django project using SCGI protocol. Cherokee will also serve static files (media files)- Install flup module:
easy_install flup
- Download django-scgi.py from this site and place it in the project folder.- Install cherokee if you haven't done that yet. Note that when compiling from source you can explicitly enable SCGI and FastCGI support:
./configure --enable-scgi --enable-fcgi
- In gentoo use:
USE="fastcgi scgi" emerge cherokee
- In /etc/cherokee you will find all cherokee config files. Edit /etc/cherokee/sites-enabled/default (if not present symlink default from sites-available).- Find:
DocumentRoot /var/www/localhost/htdocs
- Change to a path to your project, for example: /home/user/djangoProject/- Find:
UserDir public_html { Directory / { Handler common }
UserDir public_html { Directory / { Handler scgi { Server localhost:8080 } }
- Find:
Directory / { Handler common }
Directory /site_media/ { Handler common } Directory /media/ { Handler common }
- To make a symlink execute from the project folder:
ln -sf /usr/lib/python2.4/site-packages/django/contrib/admin/media media
- Check if django is in that path!- Start WSGI server:
python django-scgi.py --projects=/home/user/projectDjango/ --settings=settings --host=localhost --port=8080
Where -projects=/home/user/projectDjango/ is a path to your django project. -settings=settings defines settings file (in urls.py you should have: ROOT_URLCONF = 'urls'), --host and --port are WSGI server host and port to use.- Start cherokee server:
/etc/SOMETHING/cherokee start /etc/init.d/cherokee start (gentoo) /etc/rc.d/cherokee start (arch)
Cleaning cherokee
You may want to remove PHP, /cgi-bin and other config entries that aren't needed.django-scgi.py
If you can't download it, here is the code:import os
import sys
if os.name == 'posix':
def become_daemon(ourHomeDir='.',outLog='/dev/null',errLog='/dev/null'):
"""
Robustly turn us into a UNIX daemon, running in ourHomeDir.
Modelled after the original code of this module and some
sample code from the net.
"""
# first fork
try:
if os.fork() > 0:
sys.exit(0) # kill off parent
except OSError, e:
sys.stderr.write("fork #1 failed: (%d) %s
" % (e.errno, e.strerror))
sys.exit(1)
os.setsid()
os.chdir(ourHomeDir)
os.umask(0)
# second fork
try:
if os.fork() > 0:
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #2 failed: (%d) %s
" % (e.errno, e.strerror))
sys.exit(1)
si = open('/dev/null', 'r')
so = open(outLog, 'a+', 0)
se = open(errLog, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
else:
def become_daemon(ourHomeDir='.',outLog=None,errLog=None):
"""
If we are not running under a POSIX system, just simulate
the daemon mode by doing redirections and directory changeing
"""
os.chdir(ourHomeDir)
os.umask(0)
sys.stdin.close()
sys.stdout.close()
sys.stderr.close()
if errLog and outLog:
sys.stderr=open (errLog, 'a', 0)
sys.stdout=open (outLog, 'a', 0)
elif errLog:
sys.stderr=open (errLog, 'a', 0)
sys.stdout=NullDevice ()
elif outLog:
sys.stdout=open (outLog, 'a', 0)
sys.stderr=NullDevice ()
else:
sys.stdout = NullDevice()
sys.stderr = NullDevice()
class NullDevice:
"""
A substitute for stdout and stderr that writes to nowhere.
This is a substitute for /dev/null
"""
def write(self, s):
pass
def main():
from flup.server.scgi_fork import WSGIServer
from django.core.handlers.wsgi import WSGIHandler
import getopt
(opts, args) = getopt.getopt(sys.argv[1:], 'f:s:h:p:',
['settings=','socket=','host=','port=',
'minspare=', 'maxspare=', 'maxchildren=',
'daemon', 'etclog=', 'errorlog=', 'workdir=',
'projects='])
socket = None
host = None
port = None
minspare = 1
maxspare = 5
maxchildren = 50
daemon = None
workdir = '.'
etclog = '/dev/null'
errorlog = '/dev/null'
projects = []
for (o, v) in opts:
if o in ('-s', '--socket'):
socket = v
elif o in ('-h', '--host'):
host = v
elif o in ('-p', '--port'):
port = int(v)
elif o in ('-f', '--settings'):
os.environ['DJANGO_SETTINGS_MODULE'] = v
elif o in ('--minspare',):
minspare = int(v)
elif o in ('--maxspare',):
maxspare = int(v)
elif o in ('--maxchildren',):
maxchildren = int(v)
elif o in ('--daemon',):
daemon = 1
elif o in ('--errorlog',):
errorlog = v
elif o in ('--etclog',):
etclog = v
elif o in ('--workdir',):
workdir = v
elif o in ('--projects',):
projects.append(v)
# add projects to path
for p in projects:
if p not in sys.path:
sys.path.insert(0, p)
# if we should run as a daemon, use the above function to turn us
# into one reliably. This should correctly detach from the tty.
if daemon:
become_daemon(ourHomeDir=workdir,
outLog=etclog, errLog=errorlog)
if socket and not host and not port:
WSGIServer(WSGIHandler(), minSpare=minspare, maxSpare=maxspare, maxChildren=maxchildren, bindAddress=socket).run()
elif not socket and host and port:
WSGIServer(WSGIHandler(), minSpare=minspare, maxSpare=maxspare, maxChildren=maxchildren, bindAddress=(host, port)).run()
else:
print "usage: django-scgi.py [--settings=<settingsmodule>] --socket=<socketname>"
print " or: django-scgi.py [--settings=<settingsmodule>] --host==<hostname> --port=<portnumber>"
print
print " additional options are:"
print " --minspare=<minimum number of spare processes, default 1>"
print " --maxspare=<maximum number of spare processes, default 5>"
print " --maxchildren=<maximum number of child processes, default 50>"
print
print " --daemon"
print " --etclog=<path for stdout log, default /dev/null>"
print " --errorlog=<path for stderr log, default /dev/null>"
print " --workdir=<path for working directory, default .>"
print
print " --projects=<path to add to sys.path>"
if __name__ == '__main__':
# first patch our own version of socketpair into the sockets module
# if we don't have it already (comes with Python 2.4)
import socket
if not hasattr(socket, 'socketpair'):
import eunuchs.socketpair
def socketpair():
(p,c) = eunuchs.socketpair.socketpair()
(pp,cc) = (socket.fromfd(p,1,1), socket.fromfd(c,1,1))
os.close(c)
os.close(p)
return (pp,cc)
socket.socketpair = socketpair
main()
RkBlog
Check out the new site at https://rkblog.dev.
Comment article