Jenkins ist ein Open Source Server zur Automatisierung gewisser Tätigkeiten. Das können zum Beispiel Installationen von Infrastrukturkomponenten oder automatisierte Build and Deployment Tasks sein. Auch Docker Images lassen sich damit bauen. Damit der Jenkins Server die erforderlichen Projekte erfolgreich ausführen kann, bedarf es einiger Konfigurationsschritte. Dazu gehören neben den benötigten Plugins auch Zugangsdaten für Projekte sowie grundsätzliche Konfigurationen des Jenkins Servers. Das Jenkins Projekt bietet hierfür auch fertige Docker Images an, um den Einstieg zu vereinfachen. Ich greife hierzu immer zur LTS Version „jenkins/jenkins:lts“. Hierbei handelt es sich um ein völlig blankes Image ohne jegliche Konfiguration. Es verhält sich nach dem Start also wie eine lokale Jenkins Installation, die zum ersten Mal aufgerufen wird. Um sich die wiederkehrende Arbeit der Grundkonfiguration zu ersparen, können gewisse Konfigurationen bereits beim Erzeugen des Containers mit übergeben werden. Wird der Container mehrfach benötigt, spart das eine ganze Menge Zeit.
Die Konfiguration kann mit Hilfe einer YAML Datei übergeben werden. Um zu sehen, wie die Datei aufgebaut werden muss, kann das Jenkins Plugin „Configuration as a Code“ installiert werden.

Alle Anpassungen werden hier direkt in einer YAML Datei hinterlegt, die später verwendet werden kann.

Wenn die Konfigurationsdatei den eigenen Anforderungen entspricht, kann diese als „casc.yml“ abgespeichert werden.
Neben der Konfiguration können auch direkt alle benötigten Plugins mit installiert werden, sobald der Container gestartet wird. Diese werden in der Datei „plugins.txt“ abgelegt. Wichtig ist, dass auf jeden Fall das Plugin “configuration-as-code:latest” mit angegeben wird, damit die Konfigurationsdatei auch eingelesen werden kann.

Dem Docker Container können auch Umgebungsvariablen für Jenkins mitgegeben werden. Diese werden in der Datei “jenkins-variable.env” abgelegt.
JAVA_OPTS=-Djenkins.install.runSetupWizard=false JENKINS_HOST=jenkins.foo.bar JENKINS_URL=http://${JENKINS_HOST}:8080 JENKINS_ADMIN=jenkins JENKINS_PASS=foobar SLAVE_AGENT_PORT=50000 CASC_JENKINS_CONFIG=/var/jenkins_home/casc.yml
Besonders wichtig sind die erste und die letzte Variable. Hierbei wird der Jenkins Setup Wizard deaktiviert, da ja bereits eine fertige Konfiguration mitgeben wird. “CASC_JENKINS_CONFIG” gibt an, wo die Konfigurationsdatei innerhalb des Containers zu finden ist. Die anderen Variablen können nach Belieben angepasst werden.
Für den Docker Container wird noch eine Docker Compose Datei angelegt. Diese erzeugt und startet den Container.
version: '3.9' services: jenkins: build: . env_file: jenkins-variables.env ports: - 8000:8080 - 50000:50000 container_name: jenkins_server_lts volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - data-volume:/var/jenkins_home restart: always volumes: data-volume:
Der Parameter “build: .” gibt an, dass wir zusätzlich ein Dockerfile mit angeben. Dies ist in diesem Fall erforderlich, damit auch die Konfiguration beim Erzeugen des Containers mit angewendet und die Plugins installiert werden. Die beiden Ports sind für die Weboberfläche und den Jenkins Agent. Damit ist der Container über diese beiden Ports von außen erreichbar. Falls der Jenkins Server selbst auf Docker zugreifen können soll, wird das Volume “docker.sock” im Read Only Modus mit eingehängt. Das Volume “data-volume” speichert die persistenten Daten des Containers, damit diese auch nach einem Neustart vorhanden sind.
Kommen wir nun zum Dockerfile. Dies wird ohne Erweiterung als “Dockerfile” erzeugt und bekommt folgenden Inhalt.
FROM jenkins/jenkins:lts COPY plugins.txt /usr/share/jenkins/ref/plugins.txt RUN jenkins-plugin-cli -f /usr/share/jenkins/ref/plugins.txt COPY casc.yml /var/jenkins_home/casc.yml
Damit wird später der Container mit dem aktuellen Jenkins LTS Image gebaut, die Plugins werden installiert und die Konfiguration wird angewendet. Über das Dockerfile können auch komplette vorgefertigte Projekte in den Container kopiert werden, damit diese später nicht manuell angelegt werden müssen.
Die Dateistruktur sollte nun wie folgt aussehen.

Der Container kann jetzt über Docker Compose erzeugt und gestartet werden.
docker-compose up -d --build
Nach ein paar Sekunden lässt sich die Jenkins Oberfläche im Browser aufrufen.

In der Standardkonfiguration wird die Oberfläche per http und dem definierten Port “8000” aufgerufen. Hier lässt sich auch noch per Docker ein Reverse Proxy wie Traefik vorschalten, um eine saubere https Konfiguration zu ermöglichen. Somit wird die Kommunikation verschlüsselt und der Jenkins http Port muss nicht nach außen freigegeben werden.
Das fertige Jenkins Docker Projekt kann zusätzlich noch zum Beispiel in ein Github Repository eingecheckt werden. Wenn es dann zum Einsatz kommt, muss es nur noch aus Git ausgecheckt werden, um es sofort starten zu können. Zusätzlich ist es noch eine gute Backup Strategie.