„Prostě to tam nahrajte FTPčkem“ – nebo ne?

Server

Nahrání skriptů na server (angl. deploy, česky „nasazení“) mnozí považují za věc, u které není moc co řešit. Co taky řešit u něčeho tak triviálního, jako je upload skriptů, že? Pojďme se podívat na některé věci, které s nahráváním skriptů souvisí, a ukažme si, jak je řešit pomocí verzovacího systému.

V souborech README, v manuálech, návodech a knihách čteme často větu „Skripty nahrajeme na server…“ Některé jazyky či některé frameworky mají vlastní nástroje, které tuto problematiku řeší; těmi se zde zabývat nebudeme. Budeme se věnovat tomu obyčejnému, všednímu postupu, známému všem autorům webů… Řečeno s jednou reklamou: takovému tomu domácímu webaření.

FTP – a kde je problém?

Mnozí webaři už teď kroutí hlavou: kde je problém? Prostě nahraju na server přes FTP potřebné soubory, a je to! 

Autor těchto řádků si vzpomíná na to, jak v roce 2003 řešil deploy svého vlastního projektu, maje modem rychlosti 56.6kbps a nespolehlivé telefonní připojení, placené navíc „od minuty“ (někteří jistě pamatují). Člověk se připojil na server, zjistil, že je někde chyba, a teď ho čekalo rozhodnutí: Bude oprava natolik rychlá, že ji stihne nahrát hned, nebo bude lepší se odpojit, opravit a nahrát až pak? A opravdový problém nastal, když nahrával třeba index.php a v půlce přenosu spadlo spojení. Ubíhaly minuty, zaplněné marnými pokusy o připojení, a když se po půl hodině podařilo spojení opět navázat a soubory nahrát, čekalo v mailu už několik vzkazů a la „Nevím jestli to víš, ale nefunguje ti server, hlásí to chybu!

Dnes je vytáčené spojení (snad) minulostí, takže podobné problémy spíš nehrozí, přesto pokud děláte „deploy TotalCommanderem“, hrozí nemalé riziko nekonzistence skriptů během uploadu. Pokud se nějaký uživatel v tu chvíli připojí, může se stát, že část skriptů bude „nových“, část „starých“. Když nahráváte třeba 400 souborů najednou (což např. u WYSIWYG editorů, plných malých ikonek, není výjimkou), a přenos jednoho, dvou selže, čekají vás navíc nepříjemné chvíle při hledání „podivných“ chyb.

Najednou!

Řešením takových problémů je simulace atomicity, tj. upload souborů „najednou“ (viz vlákno diskuse). Někdo to řeší tak, že má web např. v adresáři „web“, novou verzi nahraje do adresáře „new“, a pak co nejrychleji přejmenuje „web“ na „old“ a „new“ na „web“. U tohoto přístupu bývá problémem to,že nelze použít běžné nástroje pro „FTP synchronizaci“ a přenášet jen změněné soubory, musíte vždy přenést vše.

Pokud to server umožňuje, je velmi dobrým řešením sbalit úpravy do jednoho souboru (např. .tar.gz), ten nahrát na server a pak na něm spustit „rozbalení a přepsání“. Mnohé hostingy sice neumožňují SSH přístup, ale lze využít třeba webového „správce souborů“, kde funkce „rozbalit archiv“ bývá. Rozbalení archivu je několikavteřinová operace, což lze v řadě případů považovat za „téměř atomickou“ – v porovnání s uploadem přes FTP, který je vždy řádově delší.

Výhoda uploadu jediného souboru se ukáže obzvlášť při nahrávání některých velkých frameworků, knihoven či CMS, které obsahují mnoho malých souborů. Například taková sada miniaturních vlaječek států, kde každá ikonka GIF zabírá pár desítek bajtů, ale je jich stovka, je leckdy záležitost na několik minut; pokud jsou sbalené v archivu, trvá upload pár sekund.

Maintenance

Pokud bude deploy trvat delší dobu – ať už kvůli tomu, že budete muset přenášet via FTP jeden soubor za druhým, nebo kvůli tomu, že budete dělat nějaké změny v databázi – je dobré mít připravené „maintenance“ řešení, tedy postup, kterým se uživatelům zobrazí pouze hlášení o tom, že na serveru probíhá údržba. Pokud používáte Apache a máte možnost měnit .htaccess (což kupodivu i v roce 2011 není v ČR vždy samozřejmostí), můžete si vytvořit „maintenance“ verzi, v níž všechny požadavky přesměrujete na jednu prostou HTML stránku („udrzba.html“), kde informujete o tom, že probíhají změny a o tom, kdy zhruba bude server opět v provozu.

Alfa, beta, stage, page…

U malých projektů většinou nikdo neřeší nějaké pracovní kopie a podobné – projekt existuje „u vývojáře v počítači“ a na serveru. U větších projektů je (snad…) už pravidlem, že projekt běží na několika serverech, které mají jasně určené role. Jedním z možných uspořádání je např. toto:

Vývojáři (programátoři, grafici, kodéři…) mají na svých počítačích pracovní kopie a úpravy nahrávají na server Test. Ten je dostupný pouze zvnitřku firmy a na něm probíhá testování – ať už strojové, tak „lidské“. Pokud je sada úprav hotová a funkční, nahrává se na server Stage. Ten může být dostupný i vybraným testerům zvenčí. Je to kopie 1:1 ostrého serveru – stejná konfigurace, stejné prostředí – a slouží k ověření úprav betatestery. Když je nějaká větší sada úprav ověřená na stage, může být někým vyhrnuta na ostrý Live server.

Konkrétní rozdělení úloh se může lišit – podle zvyklostí či specifických potřeb firem a jejich projektového řízení.

Verzovací systém

Verzovací systémy, jako třeba Git či Mercurial (viz Pět důvodů, proč zvolit Git), mohou výrazně usnadnit celý proces „deploymentu“ (nasazení), a to především tím, že je v nich snadné určit změny, které mají být nahrány, od změn, na kterých se ještě pracuje. Konkrétní podoba workflow je opět na zvyklostech a rozhodnutí projektového managementu.

Velká výhoda DVCS je v tom, že repozitář lze vytvořit kdekoli. Na serverech Test, Stage i Live může být adresář s webem zároveň repozitářem, do kterého jsou „pushovány“ změny. Pomocí „hooks“, čili činností volaných při určité operaci, lze zajistit např. automatické rozbalení změn po jejich úspěšném nahrání na server.

Vývojáři si změny „commitují“ do svých pracovních (lokálních) repozitářů, a pokud jsou s nimi spokojeni, provedou „push test“. Změny se tak projeví na serveru test, kde je lze ověřit, spustit strojové testy a další potřebné operace (viz metoda Continuous Integration). Úspěšné úpravy jsou pak označeny (opět ve verzovacím systému) příznakem, podle něhož budou nahrávány na Stage. Nahrání na Stage je opět jednoduchá operace „push“. Po úspěšném ověření na stage opět nastupuje „push“, kterým jsou změny zapsány na Live server.

Výhoda „pushování“ proti přenášení souborů FTP je zřejmá: Při „push“ je přenášena pouze sada změn vůči aktuálnímu stavu. DVCS řeší i případy konfliktů souborů. Přenášení je nezávislé na běhu serveru. Následné „rozbalení“ změn do pracovního adresáře webu je podobné výše popsanému rozbalení změnového archivu. Výhoda je, že veškerou režii s „balením“ úprav do archivu  a jejich následným rozbalením si řeší verzovací systém. Minimalizují se tak chyby vzniklé z nepozornosti (zde platí modifikované přísloví „Opakování je matkou chyb!“)

Praktický příklad

Autor už nepracuje jako vývojář, přesto si nějaké menší webové projekty čas od času udělá. Při vývoji používá verzovací systém Mercurial. Jeho workflow lépe vyhovuje autorovým potřebám než Git, proto v následujícím textu budou příklady používat právě Mercurial. V systému Git by byl pravděpodobně postup velmi podobný.

Prvním impulsem k vyzkoušení něčeho jiného než FTP byla u autora touha zkusit si prakticky framework Django na vlastním serveru. Server běžel u VirtualMaster jako VPS (pro zájemce je k dispozici šablona), takže nebyl problém nainstalovat cokoli.

Několik hostingů z poslední doby, např. Heroku či No.de, používá k nahrání souborů na server právě verzovací systém (konkrétně Git). Implementace takového způsobu je (téměř by se chtělo říct „pozoruhodně“) snadná. Autor na vlastním systému postupoval takto:

  1. Nainstaloval Mercurial (z balíčků)
  2. Vytvořil uživatele „deployer“, v adresáři /home/deployer vytvořil odkaz na adresář se skripty a pojmenoval ho repo (ln -s)
  3. Vytvořil na serveru v /home/deployer/repo repozitář („hg init“) – budeme si jej označovat jako „remote“
  4. V remote repozitáři upravil soubor .hg/hgrc – přidal toto:
    [hooks]
    changegroup = hg up
  5. Výše uvedená změna zajistí, že v případě nahrané změny (changegroup) je vyvolán příkaz „hg up“, který „rozbalí“ aktuální verzi včetně nahraných změn do pracovního adresáře. V tomto místě tedy probíhá ono „rozbalení“.
  6. Po několika testech nahradil „hg up“ voláním skriptu „deploy“ – běžný shell script, který zařídí rozbalení změn a restart wsgi.
  7. Na lokálním stroji vytvořil opět repozitář (hg init)
  8. V lokálním repozitáři si do .hg/hgrc uložil informace o vzdáleném repozitáři:
    [paths]
    default = ssh://deployer@12.34.56.78/repo
  9. Následoval první commit a zkušební push.

Nyní stačí veškeré změny „commitnout“ pomocí hg commit. Nahrání na server je pak otázkou jediného „hg push“ – v jeho rámci si Mercurial sebere provedené změny, nahraje je na server, tam jsou změny promítnuty do pracovního adresáře a server je restartován.

Sdílený hosting + PHP + Mercurial

Druhý pokus byl s PHP hostingem – autor používá levný zahraniční sdílený hosting pro některé PHP projekty, který má přes svou láci některé vlastnosti, co nenabízí ani mnohem dražší české hostingy v této kategorii: zde konkrétně přístup přes SSH a možnost spouštění skriptů v Pythonu.

Mercurial je napsaný v Pythonu, takže k jeho instalaci na server nemusíte mít žádná extra práva; lze jej nainstalovat jako běžný Pythonský skript. Zájemci mohou čerpat inspiraci v článku, kde je popsána instalace Mercurialu a spuštění hgweb na hostingu HostMonster. Postup bude podobný i u jiných hostingů, kde můžete spouštět Python a kde se můžete přihlásit pomocí SSH. Další kroky jsou podobné výše uvedenému postupu.

Díky funkčnímu hgweb není potřeba nastavovat přístup k remote repozitáři přes SSH, lze použít http rozhraní. Stačí nastavit práva k adresáři s hgweb skriptem pomocí souboru .htaccess a direktiv AuthUserFile apod.

V lokálním úložišti si patřičné údaje nastavíme opět v .hg/hgrc – např. takto:

[paths]
default = http://deploy:PASSWORD@www.example.com/hg/home1/path/to/my/project
[ui]
username = deploy

Další postup je stejný jako u výše uvedeného příkladu s Djangem.

Co používáte k nasazení souborů na server?

Závěr

Výše uvedené postupy, náměty a příklady popisují možný způsob řešení obvyklých problémů, spojených s nahráváním skriptů a dat na server. Berte je, prosím, jako inspiraci k vlastnímu řešení, jako „postrčení“ k o něco pohodlnějšímu a bezpečnějšímu způsobu nahrávání skriptů, spíš než jako dogma či jediný možný způsob.

Velké firmy a webová studia většinou mívají tyto procesy už nějak nastavené, ale menší firmy či mnozí freelanceři stále používají ad hoc způsob „deploy TotalCommanderem“. Účelem článku bylo ukázat, že to lze řešit i jinak, pohodlněji, a že toto řešení není s moderními DCVS nijak přehnaně obtížné.

Poznámka k hostingu

Jako v posledních letech několikrát je i tentokrát míč na straně poskytovatelů hostingu. Čeští poskytovatelé mají v této oblasti stále hodně co dohánět, ovšem to je obecný problém. Zatímco ve světě bylo (a je) běžné nabízet „neomezený“ počet domén k jednomu účtu i u levných sdílených hostingů, u nás je to stále trochu unikátní služba. Přístup pomocí SSH ke sdílenému hostingu nabízí v ČR zatím snad jediný poskytovatel. Převládající přístup je stále „Upload přes FTP, co byste chtěli řešit?

Poskytovatelé hostingu v ČR mají stále obrovský „dluh“ vůči moderním technologiím, a zrovna třeba nasazení skriptů pomocí verzovacího systému by mohla být pro ty progresivnější vhodnou „konkurenční výhodou“.

Začal programovat v roce 1984 s programovatelnou kalkulačkou. Pokračoval k BASICu, assembleru Z80, Forthu, Pascalu, Céčku, dalším assemblerům, před časem v PHP a teď by rád neprogramoval a radši se věnoval starým počítačům.

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

Komentáře: 39

Přehled komentářů

Kepi SSH přístup a deploy
Martin Malý Re: SSH přístup a deploy
Tomas Re: SSH přístup a deploy
Tomas Re: SSH přístup a deploy
Martin Malý Re: SSH přístup a deploy
Martin Malý Re: SSH přístup a deploy
janvlcek Re: SSH přístup a deploy
patrik.sima Re: SSH přístup a deploy
Michal Re: SSH přístup a deploy
smilelover SCP pres Ant
Martin Malý Re: SCP pres Ant
K-Kamil Další protokoly
Tom Re: Další protokoly
Jerry12 Re: Další protokoly
- Preklad deploy
Čelo git-deploy
salko RSync
Petr Re: "Prostě to tam nahrajte FTPčkem" - nebo ne?
patrik.sima Git-ftp
dasim Re: "Prostě to tam nahrajte FTPčkem" - nebo ne?
Tomáš Bláha diff/patch
v6ak Maintenance a AJAX
Michal Holub Capistrano web interface
edois aptitude
ins Re: aptitude
Martin Malý Re: aptitude
František Kučera Re: aptitude
edois Re: aptitude
koubel Re: aptitude
xzajic RSYNC
OldFrog Re: RSYNC
v6ak Re: RSYNC
Martin PHP deployment
Tharos Re: PHP deployment
Petr Re: PHP deployment
Almad Rollback?
Petr find + lftp
Tomáš PHP hostingy s APC a jiné
Michal Wiglasz Re: PHP hostingy s APC a jiné
Zdroj: https://www.zdrojak.cz/?p=3401