Produkční nasazení Django aplikací na Cherokee pomocí WSGI

Prostředí pro provoz aplikací v Djangu se musí postarat o co nejefektivnější využití prostředků, zejména o spouštění a ukončování procesů. V článku si představíme jednu z možných konfigurací takového prostředí. Pro odbavování aplikace použijeme HTTP server Cherokee a obdobu FastCGi – protokol uWSGI.

Typická architektura prostředí pro provoz Django aplikace se skládá z několika komponent. S klienty komunikuje web server protokolem HTTP. Klient může požadovat statický nebo dynamický obsah. Se statickým (např. mujweb.cz/ima­ges/logo.jpg) by Django ani Python neměly mít nic společného, představovaly by zbytečné zpomalení. Ve druhém případě klient přistupuje na URL s dynamickým obsahem (mujweb.cz/), kterou má web server svázanou s naší aplikací. Potřebuje s ní navázat komunikaci a předat jí kompletní klientův požadavek. Aplikace následně požadavek zpracuje a pošle zpět odpověď.

V podobném schématu ale musíme vyřešit několik komplikací. Kdo bude spouštět proces aplikace a kdo se o takový proces bude nadále starat (tedy po jaké době zabít neaktivní proces, po jakém počtu požadavků ho restartovat atd.)? Jakým protokolem bude web server s aplikací komunikovat a kdo se bude o aplikaci starat, si nyní vysvětlíme.

WSGI nebo FastCGI?

Od oficiálního ukončení projektu mod_python máme při provozování webových aplikací napsaných v jazyce Python na výběr v podstatě mezi třemi protokoly určenými k propojení aplikace a web serveru: FastCGI, SCGI a WSGI. Všechny vycházejí z principů CGI a lze je použít na většině v praxi používaných web serverů. CGI je standard definující rozhraní pro běh externích programů pod HTTP serverem. (Zdroj definice: volný překlad z abstraktu RFC 3875). Hlavní problém CGI spočívá v tom, že pro každý nový požadavek musí být vytvořen nový proces. Po obsloužení je proces zase ukončen a tak stále dokola. Z toho vyplývá například nemožnost znovu použít již navázaná databázová spojení. Při větším počtu požadavků je pak režie managamentu procesů příliš vysoká a místo, aby se server zabýval obsluhou požadavků, tvoří a ukončuje procesy. Řešením je, aby jeden proces obsloužil za dobu svého života více požadavků. Právě toto je největší rozdíl FastCGI a WSGI oproti CGI.

Doporučeným způsobem provozování Python aplikací, které pro obsluhu požadavků využívají framework Django, je WSGI. FastCGI nebo SCGI fungují také dobře, ale přijdeme tím o výhody vyplývající z použití uWSGI.

uWSGI

uWSGI je WSGI server, který je z hlediska principu funkce obdoba FastCGI a funguje jako prostředník mezi aplikací a web serverem. Stará se o výše zmíněný management procesu aplikace. Podrobnosti komunikace mezi jednotlivými komponentami jsou vidět na obrázku. Se serverem komunikuje vlastním protokolem (uwsgi, malými písmeny), ale s aplikací komunikuje již standardním WSGI.

Mezi výhody patří velmi malá spotřeba paměti (spolu s Cherokee a sqlite databází je schopen fungovat na serveru s 64MB RAM), podpora pro Python virtualenv (každá provozovaná aplikace může mít vlastní sadu knihoven, například různé verze Djanga nebo dokonce různé verze Pythonu), inteligentní management procesů a od další verze pravděpodobně i automatické načítání změn ve spuštěné aplikaci (reload). Výkonnostní a paměťové výhody dokumentuje benchmark od Nicholase Piëla porovnávající 15 WSGI serverů.

Samotné uWSGI je nastartováno web serverem při prvním požadavku.

Cherokee

Z hlediska uWSGI můžeme použít jakýkoliv web server, který má podporu uwsgi protokolu. Podporovány jsou apache2, nginx, cherokee a lighttpd. Pro tento článek zvolíme Cherokee – rychlý, malý a velmi snadno konfigurovatelný HTTP server se širokou funkcionalitou: od podpory virtuálních hostů a grafů provozu pomocí rrdtool, přes trafic shaping a streamování audio/video souborů, až po dobrou podporu load balancingu a X-Sendfile.

Konfigurace systému

Instalace frameworku Django nebo tvorba projektů v něm není předmětem tohoto článku, takže zájemce o návod k instalaci odkáži do dokumentace Djanga, sekce instalace. Tvorbu jednoduchého projektu popisuje první část oficiálního Django tutoriálu nebo seriál o Djangu přímo zde na Zdrojáku. Můžete také příkazem django-admin startproject <nazev_projektu> vygenerovat jen minimální Django projekt (“It works!”) a použít ten.

Kromě instalace Djanga budeme dále předpokládat funkční Unix-like systém a jeho základní uživatelskou znalost a znalost základních principů webserveru. Článek je psán podle linuxové distribuce Debian Lenny (aktuální stable) s tím, že balíčky Cherokee a Python jsou instalovány, kvůli jejich zastaralosti v repozitářích Lenny, ze Squeeze (aktuální testing). Používáme tedy Python 2.6, Cherokee 1.0.4 a uWSGI verze 0.9.5.4.

Začněme přípravou samotného systému. Abychom mohli instalovat z testing repozitářů, musíme o nich systému dát vědět. Vytvoříme soubor /etc/apt/apt.con­f.d/50default-release a vložíme do něj řádek APT::Default-Release „stable“;. Toto nastavení zamezí, aby se stable distribuce po přidání testing repozitářů celá aktualizovala na testing. Místo toho budeme pro balíčky, které chceme nainstalovat z repozitáře testing, používat přepínač -t testing. Samotný testing repozitář přidáme následujícím řádkem v souboru /etc/apt/sources­.list.

deb http://ftp.cz.debian.org/debian/ squeeze main non-free contrib

Na závěr aktualizujeme lokální seznam dostupných balíčků příkazem apt-get update.

Instalace Cherokee a uWSGI

Balíček HTTP serveru Cherokee z repozitáře testing nainstalujeme příkazem aptitude -t testing cherokee.

Instalace uWSGI je bohužel složitější než u Cherokee, protože v repozitářích Debianu příslušný balíček úplně chybí. Budeme tedy muset instalovat ze zdrojových kódů, ale balíčkovací systém nám i tak pomůže alespoň se závislostmi. Jedním se způsobů konfigurace uWSGI je XML konfigurace, takže budeme potřebovat balíčky libxml2 a libxml2-dev. uWSGI “svým” aplikacím dále exportuje vlastní Python modul uwsgi (to umožňuje například existenci Django aplikace pro management uWSGI serveru), takže budeme kompilovat i proti Pythonu. Přidáme tedy i balíček python-dev. Nakonec k vlastní kompilaci budeme potřebovat gcc. Kompletní příkaz pro instalaci bude vypadat takto: aptitude -t testing install libxml2 libxml2-dev python-dev gcc.

Stáhneme, rozbalíme a nainstalujeme uWSGI.

wget http://projects.unbit.it/downloads/uwsgi-0.9.5.4.tar.gz
tar xvzpf uwsgi-0.9.5.4.tar.gz
cd uwsgi-0.9.5.4
python setup.py install

Příkaz uwsgi –version by nám nyní měl vracet “uWSGI 0.9.5.4”.

Konfigurace Cherokee

Konfigurace Cherokee se provádí pomocí přehledného webového GUI rozhraní cherokee-admin. Toto rozhraní neběží neustále, ale spouští se manuálně příkazem cherokee-admin. Ve výchozí konfiguraci se váže na localhost, port 9090. Chceme-li se připojit zvenku, budeme muset přidat parametr -b (pak umožní připojení z jakéhokoliv rozhraní) nebo použít SSH tunel na port 9090 na serveru. Příkaz ssh -N -L 9090:localhost:9090 login@ip.ad.re.sa nám přesně takový vytvoří, takže pak stačí zadat lokálně do prohlížeče localhost:9090 a SSH se postará o zbytek.

Dostali jsme se do konfigurace webserveru. Konfigurovat můžeme klidně i bez spuštěného serveru, konfigurace se ukládá přímo do souboru /etc/cherokee/che­rokee.conf. Cherokee-admin umožňuje při vytváření virtuálních serverů (položka “vServers” vpravo nahoře) použít sadu průvodců pro běžné případy konfigurace. Django lze pomocí těchto průvodců nakonfigurovat dvěma způsoby.

První (Platforms > Django v nabídce přidání nového virtuálního serveru) umožní provozovat vaši Django aplikaci poměrně jednoduše pomocí SCGI – stačí zadat cestu k projektu, doménu a je hotovo (viz receptCherokee Cookbook). My bychom však v produkčním prostředí rádi využili výhod, které nám dává uWSGI.

Konfigurace uWSGI

Z bezpečnostních důvodů je vhodné, aby proces uWSGI (a s ním i celý django projekt) běžel pod jedním uživatelem. V našem příkladu zvolme jméno hellouser.

useradd -U -s /bin/false -m hellouser

Hned první krok průvodce v cherokee-admin po nás chce konfigurační soubor uWSGI. Ten může v XML formátu vypadat třeba takto. (Umístíme ho do /home/hellouser/he­lloworld.xml.)

<uwsgi>
    <pythonpath>/home/hellouser</pythonpath>
    <pythonpath>/home/hellouser/helloworld</pythonpath>
    <pidfile>/home/hellouser/helloworld.pid</pidfile>
    <harakiri>20</harakiri>
    <processes>2</processes>
    <app mountpoint="/">
        <script>django_wsgi</script>
    </app>
</uwsgi>

Parametr pythonpath přidává adresář naší aplikace (Django projektu, např. helloworld) do PYTHONPATH. Je to proměnná prostředí, která říká v jakých lokacích se mají vyhledávat importované moduly. Náš Django projekt, stejně jako Django aplikace v něm, se chová jako běžný Python-balíček. Parametr pidfile nastavuje umístění souboru obsahujícího PID hlavního (master) procesu, který slouží k managementu ostatních, tzv. workers (jejich počet se nastavuje parametrem processes a je vhodné ho odvozovat od počtu jader a procesorů ve vašem systému). Parametr harakiri stanoví čas v sekundách, za který musí worker ukončit svoji práci, jinak je ukončen master procesem. Parametr app stanoví modul (v praxi soubor s příponou *.py, v našem případě django_wsgi.py umístěný v /home/hellouser, viz dále), který obsahuje kód v Pythonu definující WSGI handler. Můžeme si ho představit jako černou krabičku, která přijme klientský požadavek od HTTP serveru ve formátu WSGI protokolu a opět odešle odpověď stejnou cestou.

Soubor s handlerem umístíme do /home/hellouser/djan­go_wsgi.py. Samotný handler připravíme následujícím kódem:

import os
import django.core.handlers.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = 'helloworld.settings'
application = django.core.handlers.wsgi.WSGIHandler()

Na závěr ještě musíme zajistit, aby cherokee spouštěl uWSGI pod správným uživatelem. To nastavíme v Sources (vpravo nahoře) > uWSGI 1 (interpreter) > Execute as User/Group.

Nyní vše uložíme tlačítkem Save v pravém horním rohu (v nabídce zvolíme Graceful restart). Na adrese (New Host Name), kterou jsme zvolili v druhém kroku průvodce uWSGI v cherokee-admin, by nás nyní měla přivítat “It worked!” stránka Djanga.

Nakonfigurovali jsme si základní prostředí pro běh Django aplikací. Zbývá nainstalovat například databázi nebo spouštět jednotlivé aplikace ve vlastním virtuálním prostředí pomocí python-virtualenv, ale o tom někdy příště.

Poznámka: Pokud si chcete výše popisovanou konfiguraci vyzkoušet, můžete využít šablony u Virtualmaster, kterou autor připravil. K dispozici je i v článku zmíněný ukázkový projekt: Django + Cherokee + WSGI

Autor se živí správou GNU/Linux serverů a programováním v Pythonu a Djangu. V současné době studuje 3. ročník ČVUT FEL, obor Softwarové inženýrství.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Zdroj: https://www.zdrojak.cz/?p=3318