GitLab CD beállítása avagy autodeploy ingyér'
Az előző két részben beállítottunk egy VPS staging szerver-t, valamint kialakítottunk egy aldomaineket automatikusan konfiguráló, jelszóval ellátó reverse proxy-t a Traefik személyében. Most pedig ássuk bele magunkat kicsit a GitLab CD-be. Finom lesz, jujuj! :)
De miééért?
Ábel kérdésére válaszolva: mert lusták vagyunk (igen, a jó fejlesztő lusta, de attól tartok, ez fordítva nem igaz). Ha valami frissült, és szeretnénk, ha látná az ügyfél, akkor több lehetőségünk is van: felmásolhatjuk FTP-re (ne), Github/GitLab helyett pusholhatjuk a szerveren egy bare repóba alternatív remote-ként (ez nem rossz, egy ideig használtam is), de:
- FTP: még mindig ne,
- Bare repo: ha már egyébként is commitolunk és pusholunk szépen, miért pusholjunk duplán?
GitLab CI/CD
Azon kívül, hogy a GitLab ingyenes csomagjában korlátlan mennyiségű privát repositorynk lehet, elérhetőek a GitLab CI/CD eszközei is, ezek közül pedig most a GitLab Runnereket - és ehhez kapcsolódóan a Variables menüpontot - fogjuk jobban szemügyre venni.
Az alábbiakban egy Craft CMS-sel készülő projekt példáján keresztül fogjuk átnézni a folyamatot. Kezdjünk is neki!
.gitlab-ci.yml
Amennyiben a projekt gyökerében létezik .gitlab-ci.yml
, úgy a GitLab a push után rögtön elindítja egy osztott Runneren az abban foglaltak végrehajtását, aminek a folyamatát mi a CI/CD > Jobs menüpont alatt tudunk nyomonkövetni.
A kódot igyekeztem agyonkommentelni, a változók mennyisége már kicsit az olvashatóság rovására ment, de cserébe könnyen hordozható lett. Mentsük le a projekt gyökerébe, .gitlab-ci.yml
néven.
Látszik, hogy lefuttat bizonyos fájlokat, ezért azokat létre kell hoznunk.
.docker/generate_env.sh
Ennek a fájlnak a feladata a .env fájl generálása. Mivel a Docker és a Craft CMS egyaránt támogatja a .env fájl használatát, ezért adja magát, hogy ezt kihasználjuk: a docker-compose.yml
fájlba nem drótozzuk be a projektspecifikus értékeket, helyette olyanra alakítottam át, ami minden projektben felhasználható.
docker-compose.yml
Ez az alapértelmezett docker-compose.yml fájlunk helyi fejlesztéshez - ezt használja a docker-compose up
, viszont ugyanazon a hoston nem lehet ugyanarra a portra kötni két külön container-t, amivel viszont ütközne az eredeti célunk. Ezért van egy külön docker-compose-ci.yml fájlunk is, amit csak a GitLab Runner használ a staging szerverünkre deployolásnál.
docker-compose-ci.yml
Nem különbözik sokban az alap fájltól: ports
helyett expose
van a 80-as portra, ami már nem ütközik, viszont arra pont elég, hogy a Traefik ráirányítsa a forgalmat. Megemlítendő érdekesség a volumes
-on belüli ./.docker/dump:/docker-entrypoint-initdb.d
: ezzel a docker-compose.yml
-lal azonos mappából kiindulva a .docker/dump/
mappában lévő összes .sql
fájlt átadjuk a docker-entrypoint-initdb.d
scriptnek, ami azokat a container database_volume
-jának létrehozásakor automatikusan importálja. Vagyis ha ide bedobunk mondjuk egy db.sql fájlt, és azt mindig, amikor DB-t szeretnénk frissíteni, egy újabb dump-pal felülírjuk, akkor a GitLab Runner-en keresztüli CD-vel egyben DB-t is tudunk deployolni.
Mindkettő .yml
fájlhoz szükségünk van a .docker/Dockerfile_webserver
fájlra, ennek a tartalma:
Semmi extra: 7.2-apache
image-t vesszük alapul, telepítjük a Craft CMS működéséhez szükséges cuccokat, illetve létrehozunk egy user-t 1000-es ID-val a containeren belül. Ennek köszönhetően nem lesznek jogosultsági problémáink a containeren kívül akkor, ha törölni szeretnénk a létrehozott fájlokat (a GitLab Runner nem interaktív shell-t futtat, ezért sudo-zni nem tudunk, a root login meg ugye le van tiltva). Az ADD
-hoz kapcsolódó fájl tartalma:
Kódok szintjén ezekre van szükségünk, innentől már csak konfigurálunk. :)
Változók beállítása
Ahhoz, hogy a Runner rendben tudjon deployolni, a változóknak értéket kell adnunk. Navigáljunk el a projekt Settings > CI / CD menüpontjához, és nyissuk ki a Variables szekciót:
Folytatva a korábban megkezdett gondolatsort a változók az alábbiak szerint alakulnak:
- BUILD_PATH: /builds/{{ organization }}, https://gitlab.com/gitlab-org/... esetén
gitlab-org
lenne - ENVIRONMENT: staging
- REPOSITORY_NAME: a repository neve, https://gitlab.com/gitlab-org/... esetén
gitlab-ce
lenne - SERVER_IP: 188.166.22.129
- SERVER_PORT: 62222
- SERVER_PROJECTS_ROOT: /home/wbmngr/sites/
- SERVER_SSH_KEY: ide egy SSH kulcs private része kell. Érdemes lehet létrehozni egyet külön a GitLab-nak, és felpusholni a staging szerverre a
wbmngr
user nevében, ahogyan itt írtam, és a Variables részre ehhez a változóhoz a private részt copypasta megoldással feldobni (cat ~/.ssh/gitlab_ssh_key
kiírja a kulcs privát felének tartalmát) - SERVER_USERNAME:
wbmngr
(létrehozhatnánk külön user-t a GitLab-nak, de az megbonyolítaná a jogosultságok kérdését)
Ezzel a résszel végeztünk is.
Szerver felkészítése
Lépj be a staging szerverre SSH-n keresztül, hogy elő tudjuk készíteni a terepet az érkező csomagoknak.
Először is hozd létre azt az útvonalat, amit megadtál a SERVER_PROJECTS_ROOT-nál, illetve állíts be rá megfelelő jogosultságokat.
Mivel minden deploynál törölni szeretnénk a korábbi fájlokat, ezért fontos, hogy a tulajdonosok mi legyünk, és csak a fájlok/mappák csoportja egyezzen meg a webszerver csoportjával.
A .gitlab-ci.yml
-ben van egy unzip lépés a szerveren - viszont az unzip program alapból nincs telepítve a VPS-en, így arra még szükségünk lesz:
Elméletileg el is készültünk - nincs más dolgod, mint commitolni egyet, majd pusholni a GitLab-ra.
Összefoglalás
Most, hogy megy a build a GitLabon, miközben izgulunk, hogy sikeres lesz-e, nézzük át nagy vonalakban a folyamatot: offline fejlesztesz, elkészülsz valamilyen funkcióval, ezután commitolsz és pusholsz. A push végeztével a GitLab elindítja a Runner-t, az összecsomagolja a kész csomagot egy .zip-be, majd felmásolja a szerverre a $SERVER_PROJECTS_ROOT
-ba. Ezután újra belép a szerveren a $SERVER_PROJECTS_ROOT
mappába, törli a $REPOSITORY_NAME
mappát, kicsomagolja a bundle-t, majd törli, és lelövi az esetleg még futó Docker containereket, törölve a hozzájuk tartozó volume-okat is. Ezután elindítja a docker-compose-ci.yml
fájl alapján a containereket, majd újraindítja a Traefik-et - semmi extra. :)
Köszi a figyelmet, készen is vagyunk - remélem, hogy Neked simábban ment a folyamat, mint nekem! :)
Ha valami nem egyértelmű, kérdésed van, vagy hibát találtál, dobj egy üzenetet!