2018. 07. 28.
frissítve: 2022. 05. 15.
Olvasási idő: 20 perc

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:

Gitlab cd autodeploy 2

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!