neljapäev, 1. oktoober 2015

Koodi deployment veebiserverisse

Vanadel headel aegadel oli koodi saatmine serverisse väga lihtne ning selleks võlusõnaks oli FTP. Näiteks töötasin umbes 10 aastat tagasi ühes veebiagentuuris, kus tegime PHP põhiseid veebilehti. Deployment nägi seal välja ülilihtne, nimelt kasutasime koodi kirjutamiseks Zend Editori, millel oli sisse ehitatud FTP tugi. Kui tahtsime midagi (live's) muuta, siis avasimegi editori, klikkisime ikoonil Open ja valisime FTP serveris asuva faili. Peale muudatuse tegemist klikkisime ikoonil Save, editor salvestas faili otse üle FTP serverisse ja oligi muudatus deploy'tud. Seejärel tuli brauseriaknas vajutada klahvile F5 ning muudatus saigi nähtavaks, mis saaks olla veel mugavam?

Paraku olid sellisel lähenemisel omad probleemid. Esiteks muidugi ei olnud ju selline uuendus kuidagi versioonitud. Kuna tegu oli lihtsalt faili üle kirjutamisega, siis muudatus kuskile kirja ei läinud ja seega ei olnud võimalik ka kergelt muudatust tagasi keerata. Kodukootud varunduslahenduseks oli lihtsalt aegajalt kõik serveris olevad failid FTP kaudu korraga alla laadida ja zip faili salvestada. Kui nüüd oli vaja mingeid muudatusi tagasi võtta, siis tuli vastav zip fail üles leida (eeldusel, et olid viitsinud/taibanud selle varukoopia üldse teha), lahti pakkida ja õige fail üles leida. Halval juhul tuli pöörduda hostingupakkuja poole ja neilt viimast backup'i lunida.

Aegajalt tuli ette ka race condition'it, juhul kui mitu arendajat sama faili kallal toimetasid ja siis üksteise muudatusi oma muudatustega üle salvestasid. Seda juhtus samas väga harva, kuna reeglina oli üks arendaja projekti kohta.

Minu totaalne lemmik oli salvestamine võrguprobleemide korral. Mida see üldse tähendab, et editor salvestab mingi faili FTP'sse? See tähendab, et kõigepealt avatakse FTP kaudu serveris fail kirjutamiseks ja seda nii, et faili pikkus lühendatakse 0 baidini ja seejärel siis kirjutatakse sellesse avatud faili selle faili uuenenud sisu. Mingist transaktsioonilisest faili kirjutamisest võis sellisel puhul vaid unistada. Praktikas juhtus tihti nii, et editor avas faili (ehk lühendas selle 0 baidini) kuid siis tekkis võrguprobleem ja Zend Editor viskas selle peale pikema jututa pildi taskusse. Tulemus? Serveris oli nüüd vana faili asemel 0 baidine fail ning lokaalses masinas polnud ka enam faili sisu saadaval, kuna editor oli kokku jooksnud.

Sarnane probleem tekkis tihti ka mahu ületamise tõttu. Veebihostingu paketid olid suhteliselt väikesed ja ikka juhtus, et klient oli laadinud sinna mingeid hiigelsuuri pilte ja pdf faile jne. nii et kettamaht oli täis saanud ja isegi üle läinud, sest FTP lubab viimase faili kettale kirjutada, isegi kui sellega läheb quota lõhki. Kui nüüd üritada nüüd sellises keskkonnas mingit faili muuta, siis faili avamine õnnestub (ehk siis lühendamine 0 baidiseks), aga sinna faili midagi kirjutada enam ei õnnestu, kuna quota on juba varasemalt lõhki. Kui selleks muudetavaks failiks juhtus olema index.php või siis rakenduse konfiguratsioonifail, siis oli tulemus teada – veebileht oli jälle "maas".

Tänapäeval on asjad tunduvalt muutunud, ainult poolearuline kasutab rakenduse üleslaadimiseks serverisse FTP'd ja seda kasvõi juba turvalisuse tõttu (ka FTPS ei pruugi olla turvaline, kuna vaikimisi on krüpteeeritud ainult command channel ehk see, kustkaudu liiguvad paroolid, aga mitte data channel, kustkaudu liiguvad failid). Võimalusi on nüüd igasuguseid, tutvustaksin lähemalt poor-man herokut ehk git'i kaudu deploy'mist.

Eeldused:
  • Meie rakendus (selles näites tavaline PHP baasil toimiv veebileht) kasutab versioonihalduseks git'i
  • Olemas on ssh ligipääs serverisse (sama kasutajana, kelle õigustes peavad olema rakenduse failid)

Samm 1. Seadista remote repository

Loo serveris repo kaust (sõltuvalt asukohast võib olla vajalik teha seda root kasutaja õigustes), suvaline asukoht kõlbab, aga näites teeme selle asukohta /var/opt

cd /var/opt
mkdir webapp.git
cd webapp.git
git init --bare

Selle tagajärjena on meil olemas täiesti tühi git repo asukohas /var/opt/webapp.git.

Samm 2. Update hook

Selle jaoks, et taolisesse tühja reposse millegi saatmine ka midagi reaalselt muudaks, seadistame update sündmuse tegevuse, milleks on bash skript asukohas hooks/update.

cd /var/opt/webapp.git/hooks
nano update

Avanenud tekstitoimetisse võib kopeerida järgmise failisisu (eeldusel, et /var/www/webapp/htdocs on kaust, kus hakkavad asuma rakenduse failid)

#!/bin/bash
GIT_WORK_TREE=/var/www/webapp/htdocs git checkout "$3" -f

Järgmiseks tuleks anda sellele failile käivitusõigused

chmod +x update

Nüüd tuleks jälgida, et rakenduse failide kaust eksisteerib ja et kõik failiõigused on paigas

mkdir -p /var/www/webapp/htdocs
chown www-data:www-data /var/www/webapp
chown -R www-data:www-data /var/www/webapp/
chown www-data:www-data /var/opt/webapp.git
chown -R www-data:www-data /var/opt/webapp.git/

Ja sellega ongi server seadistatud.

Samm 3. Lokaalne seadistus

Kohalikus git koodirepos, kus asuvad siis rakenduse failid, tuleks lisada uus git remote asukoht, tavaliselt on selle nimeks origin, kuid deploy jaoks kasutame hoopis nimetust production.

git remote add production www-data@example.com:/var/opt/webapp.git

www-data on siis see kasutaja kelle õiguses serveris toimetame ning example.com on ssh serveri hostname.

NB! Tavaline "origin" remote asukoht jääb endiselt alles kuna git hajuslahendus, nii jääb origin suunama koodihoidlasse ja production veebiserverisse. Lisaks võib teha veel staging vmt.

Samm 4. Deploy!

Nüüd ongi kõik seadistused tehtud ja edasi ei ole muud, kui muudatusi deploy'ma hakata. Iga kord kui oled uuendanud koodi ja selle ära commit'inud, võid jooksutada käsu

git push production master

kus master on siis aktiivne branch. Git laeb muudatused remote reposse, seal käivitub update hook, mis omakorda (eeldusel et commit õnnestub), kopeerib kõik vajalikud failid veebifailide kausta.

Profit!


Kommentaare ei ole: