Django: Nasazování projektu

Vytvořením projektu naše práce nekončí. Je potřeba ho zpřístupnit světu a poté udržovat. Ukážeme si nezbytné kroky při nasazování projektu a několik možných konfigurací webového serveru.

Seriál: Hrajeme si s Djangem (16 dílů)

  1. Django: Úvod a instalace 14.8.2009
  2. Django: Nastavení projektu a první pokusy 21.8.2009
  3. Django: Databázový model 28.8.2009
  4. Django: Databázový model podruhé 4.9.2009
  5. Django: Administrace 11.9.2009
  6. Django: Prezentace dat 18.9.2009
  7. Django: Prezentace dat podruhé 25.9.2009
  8. Django: Zpracovávání formulářů 2.10.2009
  9. Django: Autentizace a autorizace 9.10.2009
  10. Django: Nahrávání souborů 16.10.2009
  11. Django: Zabudované aplikace 23.10.2009
  12. Django: Rozšiřování možností Djanga 30.10.2009
  13. Django: Internacionalizace 6.11.2009
  14. Django: Nasazování projektu 13.11.2009
  15. Django: Kešování a škálování 20.11.2009
  16. Django: Závěr 27.11.2009

Při provozování projektu mimo náš vývojářský počítač je potřeba změnit několik nastavení.

Konfigurace

Režim ladění projektu nastavují v konfiguračním souboru settings.py dvě konstanty: DEBUG a TEMPLATE_DEBUG. Druhá konstanta se týká výpisu chyb v šablonách. Při provozování produkčního („ostrého“) serveru je potřeba konstanty změnit na hodnotu False, jinak se uživatelům budou při zadání neexistujicí adresy stránky nebo chybě aplikace zobrazovat ladící informace včetně výpisu zdrojového kódu. Navíc, při vypnutém ladění se posílají automaticky upozornění o chybách aplikací administrátorům stránky, pokud jsou uvedeni v konstantě ADMINS. Konstanta SEND_BROKEN_LIN­K_EMAILS zprovozňuje podobnou funkci týkající se neexistujících adres. Nastavení projektu mimo ladící server by mělo vypadat například takto:

DEBUG = False
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    ('Pavel Dvořák', 'id@dqd.cz'),
)

Chybové stránky

Při již zmiňovaném zadání neexistující stránky nebo chybě aplikace by se návštěvníkovi měla zobrazit stránka se smysluplnou hláškou o chybě. Šablonu s popisem chyby 404 (stránka nenalezena) je potřeba umístit do souboru  templates/404.html:

{% extends "base.html" %}
{% load i18n %}

{% block content %}
<h1>{% block title %}{% trans "Chyba" %} 404{% endblock %}</h1>

<p>{% trans "Soubor nenalezen." %}</p>
{% endblock %}

Stejně tak je dobrým nápadem vytvořit soubor templates/500.html pro výpis chyby 500 (interní chyba serveru):

{% extends "base.html" %}
{% load i18n %}

{% block content %}
<h1>{% block title %}{% trans "Chyba" %} 500{% endblock %}</h1>

<p>{% trans "Omlouváme se, ale v aplikaci došlo k neočekávané chybě. Zároveň byl odeslán upozorňující e-mail administrátorovi, takže problém brzy napravíme." %}</p>
{% endblock %}

Kdybyste náhodou potřebovali pro chybu 500 specifikovat vlastní pohled, dá se to zařídit pomocí proměnné handler500.

Statické soubory

Na konci druhého dílu seriálu jsme se zmiňovali o statických souborech. Při ostrém nasazení je nejlepší nechat tato data servírovat přímo serverem z jiné domény. Lze využít poddoménu (např. media.example.cz), pro větší projekty se často registruje pro tento účel zvlášť vlastní doména. Důvodem pro zakoupení další domény je fakt, že webový prohlížeč nebude na tuto doménu posílat cookies, takže se tak často zrychlí načítání statického obsahu.

Pro nás to znamená přenastavení proměnných MEDIA_ROOT, MEDIA_URL a případně ADMIN_MEDIA_PREFIX (statické soubory administračního rozhraní). Budeme předpokládat, že se statické soubory budou nacházet na adrese http://media.example.cz/, fyzicky budou uloženy v adresáři /var/www/media/ a statické soubory administrace v podadresáři /var/www/media/admin/. Nastavení ovlivněných konstant vypadá takto:

MEDIA_ROOT = '/var/www/media/'

MEDIA_URL = 'http://media.example.cz/'

ADMIN_MEDIA_PREFIX = 'http://media.example.cz/admin/'

Samozřejmě je potřeba také založit adresář /var/www/media/ a zkopírovat do něj adresář se statickými soubory administrace ( /usr/lib/python2.5/site-packages/django/contrib/admin/media), případně na něj vytvořit symbolický odkaz (v obou případech se výsledný adresář musí jmenovovat admin). Správně nastavený webový server (např. Apache nebo lighttpd) poté bude automaticky servírovat tyto soubory z poddomény. Toto nastavení může vypadat kupříkladu takto:

<VirtualHost *:80>
  ServerName media.example.cz
  DocumentRoot /var/www/media/
</VirtualHost>

Nasazování nového kódu pomocí skriptu

Typické rozvržení práce na webovém projektu vypadá tak, že pracujeme na lokálním vývojovém serveru a když jsme s výsledkem spokojeni, aktualizujeme kód na produkčním serveru. To můžeme udělat buď prostým přepsáním všech souborů, nebo lépe pomocí verzovacího systému. V případě centralizovaného verzovacího systému (např. SVN, CVS) soubory nahrajeme do repozitáře serveru, u decentralizo­vaného systému (např. Git, Darcs) si udržujeme repozitář i u sebe.

Ať už kód aktualizujeme jakkoliv, je vhodné si vytvořit skript, který celou proceduru nasazování nového kódu automatizuje. Jedinou výjimkou je změna databázového modelu, to Django samo o sobě nezvladá a musíme rozvržení tabulek upravit ručně (SQL příkaz ALTER TABLE) nebo použít nějaký z existujících projektů řešících tento problém. A co by takový skript měl obsahovat?

  1. Vytvoření kopie souboru settings.py.
  2. Přepsání konfiguračních konstant DEBUG, MEDIA_ROOT, MEDIA_URL, ADMIN_MEDIA_PREFIX, TEMPLATE_DIRS a případně DATABASE_NAME, pokud používáme databázi SQLite.
  3. Aktualizování souborů pomocí vzdáleného kopírování nebo verzovacího systému (včetně statických souborů).
  4. Nastavení správných přístupových práv u aktualizovaných souborů.
  5. Úprava tabulek v případě změny nějakého z modelů.
  6. Restartování produkčního webserveru.
  7. Obnovení předchozí verze souboru settings.py z kopie.

U velkých projektů doporučuji produkční webserver před kopírováním odstavit, aby náhodou nedošlo k načtení nesmyslné kombinace starého a nového kódu. Soubor settings.py lze také přepsat do univerzálnější podoby, kdy kupříkladu pomocí funkce gethostname určujeme jiné nastavení pro produkční a vývojový server. Tím by odpadl první, druhý a sedmý bod nasazování.

Serverová řešení

Existují mnoho různých variant nasazení Djanga, zaměřím se pouze na tři nejčastější. U všech předpokládám, že používáte webserver Apache a že je projekt uložený v adresáři /var/www/hrajeme_si/. Výchozí nastavení pro doménu example.cz může vypadat kupříkladu takto:

<VirtualHost *:80>
  ServerName example.cz
  ServerAlias www.example.cz
  DocumentRoot /var/www/
</VirtualHost>

Modul mod_python

Tento modul není už delší dobu vyvíjený, přesto je asi nejčastěji využívaný. Stačí v nadřazeném adresáři projektu ( /var/www/) vytvořit soubor .htaccess s tímto obsahem:

SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE hrajeme_si.settings
PythonDebug Off

Modul mod_wsgi

Toto je novější a v současnosti doporučovaný modul. V prvním kroku je potřeba přidat do části VirtualHost v nastavení webového serveru řádek s umístěním wsgi skriptu:

WSGIScriptAlias / /var/www/hrajeme_si/hrajeme_si.wsgi

A poté do tohoto souboru zapsat následující nastavení:

import os, sys

sys.path.append('/var/www/')
os.environ['DJANGO_SETTINGS_MODULE'] = 'hrajeme_si.settings'

from django.core.handlers import wsgi

application = wsgi.WSGIHandler()

Modul FastCGI

Poslední často používanou možností je spustit Django jako CGI skript pomocí modulu FastCGI. Kromě samotného modulu je potřeba pro správnou funkci pythonový balík flup a mít také povolený modul mod_rewrite. Opět je potřeba přidat do části VirtualHost několik řádků:

FastCGIExternalServer hrajeme_si/hrajeme_si.fcgi -socket hrajeme_si/hrajeme_si.sock
RewriteEngine On
RewriteRule ^/(.*)$ /hrajeme_si/hrajeme_si.fcgi/$1 [QSA,L]

Poté jenom stačí vytvořit soubor /var/www/hrajeme_si/hrajeme_si.fcgi s tímto obsahem:

#!/usr/bin/python
import os, sys

sys.path.append('/var/www/')
os.environ['DJANGO_SETTINGS_MODULE'] = "hrajeme_si.settings"

from django.core.servers.fastcgi import runfastcgi

runfastcgi(method='threaded', daemonize='false')

Tento soubor musí mít nastavená práva pro spuštění ( chmod +x /var/www/hrajeme_si/hrajeme_si.fcgi).

Související odkazy

Příště si řekneme něco o kešování a škálování velkých projektů.

Autor je dlouhodobým studentem Fakulty informatiky, webový nadšenec a programátor — nejraději programuje v jazycích Haskell a Python.

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

Komentáře: 3

Přehled komentářů

Pavel Dvořák Django in Production
Dan Produkcni nasazeni
Pavel Dvořák Re: Produkcni nasazeni
Zdroj: https://www.zdrojak.cz/?p=3119