Auto-Deployment mit Gitlab-Ci Pipelines

Automatisches Deployment mit Gitlab-Ci Pipelines

Deployment made easy! Wer Websites entwickelt, aktualisiert und anschließend live schalten muss, kommt man einer Deploymentstrategie nicht vorbei. Dabei muss man entscheiden, wie das ganze effektiv von dem Datenträger, der Festplatte oder dem GIT-Repository auf das Staging- und den Liveserver hochgeladen werden kann. Am besten so, dass möglichst keine oder nur minimale Downtimes entstehen.

Nun hier gibt es ganz unterschiedliche Ansätze. Viele Entwickler schwören auf die unterschiedlichsten Tools wie Deployer, Jenkins oder manche auch mit der Konsole und Rsync oder oldschool via FTP-Upload. Egal für was man sich entscheidet, am Ende muss es für jeden persönlich und zum Projekt passen. Ich habe auch meinen Weg gefunden, Projekte und Websites wie diese hier mit Gitlab-Ci zu deployen. Wie das ganze geht, möchte ich euch hier etwas näher Vorstellen. Natürlich ist Gitlab-CI extrem umfangreich. Daher möchte ich nur darauf hinweisen, dass ich hier ausschließlich meine Meinung darlege und der Guide auch keineswegs Anspruch auf Vollständigkeit erhebt. Gitlab entwickelt sich rasant weiter. Da kann man nicht zangsläufig alles sofort überblicken :).

Darum geht’s bei GITLAB-CI

Deployments

Kurz und einfach gesagt, hat man die Möglichkeit, vollautomatisiert bestimmte Aktionen nach einem Commit ins GIT-Repo durchführen zu lassen. Dabei kann man unterscheiden, wann was gemacht werden soll. Zum Beispiel nur deployen, wenn ein Versions-TAG gepusht wurde, oder nur wenn etwas in einen bestimmten Branch gepusht wurde oder ähnliches. Das ist hilfreich, wenn man nur möchte, dass ausschließlich fertige Releases mit Versionsnummern auf Server-XY deployed werden (wie das geht, zeige ich euch weiter unten).

Tests

Es ist super einfach, mit wenigen mitteln Buidltest durchführen zu lassen. Das ist super Hilfreich für APP Entwickler, die ihre JS App testen lassen wollen. Aber auch PHP Unittests oder einfache Node-NPM checks - das geht alles mit einwenig Konfiguration der .gitlab-ci.yml Datei (später dazu mehr).


Beispiel einer Git-Pipeline für git pull Deployments

Legt euch eine gitlab-ci.yml im root eures Git-Repos und probiert mit diesem Beispiel die Funktionsweisen. In diesem Beispiel wird ein deployment Abgebildet, dass sich per SSH auf den Live- und Testserver verbinden kann und dort ein einfaches git pull im jeweilgen Branch ausführt.

stages:
  - deploy

deploy_production:
  stage: deploy
  image: tetraweb/php:7.1
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - mkdir -p ~/.ssh
    - eval $(ssh-agent -s)
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
    - ssh-add <(echo "$PRODUCTION_PRIVATE_KEY")
  script:
    - ssh -t $PRODUCTION_USER@$PRODUCTION_HOST -p$PRODUCTION_PORT "cd $PRODUCTION_PATH && git pull origin master -f"
  only:
    - master

deploy_staging:
  stage: deploy
  when: manual
  image: tetraweb/php:7.1
  cache:
    paths:
    - node_modules/
    - vendor/
  before_script:
  - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
  - mkdir -p ~/.ssh
  - eval $(ssh-agent -s)
  - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  - ssh-add <(echo "$STAGING_PRIVATE_KEY")
  - npm install
  - npm outdated
  script:
  - ssh -t $STAGING_USER@$STAGING_HOST -p$STAGING_PORT "cd $STAGING_PATH && git fetch origin"
  - ssh -t $STAGING_USER@$STAGING_HOST -p$STAGING_PORT "cd $STAGING_PATH && git checkout $CI_COMMIT_REF_NAME"
  - ssh -t $STAGING_USER@$STAGING_HOST -p$STAGING_PORT "cd $STAGING_PATH && git pull origin $CI_COMMIT_REF_NAME -f"
  only:
  - branches
  except:
  - master
NameErklärung
deploy_productionUmgebungsvariable für den Liveserver
deploy_stagingUmgebungsvariable für den Liveserver
stageGibt an, was konkret passieren soll. Default ist test
imageDefiniert das Docker image, das geladen werden soll (Hier im Einsatz mein Standard Image von Tetraweb mit PHP7.1 Support, Node8x, Composer,etc.)
cacheGibt die Möglichkeit, dass bereits auf die Daten in vorherigen Deployments zurückgegriffen werden kann. Das macht sich gerade bei composer Vendor-Ordnern oder Node_Modules super
before_scriptHier kannst du alles Angeben, was passieren soll, bevor deployed wird. Zeilen 1-5 hierbei sind allerdings notwendig vom Image, damit es korrekt SSH einrichten kann für das künftige deployment
scripthierunter kommen alle Befehle die auf dem Remote-Server (Live- und Testsystem) ausgeführt werden sollen. Beachte, dass man sich dabei immernoch auf dem Image aufhält und man sich daher mit SSH auf dem Zielserver einwählt (siehe im Beispiel oben)
onlyDer Befehl only reglementiert die Ausführung. hier kann man zum Beispiel hinterlegen, dass nur bei tags deployed werden darf oder nur z.B. der Branch Master. Mehr dazu findest du hier.
exceptverbietet die Ausführung, wenn das Ergebnis wahr ist. Im Beispiel oben ist except auf Master gestellt. Heißt also, auf Staging wird alles gepushed, nur nich der master. Klar - hier wollen wir auch nur den develop oder etwaige Feature- und Releasebranches testen.
$STAGING_USER, $STAGING_HOST, $STAGING_PRIVATE_KEY, …Diese Variablen sind Platzhalter. Sie werden in den Einstellungen des Git-Repository unter Settings > CI / CD > Variables hinterlegt.

Variablen in Gitlab und Job-Liste

Wenn ihr eure Variablen unter Settings > CI / CD > Variables gepflegt habt und sie genauso heißen wie in der .gitlab-ci.yml ist auch schon die Einrichtung fast fertig. Ihr müsst nur noch den ssh-key des Zielserver im Repo unter Settings > Repository > Deploy Keys hinterlegen. Fertig.

Bei nächsten Commit wird dann die Pipeline getriggert und euer Commit entsprechend automatisch ausgerollt.
Die Jobliste und den Status des Deployments findet ihr dann wieder Links im Menü unter CI / CD > Jobs.

Viel Erfolg und viel Spaß!
Wenn Ihr Fragen oder Anregungen habt, lasst es mich wissen :).