Django pod serwerem cherokee

Konfiguracja serwera HTTP Cherokee do produkcyjnego hostowania aplikacji Django poprzez FastCGI lub SCGI. Artykuł opisuje nieco starszą wersję nie posiadającą webowej aplikacji do automatycznej konfiguracji hostowania Django

Cherokee to mały i bardzo wydajny serwer www obsługuący m.in. SCGI i FastCGI. Jest dość popularny w kręgach gnome i debiana.

Django i Cherokee z wykorzystaniem SCGI

Celem będzie skonfigurowanie cherokee do obsługiwania projektu django za pomocą protokołu SCGI oraz dostarczanie statycznych plików (media files)

- Do połączeń FastCGI/SCGI zainstaluj pakiet flup:
easy_install flup
- Następnie pobierz plik django-scgi.py z tej strony i umieść go w katalogu projektu.
- Jeżeli nie masz zainstalowanego cherokee to zrób to teraz. Zwróć uwagę że obsługa protokołów SCGI/FastCGI może być włączona/wyłączona przy konfiguracji/kompilacji. By jawnie zadeklarować obsługę obu protokołów wystarczy polecenie:
./configure --enable-scgi --enable-fcgi
- W przypadku gentoo:
USE="fastcgi scgi" emerge cherokee
- W /etc/cherokee znajdują się pliki konfiguracyjne serwera. Edytuj /etc/cherokee/sites-enabled/default (jeżeli nie ma to utwórz symlink z default z sites-available).
- Znajdź:
DocumentRoot /var/www/localhost/htdocs
- Zamień na ścieżkę do katalogu z projektem django, np. /home/user/djangoblog/
- Znajdź:
UserDir public_html {
    Directory / {
       Handler common
    }
- Zamień na:
UserDir public_html {
    Directory / {
       Handler scgi
        {
        Server localhost:8080
        }
    }
- Gdzie localhost:8080 to host i port, na którym będzie działał serwer WSGI obsługujący django.
- Znajdź:
Directory / {
    Handler common
}
- Zamień na:
Directory /site_media/ {
    Handler common
}
Directory /media/ {
    Handler common
}
Gdzie site_media to nazwa folderu z statycznymi plikami twojego projektu (wstaw nazwę swojego katalogu) a /media/ odnosi się do symlinka katalogu media panelu admina.
- By utworzyć symlink do plików statycznych panelu admin django wykonaj w katalogu projektu:
ln -sf /usr/lib/python2.4/site-packages/django/contrib/admin/media media
- Sprawdź czy w twoim systemie django znajduję się pod tą samą ścieżką.
- Uruchom serwer WSGI:
python django-scgi.py --projects=/home/user/projektDjango/ --settings=settings --host=localhost --port=8080
Gdzie -projects=/home/user/projektDjango/ to ścieżka do katalogu z projektem django, -settings=settings określa plik konfiguracyjny (w urls.py powinieneś mieć: ROOT_URLCONF = 'urls'), --host i --port to host i port na jakim serwer WSGI będzie działał.
- Uruchom serwer Cherokee. W zależności od dystrybucji będzie to:
/etc/cośtam/cherokee start
/etc/init.d/cherokee start    (gentoo)
/etc/rc.d/cherokee start     (arch)
- Otwórz w przeglądarce adres http://localhost/ - powinieneś zobaczyć stwoją stronę działającą bez żadnych problemów.

Porządkowanie cherokee

Możesz usunąć zbędne wpisy (np. odnoszące się dp PHP, /cgi-bin itp.).

django-scgi.py

Gdyby podany w tekście adres nie działał oto kod potrzebnego pliku:
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()
blog comments powered by Disqus

Kategorie

Strony