GitLab CI/CD: Testautomatisierung und Anwendungsbereitstellung

6. Juni 2024

Lang: cs en de es

Seit langem haben mich Leute gebeten, ein Tutorial über die Verwendung von CI/CD auf GitLab zu erstellen. Also habe ich ein einfaches Beispielprojekt zusammengestellt und hier ist ein Tutorial über GitLab und sein CI/CD.

Wie man CI/CD in GitLab zum Laufen bringt

Dieses Tutorial listet die Schritte auf, die Sie durchführen müssen, um die automatische Entwicklung und Bereitstellung Ihres Softwareprojekts zum Laufen zu bringen. Diese Demo konzentriert sich auf GitLab, aber Sie können eine ähnliche Implementierung auch mit anderen Lösungen wie GitHub action durchführen.

Was man haben, bereitstellen und einrichten muss:

  • GitLab verwenden.
  • Haben Sie Runners.
  • Richten Sie einen Entwicklungsprozess ein, bei dem Container verwendet werden. Zum Beispiel, Docker.
  • Trennen Sie Anwendungen so auf, dass jeder Dienst in einem eigenen Container läuft.
  • Haben Sie Tests. Dann richten Sie einen automatischen Start ein.
  • Haben Sie einen VPS, auf dem die Anwendung läuft.
  • Nginx auf dem VPS einrichten. Erstellen Sie einen Benutzer und richten Sie einen ssh-Zugang zum Server ein.
  • Entwerfen Sie einen Image-Build-Prozess für die Produktion und richten Sie die Image-Build-Automatisierung auf Gitlab ein.
  • Berechtigungen für die Bereitstellung festlegen.
  • Ausführen des Builds und Übertragen des Images in die Registry.
  • Bereitstellung auf gitlab ausführen - Aktion wird beim Zusammenführen mit dem Master/Hauptzweig ausgeführt.

Termine

Um etwas zu benutzen, muss man es verstehen. Deshalb muss man bei jeder neuen Technologie die Begriffe erklären.

Was ist ein Läufer?

Ein Runner ist eine Instanz von GitLab Runner, mit der Sie verschiedene Arten von Aufgaben wie das Erstellen, Testen und Bereitstellen eines Projekts ausführen können. GitLab Runner ist Teil von GitLab und ermöglicht es Ihnen, gängige Softwareentwicklungsvorgänge zu automatisieren.

Wenn Sie gitlab.com verwenden, stehen Ihnen standardmäßig Runner zur Verfügung. Wenn Sie GitLab auf Ihrer eigenen Infrastruktur betreiben, müssen Sie die Gitlab-Runner selbst bereitstellen. Das heißt, Sie müssen die Server bereitstellen, den Runner installieren und die Verbindung zu GitLab konfigurieren.

Details . Anleitung zur Installation des GitLab-Runners.

Der Runner startet dann Container, je nach dem von Ihnen gewählten Image, und führt den spezifischen Job aus - den Job, den Sie ausführen möchten.

Pipeline, Job

Eine Pipeline ist eine Reihe von Schritten, die ausgeführt werden, um ein bestimmtes Ziel zu erreichen, z. B. das Deployment einer Anwendung in die Produktion. Eine Pipeline enthält in der Regel mehrere Phasen (Stages), die verschiedene Schritte wie Build, Test und Deployment beinhalten. Jede Phase kann einen oder mehrere Aufträge enthalten. Pipelines können automatisch ausgelöst werden, wenn es eine Änderung im Code gibt oder nach einem bestimmten Zeitplan.

Ein Job ist eine bestimmte Aufgabe, die innerhalb einer Pipeline ausgeführt wird. Jeder Job ist eine Arbeitseinheit, die unabhängig ausgeführt und überwacht werden kann. Jobs können in verschiedene Phasen der Pipeline unterteilt werden. Jeder Job kann Skripte oder Befehle enthalten, die ausgeführt werden müssen, z. B. die Ausführung von Tests, die Erstellung von Code oder die Bereitstellung einer Anwendung.

Eine Pipeline besteht aus einer oder mehreren Phasen. Eine Stage kann aus einem oder mehreren Jobs bestehen.
Eine Stage wird der Reihe nach ausgeführt. Mehrere Jobs in einer Stage werden parallel ausgeführt.

Was sind Docker Container Registries?

Docker Container Registry (auch bekannt als Docker Registry) ist ein Dienst zur Speicherung und Verwaltung von Docker-Images. Es handelt sich um ein zentrales Repository, in dem Sie Ihre eigenen Docker-Images speichern und mit anderen Personen in Ihrem Unternehmen oder öffentlich im Internet teilen können.

GitLab enthält Container-Registries. Wenn Sie einen Build auf GitLab durchführen, ist es keine einfache Lösung, GitLab als Repository für Ihre Docker-Images zu verwenden.

Sie können auch DockerHub verwenden. Ich habe auch einen Artikel geschrieben Wie man ein Docker-Image in die Docker Registry auf Docker Hub hochlädt.

Wie stellt man eine Anwendung bereit?

Es gibt in der Regel zwei Möglichkeiten, eine Anwendung bereitzustellen:

  • Den Container starten und ein build, push und pull des Panels mit der neuen Version der Anwendung durchführen.
  • Klassischerweise ein Deployment-Skript ausführen, das einen git pull und andere Aktionen durchführt.

Betrieb ohne Container

Stellen Sie Ihre Anwendung bereit, je nachdem, wie Sie Ihre Umgebung für den Betrieb der Anwendung eingerichtet haben.
Sie müssen die Anwendung nicht in Containern betreiben, um sie überhaupt laufen zu lassen. Es ist sogar möglich, mehrere PHP-Anwendungen auf einem einzigen Server laufen zu lassen, einschließlich verschiedener PHP-Versionen, auf einem einzigen Server laufen zu lassen und die Anwendungen voneinander getrennt zu halten, um eine grundlegende Sicherheit zu gewährleisten. Natürlich muss man wissen, wie man Linux Webserver zu installieren.
Für das Deployment können Sie dann z.B. das Tool Deployer verwenden. Oder Sie schreiben ein eigenes Skript.

Anwendungsbereitstellung in Docker

Wenn Sie die Anwendung in einem Container laufen lassen, besteht das Deployment nur aus dem Herunterladen eines neuen Images und dem Entladen des Containers daraus. Normalerweise müssen auch einige Migrationsskripte ausgeführt werden. Denken Sie daran, Ihre Daten auf Volume zu speichern, damit Ihre Daten beständig sind.

Einfaches GitLab CI Beispiel

Ein Beispiel für eine einfache .gitlab-ci.yml Datei, um zu überprüfen, dass CI auf Gitlab funktioniert, könnte so aussehen:

stages:
  - Build
  - testen
  - einsetzen

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

run_tests:
  Stufe: test
  Skript:
    - echo "Running tests..."

deploy_to_production:
  Stufe: deploy
  Skript:
    - echo "Bereitstellung in der Produktion..."
  Umgebung:
    name: produktion
    url: https://your-production-url.com
Übertragen Sie die Datei in das Projekt, dann sollte die Pipeline ausgeführt werden.

GitLab CI und Variablen

Um zu funktionieren, müssen Sie Variablen an die Jobs in der Pipeline übergeben. In GitLab CI/CD können Sie Variablen auf verschiedene Weise übergeben.

Denken Sie an die Sicherheit von sensiblen Daten und Variablen. Bei sensiblen Daten empfiehlt es sich, die Funktionen von GitLab zum Schutz dieser Daten zu nutzen. Erlauben Sie zum Beispiel, dass sie nur in privilegierten Situationen verwendet werden dürfen.

Definieren von Variablen in den Repository-Einstellungen

Um Umgebungsvariablen (ENVs) und Zugriffsschlüssel sicher in GitLab zu speichern, gibt es "Variablen" und "CI/CD-Umgebungsvariablen", die in der GitLab-Oberfläche selbst festgelegt werden können und nicht Teil des Quellcodes Ihrer Anwendung sind. Dies trägt zum Schutz sensibler Informationen bei und ermöglicht ihre Verwendung innerhalb der CI/CD-Pipeline.
In der GitLab-Oberfläche selbst (in den Repository-Einstellungen) können Sie Umgebungsvariablen definieren, die in Ihrer .gitlab-ci.yml zugänglich sind. Diese Einstellungen können allgemein für das gesamte Projekt oder spezifisch für jeden Zweig oder Tag sein.
Um Variablen zu Ihrem GitLab-Repository hinzuzufügen, gehen Sie zu Projekteinstellungen -> "Einstellungen" -> "CI/CD" -> "Variablen". Hier können Sie Variablen verschiedener Typen definieren (z. B. Umgebungsvariablen, Dateitypvariablen und mehr).
Diese Variablen können innerhalb der CI/CD-Pipeline mit der klassischen bash-Syntax verwendet werden, z.B. $VARIABLE_NAME.

Zum Beispiel kann man auf diese Weise einen ssh-Schlüssel übergeben, um sich dann beim Deployment der Anwendung per ssh mit dem Server zu verbinden.

Definieren von Variablen direkt in .gitlab-ci.yml

Sie können Variablen direkt in der Konfigurationsdatei .gitlab-ci.yml übergeben.

yaml

Stufen:
  - Build

Variablen:
  MY_VARIABLE: "Wert"

build_project:
  stage: build
  Skript:
    - echo $MY_VARIABLE
In diesem Fall ist die Variable MY_VARIABLE direkt in der Datei .gitlab-ci.yml definiert und wird im Job build_project verwendet.

Variablenübergabe über Skripte

Wenn Sie den Wert von Variablen in Abhängigkeit von Bedingungen dynamisch ändern müssen, können Sie sie über Skripte in der CI/CD-Pipeline übergeben

.
yaml

Stages:
  - Build

build_project:
  Stufe: build
  Skript:
    - export MY_VARIABLE="Wert"
    - echo $MY_VARIABLE
Dieses Beispiel zeigt die Verwendung von export innerhalb eines Skripts, um die Variable MY_VARIABLE zu setzen.

Wählen eines anderen Bildes in GitLab CI

Sie können global festlegen, welches Docker-Image verwendet werden soll. Aber in verschiedenen Jobs werden Sie verschiedene Exits durchführen, also werden Sie verschiedene Images verwenden wollen.
Wenn Sie zum Beispiel einen ssh-Client benötigen, um sich mit einem Server über ssh zu verbinden, benötigen Sie ein Image, in dem sich der ssh-Client befindet. Für ein Build-Docker-Image benötigen Sie ein Image, in dem sich die Dienstprogramme für das Build-Docker-Image befinden.

Die Definition, dass das Image docker:19.03.13 verwendet werden soll.


build_image:
  '''before_script:
    - ''
  only:
    - main
  Stadium: build
  Bild: docker:19.03.13
  Dienste:

Außerdem wird festgelegt, dass dieser Job nur beim commit to main ausgeführt wird.

Verbindung über ssh herstellen

Wenn die Anwendung eingesetzt wird, muss sie sich wahrscheinlich mit dem Server verbinden, idealerweise über ssh. Wie ist das zu bewerkstelligen? Zunächst einmal ist die Verwendung von SSH-Schlüsseln die beste Option. Fügen Sie den Inhalt Ihres privaten SSH-Schlüssels als geheime Variable zu GitLab hinzu. Dadurch wird sichergestellt, dass der Schlüssel nicht öffentlich sichtbar ist.

Um eine Anwendung zu haben, die sich bei ssh anmeldet, verwenden wir das Image kroniak/ssh-client, das den ssh-Client enthält. Anschließend bereiten wir die Umgebung so vor, dass die Konfiguration für ssh so ist, wie wir sie brauchen, einschließlich des ssh-Schlüssels. So können Sie sich sicher und bequem mit dem Server verbinden. Und dann müssen Sie nur noch die Befehle auf dem Server ausführen...

Konfigurieren Sie die Verbindung mithilfe des SSH-Schlüssels in .gitlab-ci.yml:


deploy:
  before_script:
    - ''
  services: []
  stage: deploy
  bild: kroniak/ssh-client
  nur:
    - main
  skript:
    - 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"


In diesem Fall wird die docker-compose.prod.yml Datei via ssh auf den Server kopiert.

Denken Sie daran, dass die Speicherung eines privaten Schlüssels in der CI/CD-Pipeline riskant sein kann und mit Vorsicht verwendet werden sollte. Es wird empfohlen, spezielle Schlüssel mit eingeschränkten Rechten zu verwenden und ein Benutzerkonto mit eingeschränkten Rechten zu erstellen. Ein solches Konto wird nur für CI/CD-Zwecke verwendet.

Einrichten eines Docker-Containers

Die Schritte zum Bereitstellen eines Docker-Containers über GitLab CI/CD auf einem Server sind:
  1. Erstellen eines Docker-Images: Stellen Sie sicher, dass Sie ein Dockerfile haben, das Ihre Anwendung und deren Umgebung beschreibt. Erstellen Sie ein Docker-Image mit dem Befehl docker build. Zum Beispiel: docker build -t your-image-name:tag.
  2. Pushen Sie das Image in die Registry: Wenn Sie externe Docker-Registries verwenden (zum Beispiel Docker Hub), melden Sie sich mit dem Befehl docker login an.
  3. Laden Sie auf dem Server eine neue Version des Images herunter, fahren Sie den alten Container herunter und starten Sie den Container aus dem neuen Image.

Das folgende Beispiel zeigt die Schritte des Erstellens, des Einloggens in die Registry und des Pushens des Images.

build_image:
  '''before_script:
    - ''
  only:
    - main
  Stadium: build
  Bild: docker:19.03.13
  Dienste:
    - docker:19.03.13-dind
  skript:
    - 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

	

Nach dem Hinzufügen und Pushen der Anwendungsänderungen in das Repository wird die CI/CD-Pipeline ausgeführt und automatisch ein Docker-Image mit der neuen Anwendungsversion erstellt und an die Registry gepusht.
Dieser Job verwendet docker:19.03.13 für das Build-Image, das Tools zum Erstellen von Docker-Images enthält.

Das folgende Beispiel zeigt die Schritte des Einloggens in den Server mittels ssh, Kopieren der neuen Konfiguration docker-compose.prod.yml, Herunterladen des neuen Images mit der neuen Anwendung. Herunterfahren des alten Containers, Starten des Containers mit dem neuen Image und Ausführen der Migrationsskripte.

Bereitstellen:
  before_script:
    - ''
  services: []
  stage: deploy
  bild: kroniak/ssh-client
  nur:
    - main
  skript:
    - 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"

GitLab CI Beispiel

Ein vollständiges Beispiel für eine GitLab CI-Konfiguration, bei der automatisierte Tests, das Erstellen der Anwendung und die Bereitstellung für die Produktion durchgeführt werden, finden Sie hier https://gitlab.com/josef.jebavy/example-symfony-devstack-cicd/. Die Demo beinhaltet auch die Serverkonfiguration, die Sie mit Ansible automatisch durchführen können. Wenn Sie einen Fork von meinem Projekt machen, können Sie es auch selbst ausprobieren und auf Ihren Server deployen.

Video-Tutorial

Hier ist ein detailliertes Video-Tutorial, das Schritt für Schritt zeigt, wie man GitLab CI zum Laufen bringt:

Betrieb eines Projekts in einem Docker-Container

Wie man ein Projekt in einem Docker-Container ausführt:

Automatische Tests

GitLab CI/CD und automatisierte Tests:

Pipeline

Gitlab CI/CD und Pipeline-Einstellungen in gitlab-ci.yml:

Anwendung auf dem Server bereitstellen

GitLab CI/CD-Einstellungen zur Bereitstellung der Anwendung auf dem Server:

Server-Konfiguration

GitLab CI/CD-Serverkonfiguration, um die Anwendung in einem Container auszuführen und für die automatische Bereitstellung mit GitLab CI einzurichten:

Automatisierung

Die Automatisierung nimmt Ihnen einen Großteil der Arbeit ab und spart Ihnen wertvolle Zeit. Sie werden auch menschliche Fehler reduzieren. Als Minimum empfehle ich, Tests zu haben und diese automatisch auszuführen, wenn Sie in ein Git-Repository übertragen. Auf diese Weise können Sie sicher sein, dass Sie Ihre Anwendung bei jeder Quellcodeänderung testen.

Links

Artikel zu einem ähnlichen Thema

VMware vs. Proxmox: Leistungsvergleich
VPS von VMware zu Proxmox migrieren
VMware-Lizenzierungsänderung
Ausführen von Microsoft SQL Server unter Linux
Sicherung: der Proxmox Backup Server
Linux als Router und Firewall
Hochladen eines Docker-Images in die Docker-Registry
Linux: Verwaltung logischer Datenträger
Linux-Software-RAID
Ausführen einer Webanwendung hinter einem Proxy
Migration von Postfächern
Mehrstufige Docker-Erstellung
Sichern Ihrer Daten durch Einschalten des Computers
Podman
Importieren von Windows in die Proxmox-Virtualisierung
Docker und PHP-Mail
Proxmox-Virtualisierung
Docker und Cron
Lenovo ThinkPad X1 Carbon: Inbetriebnahme des LTE-Modems EM7544
Yocto-Projekt: Erstellen eines eigenen Betriebssystems für eingebettete Geräte
Vorbereiten eines Linux-Servers für die Ausführung einer Webanwendung in Python
Wie man eine schlechte Dateifreigabeleistung in Docker behebt
Wie man Docker richtig einsetzt
Installation von Linux auf einem dedizierten HPE ProLiant DL320e Server
Wie man eine Webanwendung einem Belastungstest unterzieht
Warum das JFS-Dateisystem verwenden
Booten von einer 4TB-Festplatte mit GTP unter UEFI
Btrfs-Dateisystem
Raspberry PI
WINE - Ausführen von Windous Programmen unter Linux
GNU/Linux-Betriebssystem

Newsletter

Wenn Sie daran interessiert sind, gelegentlich Neuigkeiten per E-Mail zu erhalten.
Sie können sich registrieren, indem Sie Ihre E-Mail-Adresse eingeben News-Abonnement.


+