GitLab Continuous Delivery Pipeline & Deployment Webserver

Posted on by Julian Stock.

Aktuell entwickle ich für einen Kunden ein Portal, mit welchem neben Mitarbeiter, Wohnungen und dazugehörige Mieten auch Tickets verwaltet werden können. Diese Tickets kann man auch als Störungsmeldung oder als einfaches "Anliegen" sehen - eine genaue Spezifikation liegt nicht vor. Primär soll dieses System allerdings eingesetzt werden, um Problemmeldungen aufzunehmen und später bearbeiten zu können.

GitLab Continuous Delivery Pipeline

Damit sichergestellt ist, dass das System ohne Unterbrechung läuft und sich durch menschliche Unachtsamkeit beim Veröffentlichen eines Updates (beispielsweise durch händisches Übertragen des neuen Quellcodes über ein FTP-Programm wie z. B. FileZilla) Fehler einschleichen, ist es erforderlich, eine automatisierte Lösung für diesen Vorgang einzurichten. In den letzten Tagen habe ich dann ein paar Dinge mit den GitLab Pipelines ausprobiert und bin zu einer zufriedenstellenden Lösung gekommen.

Die Voraussetzungen:

  • ein GitLab Account mit einem Repository
  • ein über SSH erreichbarer Webserver
  • ein bereits eingerichtetes (und mindestens einmalig gepulltes) Repository auf dem Webserver

Zuerst muss ein Private/Public-Key auf dem Webserver eingerichtet werden (ihr könnt diesen Schritt überspringen, falls ihr bereits ein Schlüsselpaar in der Vergangenheit angelegt habt):

ssh-keygen -t rsa -b 4096 -C "mein webservername"

Dem Wizard folgt ihr, das Passwort lasst ihr leer.

Nach dem erfolgreichen Anlegen des Schlüssels öffnet ihr den Public-Key

cat ~/.ssh/id_rsa.pub

und kopiert den Inhalt in die Zwischenablage. Dieser öffentliche Schlüssel muss jetzt in euren GitLab Einstellungen hinterlegt werden, damit sich euer Webserver später ohne Authentifizierung die neuen Sourcen aus eurem Git-Repository ziehen kann.

Öffnet https://gitlab.com/profile/keys und gebt in dem Formular eure Key-Daten ein. Der Name des Schlüssels sollte automatisch ausgefüllt werden, ihr könnt ihn aber auch frei überschreiben.

Anschließend fügt ihr in eurem develop/master Branch die Datei .gitlab-ci.yml mit folgendem Inhalt hinzu:

before_script:
  - apt-get update -yqq
  - apt-get install -yqq git
  - 'which ssh-agent || ( apt-get install -qq openssh-client )'
  - mkdir -p ~/.ssh
  - eval $(ssh-agent -s)
  - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
stages:
  - deploy
deploy:staging:
  stage: deploy
  environment:
    name: staging
    url: $QA_DOMAIN
  script:
    - echo "Deploy to staging (QA) server"
    - ssh-add <(echo "$QA_SSH_PRIVATE_KEY")
    - ssh $QA_SERVER_USER@$QA_SERVER_HOST "cd $QA_WEB_ROOT && git reset --hard && git checkout develop && git pull origin develop && exit"
  only:
    - develop
deploy:prod:
  stage: deploy
  environment:
    name: production
    url: $PROD_DOMAIN
  script:
    - echo "Deploy to production server"
    - ssh-add <(echo "$PROD_SSH_PRIVATE_KEY")
    - ssh $PROD_SERVER_USER@$PROD_SERVER_HOST "cd $PROD_WEB_ROOT && git reset --hard && git checkout master && git pull origin master && exit"
  only:
    - master

Link zu gist.github.com

GitLab Continuous Delivery Pipeline Variablen

Dort seht ihr auch die folgenden Variablen (jeweils für ein QA und ein PROD System):

  • $QA_DOMAIN
  • $QA_SSH_PRIVATE_KEY
  • $QA_SERVER_USER
  • $QA_SERVER_HOST
  • $QA_WEB_ROOT
  • $PROD_DOMAIN
  • $PROD_SSH_PRIVATE_KEY
  • $PROD_SERVER_USER
  • $PROD_SERVER_HOST
  • $PROD_WEB_ROOT

Diese Werte können wir jetzt befüllen lassen. Öffnet dazu die Projekteinstellungen (Settings -> CI / CD) und erweitert dort den Bereich "Variables".

Unter der Annahme, dass ihr einen Webserver habt, den ihr mit

ssh myuser@mysecrethost.tld

erreichen könnt und die spätere (PROD-) Website unter

cd /var/www/mysecrethost.tld/htdocs/web/

liegt, wären die Variablen wie folgt zu füllen (achtet darauf, die Werte entsprechend anzupassen, falls ihr abweichende QA/PROD-Server nutzt):

  • $PROD_DOMAIN = http://www.mysecrethost.tld
  • $PROD_SERVER_USER = myuser
  • $PROD_SERVER_HOST = mysecrethost.tld
  • $PROD_WEB_ROOT = /var/www/mysecret­host.tld/htdocs/web/

Den Wert für den Private-Key $PROD_SSH_PRIVATE_KEY entnehmt ihr der

cat ~/.ssh/id_rsa

auf eurem Webserver.

Ich hatte am Anfang arge Bedenken, dass das Teilen eines privaten Schlüssels nicht so der Hit ist, allerdings scheint es keine andere Möglichkeit zu geben - bei mir hat es letztendlich nur damit funktioniert.

Wichtig ist allerdings noch, dass wir den Key auf unserem Webserver "erlauben". Das geschieht, indem ihr in die Datei

nano ~/.ssh/authorized_keys

den Public-Key, den wir vorhin kopiert haben, auch hier einfügt.

Wenn ihr jetzt alles gepushed habt, sollte eure Pipeline bereits loslegen und unter dem angegebenen Pfad die neuen Sourcen sichtbar sein 😊

Falls doch etwas nicht wie erwartet funktioniert oder ihr Fragen/Anmerkungen habt, meldet euch bitte gerne in den Kommentaren.

Bis in Bälde,
Julian


Julian Stock
Webentwickler aus Lübeck · 35 Jahre

Social