GitLab CI/CD: automatizace testů a nasazení aplikace

6. června 2024

Lang: cs en de es

Dlouho dobu mě lidé žádali, abych připravil návod jak používat CI/CD na GitLabu. Připravil jsem tedy základní ukázkový projekt a zde je návod GitLab a jeho CI/CD.

Návod jak zprovoznit CI/CD v GitLabu

Tento návod obsahuje seznam kroků, které musíte splnit, aby jste zprovoznili automatický vývoj a deploy softwarového projektu. Tato ukázka je zaměřená na GitLab, ale obdobně to můžete realizovat na jiných řešeních jako je například GitHub action.

Co je potřeba mít, zajistit a nastavit:

  • Používat GitLab.
  • Mít runnnery.
  • Nastaven proces vývoje, tak že se používají kontejnery. Například Docker.
  • Rozdělit aplikace tak, aby každá služba běžela v samostatném kontejneru.
  • Mít testy. Následně si nastavíme automatické spouštění.
  • Mít VPS pro provoz aplikace.
  • Nastavit nginx na VPS. Vytvořit uživatele a nastavit ssh přistup na server.
  • Navrhnout proces buildu image pro produkci a nastavit automatizaci buildu image na gitlabu.
  • Nastavit práva pro deploy.
  • Provést build a push image do registry.
  • Spustit deploy na gitlabu - akce se spustí při merge do větve master/main.

Termíny

Aby člověk mohl něco používat je potřeba si rozumět. Proto u každé nové technologie je potřeba si vysvětlit termíny.

Co je to runner?

Runner je instance programu GitLab Runner, který umožňuje spouštět různé typy úloh, jako je sestavování, testování a nasazování projektu. GitLab Runner je součástí GitLabu a umožňuje automatizovat běžné operace související s vývojem softwaru.

Pokud používáte gitlab.com by default máte runnery k dispozici. Pokud GitLab provozujete na vlastní infrastruktuře, tak budete muset zajistit i Gitlab runnery vlastními silami. Tedy zajistit servery, nainstalovat runner a nakonfigurovat propojení s GitLabem.

Podrobnosti jak nainstalovat GitLab runner.

Runner pak spouští kontejnery, dle zvoleného image a v něm se vykoná konkretní job - úloha, kterou chcete vykonat.

Pipeline, Job

Pipeline je sada kroků, které jsou vykonávány za účelem dosažení určitého cíle, například nasazení aplikace do produkce. Pipeline obvykle obsahuje několik fází (stages), které zahrnují různé kroky, jako je sestavení, testování a nasazení. Každá fáze může obsahovat jeden nebo více jobů. Pipeliny mohou být spuštěny automaticky při každé změně v kódu nebo na základě určitého plánu.

Job je konkrétní úloha, která se provádí v rámci pipeline. Každý job je jednotka práce, která může být nezávisle spuštěna a sledována. Joby mohou být rozděleny do různých fází pipeline. Každý job může obsahovat skripty nebo příkazy, které je potřeba provést, například spuštění testů, sestavení kódu nebo nasazení aplikace.

Pipeline se skládá z jednoho nebo více stage. Stage se může skládat z jednoho nebo více jobů.
Stage se spouští za sebou. Více jobů v jedné stage se spouští paralelně.

Co jsou to docker container registry?

Docker Container Registry (také známý jako Docker Registry) je služba pro ukládání a správu Docker obrazů. Jedná se o centrální úložiště, kde můžete ukládat vaše vlastní Docker obrazy a sdílet je s ostatními lidmi ve vaší organizaci nebo veřejně na Internetu.

GitLab obsahuje Container registry. Když provádíte build na GitLabu je nejednoduší řešení použít právě GitLab jako úložiště pro vaše docker obrazy.

Také můžete použít DockerHub. Sepsal jsem i článek Jak nahrát docker image do Docker Registry na Docker Hub.

Jak řešit deploy aplikace?

Deploy aplikace můžete realizovat typicky dvěma způsoby:

  • Pomoci kontejneru a provést build, push a pull obrazu s novou verzí aplikace.
  • Klasicky spustit nějaký deploy skript, který provede git pull a další úkony.

Provoz bez kontejnerů

Deploy aplikace budete řešit podle toho jak máte nastavené prostředí pro provoz aplikace.
Pro provoz aplikace vůbec není třeba mít aplikaci v hontejnerech. Je i možné provozovat více PHP aplikací na jednom serveru, včetně různých verzí PHP a mít jednotlivé aplikace od sebe oddělené a tím pádem zajištěnou základní bezpečnost. Samozřejmě je potřeba umět takový linuxový webový server nainstalovat .
Pro deploy pak můžete použít například nástroj Deployer. Nebo si napíšete nějaký vlastní skript.

Provoz aplikace v dockeru

Pokud bude provozovat aplikaci v kontejneru, tak deploy se skládá jen z toho stáhnout a nový obraz a pustit z něj kontejner. Typicky je potřeba pustiti i nějaké migrační skripty. Nezapomeňte mít data na volume, aby vaše data byla perzistencí.

Jednoduchý příklad GitLab CI

Příklad jednoduchého .gitlab-ci.yml souboru, kterým ověříte, že CI na Gitlabu funguje, může vypadat takto:

stages:
  - build
  - test
  - deploy

build_project:
  stage: build
  script:
    - echo "Building the project..."

run_tests:
  stage: test
  script:
    - echo "Running tests..."

deploy_to_production:
  stage: deploy
  script:
    - echo "Deploying to production..."
  environment:
    name: production
    url: https://your-production-url.com
Soubor commitněte do projektu a následně by se měla pustit pipelajna.

GitLab CI a proměnné

Pro fungování budete potřebovat předávat jobům v pipelajně proměnné. V GitLab CI/CD je možné předávat proměnné několika různými způsoby.

Nezapomeňte dbát na bezpečnost citlivých informací a proměnných. V případě citlivých údajů, je dobré využít funkcí GitLabu pro ochranu těchto dat. Například umožnit jejich použijí jen v privilegovaných situacích.

Definování proměnných v nastavení repositáře

Pro bezpečné uložení proměnných prostředí (ENV) a přístupových klíčů v GitLabu existují tzv. "variables" a "CI/CD environment variables", které lze nastavit v samotném rozhraní GitLabu a nejsou součástí zdrojového kódu vaší aplikace. To pomáhá chránit citlivé informace a umožňuje jejich použití v rámci CI/CD pipeline.
V samotném rozhraní GitLabu (v nastavení repozitáře) můžete definovat proměnné prostředí, které budou přístupné ve vašem .gitlab-ci.yml. Toto nastavení může být obecné pro celý projekt nebo může být specifické pro každou branch, tag.
Pro přidání proměnných do repozitáře v GitLabu jděte do nastavení projektu -> "Settings" -> "CI/CD" -> "Variables". Zde můžete definovat proměnné různých typů (například proměnné prostředí, proměnné typu soubor a další).
Tyto proměnné lze použít v rámci vaší CI/CD pipeline pomocí klasické bash syntaxe např. $VARIABLE_NAME.

Takto si například můžete předat ssh klíč, aby jste se následně mohli připojit pomocí ssh na server až budete provádět deploy aplikace.

Definování proměnných přímo v .gitlab-ci.yml

Můžete předávat proměnné přímo v konfiguračním souboru .gitlab-ci.yml.

yaml

stages:
  - build

variables:
  MY_VARIABLE: "value"

build_project:
  stage: build
  script:
    - echo $MY_VARIABLE
V tomto případě je proměnná MY_VARIABLE definována přímo v souboru .gitlab-ci.yml a je použita v jobu build_project.

Předávání proměnných pomocí skriptů

Pokud potřebujete dynamicky měnit hodnotu proměnných v závislosti na podmínkách, můžete je předat prostřednictvím skriptů v CI/CD pipeline

yaml

stages:
  - build

build_project:
  stage: build
  script:
    - export MY_VARIABLE="value"
    - echo $MY_VARIABLE
Tento příklad ukazuje použití exportu v rámci skriptu pro nastavení proměnné MY_VARIABLE.

Volba jiného image v GitLab CI

Může definovat globálně který docker image se má používat. Ale v různých jobech budete dělat různé ukony a tak se vám budou hodit používat různé image.
Například pokud potřebuje ssh klienta, aby jste se pomocí ssh připojili na server, budete potřebovat image kde je ssh klient. Pro build docker image budete potřebovat image, kde jsou utility pro build docker image.

Definice, že se ma použít image docker:19.03.13.


build_image:
  before_script:
    - ''
  only:
    - main
  stage: build
  image: docker:19.03.13
  services:

Zároveň je tu definováno, že tento job se bude spouštět jen při commitu do větve main.

Připojení pomocí ssh

Při deploy aplikace se pravděpodobně bude potřebovat připojit na server a to ideálně pomocí ssh. Jak na to? V první řadě je potřeba si říct, že nejlepší možnost je použít SSH klíče. Přidejte obsah vašeho SSH privátního klíče jako tajnou proměnnou do GitLabu. Tím se zabezpečíte, že klíč nebude veřejně viditelný.

Aby jsme měli k dispozici aplikaci pro přihlášení na ssh, tak použijeme image kroniak/ssh-client, který obsahuje ssh klienta. Následně si připravíme prostředí tak, aby byla konfigurace pro ssh tak jak potřebujeme včetně ssh klíče. Díky tomu se můžete bezpečně a pohodlně připojit na server. A pak už stačí jenom spouštět příkazy na serveru...

Konfigurace připojení pomocí SSH klíče v .gitlab-ci.yml:


deploy:
  before_script:
    - ''
  services: []
  stage: deploy
  image: kroniak/ssh-client
  only:
    - main
  script:
    - mkdir ~/.ssh/
    - echo "$SSH_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
    - chmod 600 ~/.ssh/id_rsa
    - export SSH_AUTH_SOCK && export SSH_ASKPASS=ssh-askpass && eval `ssh-agent -s` && ssh-add ~/.ssh/id_rsa
    - "scp docker-compose.prod.yml user@test3.xeres.cz:app"


V tomto případě se na server přes ssh nakopíruje soubor docker-compose.prod.yml .

Mějte na paměti, že ukládání privátního klíče do CI/CD pipeline může být rizikové a mělo by být používáno opatrně. Doporučuje se používat speciální klíče s omezenými oprávněními a vytvořit uživatelský účet s omezenými právy. Takový účet bude sloužit pouze pro účely CI/CD.

Nasazení Docker kontejneru

Kroky pro nasazení Docker kontejneru prostřednictvím GitLab CI/CD na server jsou:
  1. Vytvoření Docker obrazu: Zkontrolujte, zda máte soubor Dockerfile, který popisuje vaši aplikaci a její prostředí. Vytvořte Docker obraz pomocí příkazu docker build. Například: docker build -t your-image-name:tag .
  2. Push obrazu do registru: Pokud používáte externí Docker registry (například Docker Hub), přihlaste se pomocí příkazu docker login.
  3. Na serveru stažení nové verze image, vypnutí starého kontejneru a puštění kontejneru z nového image.

Následující příklad ukazuje kroky buildu, přihlášení do registry a pushnutí image.

build_image:
  before_script:
    - ''
  only:
    - main
  stage: build
  image: docker:19.03.13
  services:
    - docker:19.03.13-dind
  script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
    - docker build ./ -t  registry.gitlab.com/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:app
    - docker push registry.gitlab.com/josef.jebavy/example-symfony-devstack-cicd:app

	

Po přidání a pushnutí změn aplikace do repozitáře se spustí CI/CD pipeline a automaticky provede build docker image s novou verzí aplikace a provede push do registry.
Tento job pouřívá pro build image docker:19.03.13, který obsahuje nástroje pro build docker obrazů.

Následující příklad ukazuje kroky přihlášení na server pomocí ssh, nakopírovaní nové konfigurace docker-compose.prod.yml, stažení nového image s novou aplikací. Vypnutí starého kontejneru, start kontejneru z nového image a puštění migračních skriptů.

deploy:
  before_script:
    - ''
  services: []
  stage: deploy
  image: kroniak/ssh-client
  only:
    - main
  script:
    - mkdir ~/.ssh/
    - echo "$SSH_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
    - chmod 600 ~/.ssh/id_rsa
    - export SSH_AUTH_SOCK && export SSH_ASKPASS=ssh-askpass && eval `ssh-agent -s` && ssh-add ~/.ssh/id_rsa
    - "scp docker-compose.prod.yml user@test3.xeres.cz:app"
    - ssh user@test3.xeres.cz "docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com && docker pull registry.gitlab.com/josef.jebavy/example-symfony-devstack-cicd:app"
    - ssh user@test3.xeres.cz "cd app && docker compose -f docker-compose.prod.yml stop web  && docker compose -f docker-compose.prod.yml rm web -f && docker compose -f docker-compose.prod.yml up -d "
    - ssh user@test3.xeres.cz "cd app && docker exec -d test-app-web bin/console doctrine:database:create --if-not-exists && docker exec -d test-app-web php bin/console doctrine:migrations:migrate --no-interaction"

Příklad GitLab CI

Kompletní ukázku konfigurace GitLab CI, kde se provádí automatické testy, build aplikace a deploy na produkci najdete zde https://gitlab.com/josef.jebavy/example-symfony-devstack-cicd/. Ukázka obsahuje i konfiguraci serveru, kterou můžete provést automaticky pomocí nástroje Ansible. Pokud uděláte fork mého projektu, můžete si to vyzkoušet i sami a provést deploy na váš server.

Video návod

Zde je krok za krokem podrobný vzorový video návod na zprovoznění GitLab CI:

Provoz projektu v docker kontejneru

Jak na provoz projektu v docker kontejnerech:

Automatické testy

GitLab CI/CD a automatické testy:

Pipeline

Gitlab CI/CD a nastavení pipeline v souboru gitlab-ci.yml:

Deploy aplikace na server

Nastavení GitLab CI/CD pro deploy aplikace na server:

Konfigurace serveru

GitLab CI/CD konfigurace serveru pro provoz aplikace v kontejneru a nastavení pro automatická deploy pomocí GitLab CI:

Automatizace

Automatizace za vám udělá spoustu práce a tím ušetří váš drahocenný čas. Také omezíte výskyt lidských chyb. Minimálně doporučuji mít testy a ty automaticky spouštět při commitu do git repozitáře. S každou úpravou zdrojového kódu tak budete mít jistotu otestování aplikace.

Odkazy

Články na podobné téma

VMware vs Proxmox: porovnání výkonu
Migrace VPS z VMware na Proxmox
Změna licencování VMware
Provoz Microsoft SQL serveru na Linuxu
Zálohování: Proxmox backup server
Linux jako router a firewall
Jak náhrát docker image do Docker Registry
Linux: Logical Volume Management
Linuxový softwarový RAID
Provoz webové aplikace za proxy
Migrace mail schránek
Docker multistage build
Zálohování dat zapnutím počítače
Podman
Import Windows do virtualizace Proxmox
Docker a PHP mail
Virtualizace Proxmox
Docker a Cron
Lenovo ThinkPad X1 Carbon: zprovoznění LTE modemu EM7544
Yocto Project: Build vlastního operačního sytému pro embedded zařízení
Příprava linuxového serveru pro běh webové aplikace v jazyce Python
Jak řešit špatný výkon sdílených souborů u Dockeru
Jak začít správně používat Docker
Instalace Linuxu na dedikovaný server HPE ProLiant DL320e
Jak provést zátěžový test webové aplikace
Proč používat filesystém JFS
Jak bootovat z 4TB disku s GTP pomocí UEFI
Jak nainstalovat operační systém Mageia Linux bez DVD mechaniky
Souborový systém Btrfs
Raspberry PI
Jak zprovoznit vzdálené přehrávání přes síť na televizi s DLNA
Upgrade Mandriva Linuxu za běhu
Poznámky ke GNU/Linux
WINE - spouštíme programy pro Windous pod Linuxem
Operační systém GNU/Linux

Odběr novinek

Pokud máte zájem dostávat příležitostně na email novinky.
Můžete se vyplněním emailu registrovat k odběru novinek.


+