Automatický deploy webových aplikací pomocí Gitu

Tento článek částečně navazuje na článek o sdílených repozitářích Gitu zde Sdílené repozitáře verzovacího systému GIT (git, gitweb, gitosis). Obsahuje ukázku možného řešení automatického deploy-e web aplikace na webový server pomocí Gitu.

Hook skripty

Git umožňuje na základě různých událostí spouštět vlastní akce pomocí takzvaných hook skriptů. Tyto skripty se nacházejí v každém repozitáři, konkrétně uvnitř repozitáře v adresáři .git/hooks. Tyto skripty se dělí podle událostí, které je spouští, na klientské a serverové. V tomto článku se budeme věnovat pouze jednomu z nich, a to serverovému post-receive. Pro informace o všech skriptech doporučuji navštívit http://git-scm.com/book/en/Customizing-Git-Git-Hooks.

Dostupné jsou tyto skripty:

  • applypatch-msg
  • pre-applypatch
  • post-applypatch
  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • pre-rebase
  • post-checkout
  • post-merge
  • pre-receive
  • update
  • post-receive
  • post-update
  • pre-auto-gc
  • post-rewrite

Jak je popsáno v dokumentaci na adrese výše, skript post-receive je volán jakmile je kompletně dokončen push veškerých změn na server. Je to tedy ideální událost pro deploy změněných dat na server s webovou aplikací.

Lokální deploy na serveru s repozitářem

Mějme na svém disku repozitář web.git, který je naklonovaný například z repozitáře gitserver:repositories/web.git. Na stejném serveru jako se nachází git repozitář (gitserver) běží i webový server s webem.

Adresářová struktura na serveru je například:

Cesta ke git repozitáři:
/var/git/repositories/web.git

Kořenový adresář webserveru:
/var/www/

Cílem je vytvořit automatický deploy webu z repozitáře web.git do adresáře /var/www.

Nejdříve v lokálním repozitáři vytvoříme novou větev s názvem „live“. Obsah této větve bude vždy odpovídat obsahu adresáře /var/www na serveru.

$ git checkout -b live

To je z úprav v lokálním repozitáři vše. Nyní je potřeba přihlásit se na server a přejít do adresáře /var/git/repositories/web.git/hooks. V tomto umístění se nachází skript post-receive.sample. Přejmenujeme ho na post-receive

[/var/git/repositories/web.git/hooks] $ mv post-receive.sample post-receive

a přidáme mu práva na spuštění:

[/var/git/repositories/web.git/hooks] $ chmod +x post-receive

V tomto skriptu je možné z informací v commitu zjistit, do které větve aktuální změny patří. Skript post-receive přijímá tři argumenty: identikátor původní revize, identifikátor nové revize a název reference. Obsah skriptu post-receive kompletně odstraníme a vložíme do něj tento kód:

#!/bin/bash

while read oldrev newrev refname
do
  branch=$(git rev-parse --symbolic --abbrev-ref $refname)
done

V uvedeném kódu se zjistí, do jaké větve se aktuální změny nahrávají a název větve se zapíše do proměnné „branch“. Protože deploy webu chceme provést na základě aktualizace větve „live“, stačí ověřit, jestli se změny zapsaly do této větve:

#!/bin/bash

while read oldrev newrev refname
do
  branch=$(git rev-parse --symbolic --abbrev-ref $refname)

    if [ "live" == "$branch" ]; then
       echo "Deploy webu..."
    fi
done

Pokud nyní provedeme push z lokálního repozitáře do větve live, dostaneme odpověď podobnou této:

$ git push origin live

Counting objects: 12, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (8/8), 646 bytes, done.
Total 8 (delta 2), reused 0 (delta 0)
remote: Deploy webu...
To git@forest:repositories/test.git
271583b..a9d3aa1 live -> live

Nyní tedy stačí skript naučit přesunout data do adresáře webového serveru. Repozitáře na serveru jsou inicializovány obvykle s příkazem –bare, což znamená, že nemají pracovní adresář. Ten lze však ze serverového repozitáře získat doplněním parametru „–work-tree“, v tomto případě takto:

git --work-tree=/var/www checkout -f live

Finální skript vypadá takto:

#!/bin/bash

while read oldrev newrev refname
do
  branch=$(git rev-parse --symbolic --abbrev-ref $refname)

  if [ "live" == "$branch" ]; then
    git --work-tree=/var/www checkout -f live
  fi
done

Jakmile se provede push z lokálního repozitáře do větve live, přesunou se data v pracovním adresáři do adresáře webserveru a tím se automaticky zveřejní světu.

git1

Vzdálený deploy na server s webovou aplikací

Častěji se stává, že serverový repozitář je na jiném serveru, než na kterém běží webová aplikace. V takovém případě je potřeba v lokálním repozitáři vytvořit nový vzdálený repozitář. Například takto:

git remote add web ssh://uzivatel@server:/var/repositories/site.git

Repozitář v umístění /var/repositories/site.git musí na serveru samozřejmě existovat. V repozitáři jsou stejně jako v předchozí kapitole tzv. hook skripty (/var/repositories/site.git/hooks/). Pro zjednodušení zde použijeme stejný skript jako v předchozí kapitole. Do skriptu /var/repositories/site.git/hooks/post-receive tedy vložíme tento obsah:

#!/bin/bash

while read oldrev newrev refname
do
  branch=$(git rev-parse --symbolic --abbrev-ref $refname)

  if [ "live" == "$branch" ]; then
    git --work-tree=/var/www checkout -f live
  fi
done

Nyní je možné pracovat například na větvi master jako obvykle a změny posílat do repozitáře na server s gitem.

$ git push origin master

V okamžik, kdy máme práci hotovou a chceme změny poslat na webový server, stačí se přepnout na větev live, sloučit do ní změny z větve master a poslat na server:

$ git checkout live
$ git merge master
$ git push web live

Následně se na serveru provede skript post-receive, který data přesune do adresáře webového serveru.

git2

Závěr

Článek obsahuje jeden z možných způsobů, jakým si lze přizpůsobit git. Obsah se zaměřuje především na princip, neřeší další souvislosti jako jsou práva souborů a dodatečné operace potřebné k funkčnímu zprovoznění webové aplikace na webovém serveru. V případě jakýchkoliv dotazů mne můžete kontaktovat na info@bcvsolutions.eu.