Lighttpd: spojení s ostatními

25. 8. 2008
Doba čtení: 7 minut

Sdílet

V minulém díle jsme si řekli, co přibližně lighttpd umí, v dnešním se podíváme na některé jeho moduly pro komunikaci s ostatními technologiemi jako je CGI, fastCGI, sCGI a mod_proxy. Ukážeme si, jak předvést světu aplikaci napsanou v PHP a v Pythonu a také některé z dalších modulů.

Úvod

Lighttpd kromě servírování statického obsahu podporuje i technologie pro komunikaci s ostatními webovými aplikacemi. Těmi jsou CGI, FastCGI a SCGI. Když k lighttpd přijde požadavek na nějaký objekt, může se jednat třeba o html soubor, obrázek nebo i skript. Pokud se požadavek týká skriptu a lighttpd je tak nastaveno, odešlou se klientovi data, která skript vrátí. Tady přichází *CGI technologie, které popisují, jakým způsobem se mají dostat požadavky z web serveru do skriptu a jakým způsobem má skript odpovědět. Mluvím o skriptu, protože to je nejčastější použití, ale zvláště u zatížených serverů se klidně může pro některé části webu jednat i o normální binární program. Rozdíly mezi *CGI protokoly, které lighttpd používá, si popíšeme dále.

Konfigurace

Konfigurace v lighttpd se podobá jednoduchému skriptu. Podporuje includování, podmínky, proměnné a podle nastavení tohoto prostředí se bude chovat samotné lighttpd. Proměnné jsou pomyslně rozdělit do dvou skupin. Jedna skupina ovlivňuje parametry věcí, které jsou v jádře lighttpd a druhá má kruh vlivu u modulů. Konfigurace jaderných parametrů se provádí přes server.[parametr] a konfigurace modulů [modul].[parametr].

Moduly

Minule jsme si řekli, že lighttpd načítá při spouštění moduly. Modulů je relativně velké množství a pomáhají nám optimalizovat server přesně k našim potřebám. V dalších příkladech budeme využívat funkcionality modulů, proto bych měl zmínit, jak zajistit, aby se modul při spuštění lighttpd načetl. To zařídíme pomocí proměnné server.modules=([…]) kam umístíme seznam modulů oddělené čárkou.

CGI

CGI (Common Gateway Interface) je nejjednodušší z rodiny CGI a trpí na dnešní dobu těžko překousnutelným neduhem, kdy se musí při každém požadavku ze strany klienta spustit proces, jehož výstup se odešle. Stále se ovšem někde používá, protože je velmi jednoduchý a nevyžaduje moc administrátorských zásahů. Nejvíce bylo CGI používáno ve spojení v Perlem, ale později ho vytlačilo PHP, které si také díky dostupnosti mod_php pro Apache získávalo čím dál větší oblibu.

V lighttpd je nastavení CGI velmi jednoduché. Stačí načíst modul mod_cgi a nastavit s jakými koncovkami se budou soubory posílat jakým programům.

cgi.assign = ( ".php"  => "/usr/bin/php",
               ".py"   => "/usr/bin/python",
               ".pl"   => "/usr/bin/perl" ) 

FastCGI

Kvalitní náhradou za CGI, která se dnes používá ve spojené s frameworky jako je Django, TurboGears nebo Ruby on Rails je FastCGI. Zakládá si na úplně jiném principu, kdy aplikace běží jako daemon a webový server se k ní připojuje s požadavkem na dynamický obsah. Tím odpadlo relativně dlouhé startování skriptu/programu při každém požadavku a zlepšila se tím odezva celého webu. Na druhou stranu musí aplikace, která komunikuje přes FastCGI běžet pořád jako daemon a tím zbytečně zabírá prostor v paměti, i když ji nikdo o nic nežádá. Rychlostí FastCGI s použitím PHP se lighttpd řadí na stejnou úroveň s mod_php z Apache.

V lighttpd se FastCGI nastavuje taktéž jednoduše, i když tam je o poznání více míst, která jdou poplést. Nastavení připojení k aplikaci přes FastCGI jde dělat dvěma cestami. Při té první určíme klasickou IP adresu a port a pokud nepotřebujeme další nastavení, komunikace může začít. Druhá a možná i výkonnější možnost je využití unixových socketů. Aplikace vytvoří jen virtuální socket, jehož jeden konec umístí jako soubor na disk a na druhém sama naslouchá. Do celého procesu se neplete síťový subsystém a z pohledu systému má tak komunikace nižší režii.

Ukázka nastavení vypadá takto:

fastcgi.server = (
 <extension> => #koncovka souboru nebo prefix (např. .php,/ nebo /fcgi)
  (
    ( "host" => <string> ,                  #buď použijeme nastavení hostname
      "port" => <integer> ,                 # a portu
      "socket" => <string>,                 # a nebo předáme název souboru představující virtuální socket
      "bin-path" => <string>,               # volitelné - cesta k programu/skriptu
      "bin-environment" => <array>,         # volitelné - proměnné prostředí
      "bin-copy-environment" => <array>,    # volitelné - pokud definujeme, tak se vymažou všechny proměnné a použijí se jen naše
      "mode" => <string>,                   # volitelné - FastCGI mód (responder nebo authorizer)
      "docroot" => <string> ,               # volitelné - platí pokud je mod responder - nastavení docroot na druhé straně
      "check-local" => <string>,            # volitelné - pokud je "enable", lighttpd sám zjistí, jestli je požadovaná stránka k nalezení
      "max-procs" => <integer>,             # volitelné - maximální počet procesů
      "disable-time" => <integer>,          # volitelné - doba čekání, než se znovu zkontroluje vypnutý proces
      "allow-x-send-file" => <boolean>,     # volitelné - povolí hlavičky pro odesílání souborů
      "kill-signal" => <integer>,           # volitelné - Signál pro zabití FastCGI
    ),
    ( "host" => [...]
    )
    [...]
  )
) 

Volbu check-local je dobré vypínat ve spojení s extension / nebo jiné části url, protože u „hezkých“ URL se bude prakticky vždy jednat o neexistující fyzické cesty, a pokud by byla tato volba zapnuta, vracel by web server stránku 404.

SCGI

SCGI je principem podobné protokolu FastCGI, ale jeho implementace je jednoduší, což naznačuje i název Simple Common Gateway Interface. Jedná se o protokol, který vznikl v roce 2006. Z pohledu administrátora lighttpd se v nastavení jedná jen o změnu fastcgi.server na scgi.server.

mod_proxy

V případě, kdy chceme požadavek přesměrovat na jiný web server, použijeme mod_proxy. Konfigurace je jednoduchá a umí rozdělovat zátěž mezi velké množství serverů. Využití najde i u frameworků, které mají v sobě integrován malý web server, určený pro testovací účely. Použití je následující:

proxy.server (
    <extension> =>
    (
        ( "host" => <string> ,"port" => <integer> ),
        ( "host" => <string> , "port" => <integer> ),
        [...]
    ),
    <extension> => [...]
) 

Mod_proxy má i další parametry:

proxy.debug = 0|1 # 0 pro vypnutí ladícího hlášení a 1 pro zapnutí
proxy.balance = "hash"|"round-robin"|"fair" # podrobnosti v dokumentaci 

Access log

Logování přístupu má mnoho využití. Může se hodit při hledání špatných odkazů, může pomoci s optimalizací stránek a nebo se z díky němu dá vytvořit přehledná statistika přístupů. Lighttpd loguje dva druhy zpráv. První je log přístupů a druhý log chyb. Ten druhý je umístěn přímo v jádře lighttpd, první je pouze modul. Oba případy lze přesměrovat do syslogu, kam by se měla většina logů, pokud to výkon dovolí, směrovat. Nastavení je jednoduché a vypadá nějak takto:

Access log

accesslog.use-syslog = "enable"/"disable"

nebo

accesslog.filename = "/cesta/k/log/souboru"

a

accesslog.format   = <format> #není povinné

Error log

server.errorlog-use-syslog = "enable"/"disable"
server.errorlog: "/cesta/k/log/souboru" 

Uživatel si může nadefinovat, jak budou jednotlivé řádky logu vypadat. V dokumentaci je velká tabulka s hodnotami, které lze použít.

Dirlisting

Pro sdílení obsahu disku slouží modul mod_dirlisting. Modul je zaveden, i když ho neuvedeme v server.modules. Parametry, které můžeme použít ve spojení s dirlistingem, jsou následující:

server.dir-listing           - zapnout či vypnout listování adresářů
dir-listing.activate         - to samé
dir-listing.external-css     - cesta k externímu css souboru
dir-listing.encoding         - nastavení kódování
dir-listing.hide-dotfiles    - schovat soubory s tečkou (skryté soubory)
dir-listing.show-header      - vložit HEADER.txt nad list souborů
dir-listing.hide-header-file - schovat HEADER.txt
dir-listing.show-readme      - vložit README.txt nad list souborů
dir-listing.hide-readme-file - schovat README.txt
dir-listing.exclude:         - schová soubory, které vyhovují zadaným regulárních výrazů
dir-listing.set-footer       - Zobrazí zadaný text v patičce 
lighttpd-dirlisting

Příklad

Pro ukázku dnes zmíněných voleb uvedu vylepšený příklad z minula.

@%&@

bitcoin_skoleni

#moduly, které se mají načíst
server.modules = ("mod_accesslog","mod_dirlisting","mod_scgi","mod_fastcgi","mod_proxy")
#uživatel a skupina, pod kterými pojede lighttpd
server.username            = "lighttpd"
server.groupname           = "lighttpd"
server.use-ipv6            = "enable" #povolení IPv6
server.errorlog-use-syslog = "enable" #použít syslog na logování chyb
accesslog.use-syslog       = "enable" #použít syslog na logování přístupu
server.indexfiles          = ("index.html", "index.htm")
server.document-root       = "/home/share" #kde má mí web server /
dir-listing.activate       = "enable" #povolit vylistování obsahu adresáře
include "mime-types.conf"
#přesměrování požadavků na scgi server, na který jsme připojeni přes unixový socket
#přesměrovávají se požadavky z URL začínající na "/framework"
$HTTP["url"] =~ "^/framework" {
    scgi.server = (
        "" => (( "socket" => "/tmp/test.sock",  "check-local" => "disable"))
    )
}
#přesměrování všech požadavků na doménu root.cz na 127.0.0.1:29001
$HTTP["host"] == "root.cz" {
        proxy.balance = "hash"
        proxy.server = (
        "" => (( "host" => "127.0.0.1", "port" => 29001))
        )
}
#nastavení pro PHP vypadá podobně jako u scgi
$HTTP["url"] =~ "^/php" {
    fastcgi.server = (
        ".php" => (( "bin-path" => "/usr/bin/php-cgi","socket" => "/tmp/php.socket"))
    )
}

@%&@

Závěr

Příště představím pár zajímavých modulů, proberu podrobněji možnosti konfigurace a hlavně ukážu, jak je na tom ligttpd s provozem více webů najednou.

Autor článku

Adam Štrauch je redaktorem serveru Root.cz a svobodný software nasazuje jak na desktopech tak i na routerech a serverech. Ve svém volném čase se stará o komunitní síť, ve které je již přes 100 členů.