Git deployment Node.js aplikácie na Raspberry Pi

Publikoval Michal Kočí dňa 16.7.2015 o 11:00 v kategóriach Node.js a Raspberry Pi

Ak používate Git ako verzovací systém pre zdrojové kódy vašej aplikácie, možno ste postrehli, že je docela populárne (a právom) robiť deployment aplikácie práve cez Git. Dnes sa pozrieme ako na to, ak máte Raspberry Pi a na ňom hostujete svoje webové aplikácie.

Prečo robiť deployment cez Git?

Lebo je to šikovné, rýchle a jednoduché. Ale nie nutné. Ak máte Node.js aplikáciu, tak deployment (alebo inak povedané rollout) znamená, že musíte na váš server dostať zdrojové súbory vašej aplikácie (javascript, css, html, obrázky, ...) rovnako aj všetky závislosti (obvykle obsah adresára node_modules).

Pokiaľ sa jedná o *nixový server, môžete použiť na nahratie súborov scp (secure copy), ftp (ak máte na serveri ftp nainštalované) alebo obdobný nástroj. Na serveri potom potrebujete dostať aplikáciu do správneho adresára.

Ak súčasťou toho, čo ste na server dostali nie sú závislosti (node_modules), musíte si ich na serveri nainštalovať. A potom reštartnúť web, samozrejme len v prípade, že nemáte sledovanie zmien ktoré si ho reštartne samo (ukázali sme si v minulom príspevku).

To je docela dosť práce, navyše manuálnej a tak je veľká šanca, že niekde spravíte chybu a ak aj nie, tak sa pravdepodobne pri každom ďalšom deploymente budete viac a viac nudiť. Nebolo by lepšie robiť to celé automatizovane? Samozrejme, že bolo...

Ako funguje Git deployment?

Princíp je veľmi jednoduchý. Najskôr si na serveri nainštalujete Git a pripravíte si prázdne repository pre váš projekt. Potom si pre toto repository pripravíte tzv. hook, teda skript, ktorý sa spustí po nejakej aktivite - v našom prípade to bude post-update, teda hook ktorý sa vykoná po git push.

Tento skript si pripravíme a v ňom zabezpečíme, že si vaša aplikácia, ktorá bude niekde inde na serveri nainštalovaná (cez git clone) potiahne aktuálnu verziu (git pull). Ak v repository nemáte commitnuté externé závislosti (node_modules), tak ich skript nainštaluje. A ak máte nastavené sledovanie zmien v adresári, aplikácia sa reštartne a vy hneď bežíte novú verziu.

Ako nainštalovať Git deployment na serveri

V prvom rade si naištalujte samotný Git:

sudo apt-get install git

Či sa vám nainštaloval správne si overíte ľahko, necháte si vypísať verziu:

git --version

Dobre, Git nainštalovaný, teraz si potrebujete vytvoriť samotné repository. Môžete ho mať napríklad v adresári git, ktorý bude vo vašom domovskom adresári:

cd ~
mkdir git
cd git

Pre účely nášho príkladu budeme ďalej predpokladať, že:

  • sa jedná o vašu prvú aplikáciu a tak budeme používať názov myfirstapp
  • je na serveri už nainštalovaná v adresári /var/www/myfirstapp
  • vaše užívateľské meno na Raspbery Pi je jasam
  • vaše Raspberry má IP adresu 10.0.1.10

Ak sa čokoľvek z vyššie uvedeného vo vašom prípade líši, tak to v príkladoch nižšie patrične zmeňte.

Chceli by ste sa rýchlo a ľahko naučiť programovať webové aplikácie v Javascripte a bežať ich na Node.js? Jednoduché. Rád vás to naučím na mojom školení Node.js - serverových aplikácií v Javascripte.

Poďme si teda vytvoriť samotné repository, stále sme v adresári ~/git

mkdir myfirstapp.git
cd myfirstapp.git
git init --bare

Vytvorili sme myfirstapp.git adresár a v ňom sme inicializovalé prázdne repository. Do neho budeme pushovať aplikáciu, ktorú chceme deployovať. V tomto adresári sa vytvoril adresár hooks a v ňom ukážkové hook skripty, všetky majú príponu .sample a tak sú neaktívne.

Drobné upozornenie. Toto je klasické repositoty, ktoré si udržiava informácie o obsiahnutých súboroch, commitoch, branchoch a podobne. Čiže priamo tento adresár nechcete použiť na bežanie vášho webu - ten budete bežať z iného adresára, klonu tohto repository.

Pridanie repository na vašom vývojovom počítači

Ešte než si pripravíme hook, vráťme sa na váš vývojový počítač a pridajme si toto repository. Vychádzam z toho, že váš adresár, v ktorom máte vývojovú verziu aplikácie je naklonovaný z vášho hlavného Git repository (napríklad z bitbucketu alebo githubu).

Pozrieť sa aké remoty máte na adresár napojené viete týmto príkazom spusteným v danom adresári:

git remote -v

Ukáže vám všetky remotes, teda ich názvy a cesty pre fetch a push. Pokiaľ ste s remotes nič nerobili, tak vám pravdepodobne vypísalo dva riadky, oba s názvom origin a s cestou k vášmu repository, jeden pre fetch a druhý pre push.

Čo je na Gite úžasné je, že adresár môžete mať napojený na viac remotov, čo sa hodí aj v tomto prípade. Jeden (obvykle origin) máte napojený na vaše hlavné git repository a druhý (budeme ho volať prod) budete mať na deployment.

Pridajme si teda ďalší remote, patrične upravte parametre príkazu (užívateľské meno, IP adresu a prípadne adresár vášho Rapsberry Pi git repository):

git remote add prod ssh://jasam@10.0.1.10/home/jasam/git/myfirstapp.git

Čiže, pridali sme nový remote s názvom prod, pristupovať k nemu sa bude cez ssh, pripájať sa bude na počítač s IP 10.0.1.10, použitý bude užívateľ jasam a na Raspberry Pi je toto git repository na ceste /home/jasam/git/myfirstapp.git.

Môžete si zase vylistovať remoty (cez git remote -v), teraz by v nich mal byť ako origin, tak aj prod.

Najvyšší čas pushnúť do vášho Raspberry Pi. Spravte teda push, samozrejme do remotu prod, buď cez grafickú aplikáciu ak nejakú používate (napríklad TortoiseGit či SourceTree) alebo cez príkazový riadok:

git push prod

Výborne, práve ste pushli aktuálnu verziu na vaše Raspberry Pi. To ešte nie je nakonfigurované na deployment, ale aby sme všetko riadne pripravili, je dobré mať na ňom už aplikáciu v danom repository.

Naklonovanie repository do adresára aplikácie

Vaša aplikácia je nainštalovaná v adresári /var/www/myfirstapp a dostali ste ju tam buď nejak manuálne, alebo ste ju tam manuálne vytvorili, to je jedno. Čo chceme dosiahnuť je, že tento adresár bude klonom repository, nebudete v ňom robiť manuálne zmeny, ale všetky zmeny budete robiť na vašom vývojovom stroji a publikovať do produkcie cez git.

Začnime teda tým, že tento adresár zmažete, ak existuje. Áno, zmaže to váš adresár, takže s rozumom, uistite sa, že všetky zmeny máte v Gite a pushnuté na Raspberry Pi aby v momente, keď nastavíme klon ste mali späť adresár s tou verziou, ktorú chcete.

cd /var/www
sudo rm -rf myfirstapp

Adresár je v tomto momente zmazaný, poďme si naklonovať repository:

git clone ~/git/myfirstapp.git
cd myfirstapp

Naklonovali ste repository, ktoré sa nachádza v adresári ~/git/myfirstapp.git do adresára /var/www/myfirstapp - tento vám rovno vytvoril git. V ňom teraz nájdete samotnú aplikáciu.

Ak do repository necommitujete node_modules ale nejaké moduly používate, musíte si ich ešte nainštalovať. Či ich komitovať alebo nie je na vás, názory sa rôznia, ja osobne tento adresár nekomitujem.

Ak používate npm, tak viete, že je dobré si pri inštalácii balíčka zvoliť jeho uloženie (respektíve informácie o ňom) do konfiguračného súboru package.json. Na to sa používa parameter --save alebo --save-dev.

Rozdiel v nich je, že parameter --save by ste mali používať pre balíčky, ktoré sú potrebné pre beh aplikácie a --save-dev na balíčky, ktoré používate iba na vývojovom prostredí. Napríklad gulp a podobné nástroje potrebujete pri vývoji, pred commitom a podobne, ale nie sú nutné pre beh aplikácie a tak ich inštalujete iba pre dev.

Ak to takto robíte, robíte to dobre a potom pri inštalácii balíčkov na produkčnom serveri použijete nasledujúci príkaz:

npm install --production

Ak to tak nerobíte, možno by ste mali, v tom prípade použite príkaz bez parametra --production a to isté bude platiť za chvíľu, keď budeme robiť post-update hook.

npm install

Vytvorenie post-update hooku

Paráda, blížime sa k úspešnému koncu. Máme rozbehané git repository, máme na lokálnom počítači toto repository pridané ako remote, ostáva už len vytvoriť samotný hook.

Prejdite do adresára hooks vo vašom repository (nie v jeho klone) a vytvorte v ňom súbor post-update:

cd ~/git/myfirstapp.git/hooks
nano post-update

A do tohto skriptu zapíšte nasledovné:

#!/usr/bin/env bash
pwd
echo "Switching to directory"
cd /var/www/myfirstapp
echo "Unsetting git directory"
unset GIT_DIR
echo "Updating local folder"
git pull
echo "Installing dependencies"
npm install --production
echo "Done"

Skript sa dá osekať a vypisuje priebežne čo robí, aby ste videli pri pushhnutí čo presne sa deje. Ak nechcete, riadky začínajúce s pwd a echo odstráňte.

Skript najskôr vypíše aktuálny adresár a prepne sa do adresára, kde je repository naklonované. Odnastaví premennú GIT_DIR, ak to nespravíte, nebude vám to fungovať - skript beží v kontexte Gitu a tak treba túto premennú odnastaviť. Keď je skript prepnutý do správneho adresára, poriahne si poslednú nakomitovanú verziu a nainštaluje npm balíčky.

Uložte súbor a máte hotovo. Keď najbližšie spravíte push do tohto repository, automaticky sa vám zaktualizuje aplikácia a ak používate napríklad forever-service, ktorý sme inštalovali v predminulom príspevku, aplikácia sa pekne zreštartuje. A všetko pri pushnutí uvidíte vo výstupe, bude to vyzerať takto nejak:

remote: /home/jasam/git/myfirstapp.git
remote: Switching to directory
remote: Unsetting git directory
remote: Updating local folder
remote: From /home/jasam/git/myfirstapp
remote:    3e9d573..5522bca  master     -> origin/master
remote: Updating 3e9d573..5522bca
remote: Fast-forward
remote:  app.js |    2 +-
remote:  1 file changed, 1 insertion(+), 1 deletion(-)
remote: Installing dependencies
remote: npm WARN package.json myfirstapp@1.0.0 No README data
remote: Done here

Možno to nebolo málo krokov, uznávam, ale raz nastavíte a váš deployment bude nabudúce na jeden jediný príkaz (git push) a tak námaha teraz vynaložená sa vám veľa krát vráti.

Mohlo by ťa tiež zaujímať

Páčil sa ti príspevok?

Zdieľaj príspevok alebo si ho odlož na neskôr

Sleduj ma

Ak nechceš premeškať príspevky ako je tento, sleduj ma na Twitteri, alebo ak máš RSS čítačku, môžeš sledovať môj RSS kanál.

Komentáre

K tomuto článku nie su pridané žiadne komentáre.

Pridať komentár

Máš niečo zaujímavé povedať k článku? Pridaj to k článku ako komentár. Spam, reklamu alebo inak nerelevantné komentáre okamžite mažem.