GitLab Continuous Delivery Pipeline & Deployment Webserver
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.
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
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/mysecrethost.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