Docker-Anwendung mit docker-compose und GitLab-CI automatisch bauen
Ich bin gerade dabei, probeweise meine HotS-Team-Webseite mit Docker zu bauen. Immer, wenn Blizzard einen neuen Helden ins Spiel bringt, muss ich ein paar (viele) Handgriffe machen und diese erst lokal ausprobieren und schließlich auf meinem Produktivserver erneut ausführen. Als Informatiker bin ich faul und möchte diesen Vorgang automatiseren. Hier kommt Docker ins Spiel…
In diesem Artikel zeige ich euch, wie ihr mit Docker und GitLab eine Anwendung bauen könnt.
Installation eines Runners
Als ersten Schritt richte ich einen neuen Server mit Ubuntu 18.04 ein. Ich installiere dort einen GitLab-Runner und verwende den Shell-Executor.
In diesem Artikel könnt ihr Details finden, wie man einen GitLab-Runner installiert.
Warum den Shell-Executor? Im obig erwähnten Artikel steht drin, dass der Shell-Executor viele Nachteile hat und der Docker-Executor doch besser wäre. Das ist erstmal richtig. Gucken wir uns aber einmal an, was wir mit diesem Runner machen möchten:
Ziel ist es, die Befehle docker-compose
bzw. docker
zu verwenden. Das klappt mit dem
Docker-Executor nicht. Man kann einen Docker-Daemon nicht so einfach in Docker laufen lassen.
Ihr werdet im Internet Anleitungen finden, wie es mit dem --privileged
-Flag klappt,
aber das möchte ich nicht. (Es erlaubt dem Container auszubrechen!)
Mit dem Shell-Executor haben wir dieses Problem nicht.
Ich registriere meinen neuen GitLab-Runner am GitLab und weise ihm zwei Tags zu: shell
(um zu markieren, dass dies ein Shell-Executor ist) und docker-daemon
(um zu markieren, dass hier ein Docker-Daemon läuft). Damit kann ich später in meinen Projekten
für die jeweiligen Jobs speziell diesen Runner auswählen.
Installation von Docker und docker-compose
Als root
installiere ich eine aktuelle Version von docker-compose
gemäß der Anleitung auf
docs.docker.com:
curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Docker selber installiere ich aus den Ubuntu-Paketquellen:
apt install docker.io
Zum Schluss kurz prüfen, ob Docker läuft:
root@shell-gitlab-runner:~# docker version
Client:
Version: 18.09.7
API version: 1.39
Go version: go1.10.1
Git commit: 2d0083d
Built: Fri Aug 16 14:20:06 2019
OS/Arch: linux/amd64
Experimental: false
Server:
Engine:
Version: 18.09.7
API version: 1.39 (minimum version 1.12)
Go version: go1.10.1
Git commit: 2d0083d
Built: Wed Aug 14 19:41:23 2019
OS/Arch: linux/amd64
Experimental: false
Build mit GitLab-CI durchführen
In meinem Projekt habe ich eine docker-compose.yml
angelegt, auf die ich jetzt nicht weiter
eingehe. Mit dem docker-compose
-Tool und dieser Datei kann ich meine Anwendung mit Docker
verwenden.
Ich lege nun eine Datei .gitlab-ci.yml
im Stammverzeichnis meines Projekts mit folgendem
Inhalt an:
stages:
- build
build:
stage: build
tags:
- shell
- docker-daemon
script:
- docker-compose build
Die Anweisungen in dieser Datei sind relativ einfach:
- Der Bereich
stages
definiert nur eine Stage mit dem Namenbuild
. - Es wird ein einziger Job mit dem Namen
build
definiert, der innerhalb der Stagebuild
abläuft. - Wir fordern vom GitLab, dass es einen Runner zuteilt, der die Tags
shell
unddocker-daemon
besitzt. Damit selektieren wir unseren eben installierten Runner. - Im Bereich
script
wird eine einzige Befehlszeile angegeben, die der Runner ausführen soll:docker-compose build
. Dies baut mir meine Anwendung in Form von Docker-Images.
Beim nächsten Push wird GitLab die .gitlab-ci.yml
erkennen und im Bereich "CI / CD" unter
"Pipelines" eine Pipeline anlegen und ausführen.
Versuch 1: Couldn't connect to Docker daemon at http+docker://localhost - is it running?
Ich gucke in mein GitLab… der Job läuft… und scheitert aber :(
$ docker-compose build
Couldn't connect to Docker daemon at http+docker://localhost - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
ERROR: Job failed: exit status 1
Wir bekommen keine Verbindung zum Daemon. Doch vorhin hab ich extra kontrolliert, dass Docker läuft!? Es kann sich also nur um ein Permission-Problem handeln.
Problem untersuchen und lösen
Um das Problem zu lösen, logge ich mich auf dem Runner per SSH ein. Wichtig ist nun, die Schritte genau so durchzuführen, wie es auch der GitLab-Runner selber tun würde. Aus dem Log des Jobs erfahre ich das Arbeitsverzeichnis, in dem Job ausgeführt wurde. In das wechsle ich hinein und sehe mich um:
cd /home/gitlab-runner/builds/GR1f_yAH/0/thehacker/hots-team.com
ll
Ich sehe, dass alle Dateien dem Nutzer gitlab-runner
gehören. Also wechsle ich in diesen Nutzer,
um dieselben Rechte wie der Runner zu haben und probiere die nötigen Befehle aus:
root@shell-gitlab-runner:/home/gitlab-runner/builds/GR1f_yAH/0/thehacker/hots-team.com# su gitlab-runner
gitlab-runner@shell-gitlab-runner:~/builds/GR1f_yAH/0/thehacker/hots-team.com$ docker-compose build
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
gitlab-runner@shell-gitlab-runner:~/builds/GR1f_yAH/0/thehacker/hots-team.com$ docker version
Client:
Version: 18.09.7
API version: 1.39
Go version: go1.10.1
Git commit: 2d0083d
Built: Fri Aug 16 14:20:06 2019
OS/Arch: linux/amd64
Experimental: false
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/version: dial unix /var/run/docker.sock: connect: permission denied
Man erkennt, dass der gitlab-runner
nicht die nötigen Rechte hat.
Wir lösen das Problem, indem wir dem gitlab-runner
-Nutzer der Gruppe docker
zuweisen:
gitlab-runner@shell-gitlab-runner:~/builds/GR1f_yAH/0/thehacker/hots-team.com$ exit
root@shell-gitlab-runner:/home/gitlab-runner/builds/GR1f_yAH/0/thehacker/hots-team.com# usermod -aG docker gitlab-runner
root@shell-gitlab-runner:/home/gitlab-runner/builds/GR1f_yAH/0/thehacker/hots-team.com# su gitlab-runner
gitlab-runner@shell-gitlab-runner:~/builds/GR1f_yAH/0/thehacker/hots-team.com$ docker version
Client:
Version: 18.09.7
API version: 1.39
Go version: go1.10.1
Git commit: 2d0083d
Built: Fri Aug 16 14:20:06 2019
OS/Arch: linux/amd64
Experimental: false
Server:
Engine:
Version: 18.09.7
API version: 1.39 (minimum version 1.12)
Go version: go1.10.1
Git commit: 2d0083d
Built: Wed Aug 14 19:41:23 2019
OS/Arch: linux/amd64
Experimental: false
Wir erhalten nun eine Antwort vom Docker-Daemon :-)
Versuch 2: Job succeeded
Da wir keine Änderungen am Quellcode selber gemacht haben, können wir im GitLab bei dem fehlgeschlagenem Job einfach auf den "Wiederholen"-Button klicken, um den Job erneut laufen zu lassen.
Diesmal klappt alles.
Fazit
Ich habe damit auf dem GitLab-Runner meine Docker-Images für meine Anwendung gebaut, die ich jetzt auf einen beliebigen Server pushen und dort ausführen lassen kann.
Dies wird Gegenstand eines weiteren Artikel sein.
Kommentare zu diesem Artikel
Schreib einen Kommentar zum Artikel
Vielen Dank für deinen Kommentar! :-)
Da alle Kommentare von Hand bearbeitet werden,
gedulde dich bitte, bis der Kommentar freigeschaltet wird.
Formular nicht richtig ausgefüllt.
Oops... da ist was schiefgelaufen :-(
Dein Kommentar konnte nicht gespeichert werden.
Bitte probier es später nochmal.