Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Cloud / Hosting 03.08.2026 · 10 min Lesezeit

Jenkins mit Docker installieren: Der bewährteste Open-Source-CI/CD-Server

Jenkins ist mit über 1.800 Plugins der universellste CI/CD-Server. Diese Anleitung zeigt, wie du ihn per Docker Compose in etwa 20 Minuten betriebsbereit bekommst – mit compose.yaml, .env, initialem Setup-Wizard und Verifikation nach jedem Schritt.

Illustration zur Installation von Jenkins mit Docker. Das Bild zeigt einen CI/CD Server mit Build Pipeline, Docker Containern, Server Infrastruktur und einem modernen Dashboard für Continuous Integration und Continuous Deployment in einer Linux Umgebung. KI-generiert

Jenkins ist seit Jahren der meistgenutzte Open-Source-Automationsserver im CI/CD-Bereich. Mit über 1.800 verfügbaren Plugins lässt er sich an nahezu jeden Build-, Test- und Deploy-Workflow anpassen – ob einfache Freestyle-Jobs, deklarative Pipelines (Jenkinsfile), Multi-Branch-Pipelines oder verteilte Build-Agenten. Wer als Team maximale Flexibilität und vollständige Kontrolle über seine Automatisierungspipelines braucht, findet in Jenkins ein bewährtes Fundament. Das offizielle Docker-Image jenkins/jenkins:lts-jdk21 läuft plattformneutral auf Linux (amd64 und arm64) und ist für den Betrieb via Docker Compose optimiert – kein separater Datenbankserver notwendig.

Voraussetzungen

  1. Docker Engine ≥ 20.10 und das Docker Compose Plugin v2 (docker compose ohne Bindestrich) müssen auf dem Host installiert sein. Eine vollständige Installationsanleitung findest du unter Docker und Docker Compose auf Linux installieren.
  2. Ein Linux-Host, eine VM oder ein NAS mit Docker-Unterstützung – die Anleitung funktioniert auf Ubuntu, Debian und jedem anderen System mit Docker Engine (auch ARM64, z. B. Raspberry Pi 4/5 oder Apple Silicon).
  3. Mindestens 1 GB RAM, empfohlen 2–4 GB für produktive Builds; mindestens 5 GB freier Speicherplatz (Workspaces und Build-Artefakte wachsen über die Zeit).
  4. Internetzugang für den initialen Plugin-Download (ca. 200–500 MB je nach Auswahl im Setup-Wizard).
  5. Für HTTPS-Zugang von außen empfiehlt sich ein Reverse Proxy; eine bewährte Lösung zeigt die Anleitung Traefik als Docker-Reverse-Proxy mit automatischem HTTPS.

Schritt 1: Projektordner anlegen

Lege einen dedizierten Ordner für den Jenkins-Stack an. Ein Unterverzeichnis unter /opt/ ist für systemweite Dienste üblich; im Home-Verzeichnis geht es genauso.

mkdir -p /opt/jenkins
cd /opt/jenkins

Der Ordner enthält ausschließlich compose.yaml und .env. Das Jenkins-Datenverzeichnis (jenkins_home) verwaltet Docker als Named Volume – kein Bind-Mount-Berechtigungsproblem.

Verifizieren: ls /opt/jenkins – der Ordner existiert (zunächst leer, was korrekt ist).

Schritt 2: .env-Datei anlegen

Die .env-Datei enthält alle Konfigurationsparameter, die du ohne Änderung an der compose.yaml anpassen kannst. Da Jenkins keine Datenbankpasswörter oder Secret-Keys in Umgebungsvariablen benötigt, ist die Datei bewusst schlank.

# Jenkins – Konfiguration
# Port, auf dem Jenkins im Browser erreichbar ist
JENKINS_HTTP_PORT=8080

# Port fuer eingehende Build-Agenten (JNLP) – nur benoetigt wenn externe Nodes verbunden werden
JENKINS_AGENT_PORT=50000

# Java VM Optionen: Zeitzone und Heap-Groesse (anpassen bei wenig RAM: -Xmx1g -Xms256m)
JAVA_OPTS=-Duser.timezone=Europe/Berlin -Xmx2g -Xms512m

# Jenkins-Startargumente (leer lassen fuer Standard; Beispiel fuer Reverse-Proxy: --prefix=/jenkins)
JENKINS_OPTS=

Verifizieren: cat /opt/jenkins/.env – alle vier Variablen sind sichtbar, keine Syntaxfehler (kein Leerzeichen um das =-Zeichen).

Schritt 3: compose.yaml erstellen

Die folgende compose.yaml verwendet das offizielle LTS-Image mit JDK 21, ein Named Volume für Datenpersistenz und einen Healthcheck, der Jenkins' verzögerten Start berücksichtigt.

services:
  jenkins:
    image: jenkins/jenkins:lts-jdk21
    container_name: jenkins
    restart: on-failure
    ports:
      - "${JENKINS_HTTP_PORT:-8080}:8080"
      - "${JENKINS_AGENT_PORT:-50000}:50000"
    volumes:
      - jenkins_home:/var/jenkins_home
    environment:
      - JAVA_OPTS=${JAVA_OPTS:--Duser.timezone=Europe/Berlin -Xmx2g -Xms512m}
      - JENKINS_OPTS=${JENKINS_OPTS:-}
      - JENKINS_SLAVE_AGENT_PORT=50000
    healthcheck:
      test: ["CMD-SHELL", "curl -sf http://localhost:8080/login || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 120s

volumes:
  jenkins_home:
    driver: local

Wichtige Details zur Konfiguration im Überblick:

ParameterWertHinweis
Imagejenkins/jenkins:lts-jdk21LTS + OpenJDK 21 – empfohlenes Produktions-Tag; Alternative: lts-jdk17
Port 8080Web-UI (Pflicht)Haupt-Zugriff für Browser und REST-API
Port 50000Agenten-Port (optional)Nur benötigt wenn externe Build-Nodes per JNLP angebunden werden
Volume jenkins_home/var/jenkins_homeSpeichert Konfiguration, Plugins, Workspaces und Build-Logs dauerhaft
UID/GID1000/1000Named Volume: Docker setzt Berechtigungen automatisch; Bind Mount: chown 1000:1000 vorab
DatenbankkeineJenkins ist dateibasiert – kein PostgreSQL/MySQL erforderlich

Verifizieren: cat /opt/jenkins/compose.yaml – YAML ohne Einrückungsfehler, Image-Name korrekt (jenkins/jenkins:lts-jdk21, nicht das veraltete jenkins-Image ohne Namespace).

Schritt 4: Jenkins starten

Starte Jenkins im Hintergrund. Der erste Start dauert 2–3 Minuten, da das Image geladen und Jenkins initialisiert wird.

cd /opt/jenkins
docker compose up -d

Verfolge die Logs während des Starts:

docker compose logs -f jenkins

Jenkins ist startbereit, wenn du in den Logs folgende Zeile siehst:

Jenkins is fully up and running

Verifizieren: docker compose ps – der Container jenkins zeigt Up (nach ca. 2 Minuten auch healthy). Außerdem:

curl -sf http://localhost:8080/login && echo "OK" || echo "Noch nicht bereit"

Erwartete Ausgabe nach vollständigem Start: OK. Solange Jenkins noch hochfährt, gibt curl einen Fehler zurück – das ist normal und durch den start_period-Parameter im Healthcheck berücksichtigt.

Schritt 5: Initiales Admin-Passwort abrufen

Beim ersten Start generiert Jenkins automatisch ein zufälliges Admin-Passwort und speichert es in /var/jenkins_home/secrets/initialAdminPassword. Du brauchst es für den Setup-Wizard.

docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

Alternativ findest du das Passwort prominent in den Container-Logs:

docker compose logs jenkins | grep -A 5 "Please use the following password"

Die Ausgabe sieht etwa so aus:

*************************************************************
Jenkins initial setup is required. An admin user has been created
and a password generated.
Please use the following password to proceed to installation:

a1b2c3d4e5f6789012345678abcdef01

*************************************************************

Notiere diesen 32-stelligen hexadezimalen String – du benötigst ihn einmalig im nächsten Schritt.

Verifizieren: Wenn docker exec fehlschlägt, ist Jenkins noch nicht vollständig gestartet – kurz warten und wiederholen. Das Passwort ist stets genau 32 Zeichen lang.

Schritt 6: Setup-Wizard im Browser abschließen

Öffne http://<HOST-IP>:8080 im Browser (oder http://localhost:8080 lokal). Der Setup-Wizard führt dich durch drei Schritte:

  1. Jenkins entsperren: Gib das initiale Admin-Passwort aus Schritt 5 ein und klicke auf „Continue".
  2. Plugins installieren: Wähle „Install suggested plugins" – Jenkins installiert die empfohlenen Plugins (Pipeline, Git, Credentials, Blue Ocean u. a.). Dieser Schritt dauert 5–10 Minuten und benötigt Internetzugang.
  3. Admin-Account erstellen: Lege einen Benutzernamen, ein sicheres Passwort und eine E-Mail-Adresse für den administrativen Account fest. Klicke auf „Save and Finish".

Nach Abschluss des Wizards startet Jenkins und ist vollständig einsatzbereit.

Verifizieren: Nach dem Setup-Wizard erscheint das Jenkins-Dashboard. Navigiere zu „Manage Jenkins → System Information" – dort sind alle aktiven Plugins und Systemparameter aufgelistet. Im Terminal:

curl -I http://localhost:8080/
# Erwartete Antwort: HTTP/1.1 200 OK  (oder 403 bei aktivierter Login-Pflicht – beide korrekt)

Schritt 7: Erster Pipeline-Job anlegen (optional)

Um zu prüfen, ob Jenkins korrekt arbeitet, lege einen einfachen Test-Job an. Klicke im Dashboard auf „New Item", wähle „Pipeline" und vergib einen Namen, z. B. test-pipeline. Im „Pipeline"-Reiter gibst du folgendes Jenkinsfile direkt ein:

pipeline {
    agent any
    stages {
        stage('Hello') {
            steps {
                echo 'Jenkins laeuft korrekt!'
            }
        }
    }
}

Klicke auf „Save" und dann „Build Now". Der Build sollte nach wenigen Sekunden mit blauer Kugel (Erfolg) abschließen.

Verifizieren: Im Build-Log unter „Console Output" erscheint die Ausgabe Jenkins laeuft korrekt! und der Build zeigt Status „SUCCESS".

Schritt 8: Updates durchführen

Jenkins-Updates sind denkbar einfach – alle Daten bleiben im Named Volume erhalten. Plane vor jedem Update dennoch ein Backup des Volumes ein.

cd /opt/jenkins
docker compose pull
docker compose up -d

Docker lädt das neue LTS-Image, stoppt den alten Container und startet einen neuen. Das Volume jenkins_home bleibt unberührt.

Verifizieren:

docker compose ps
# STATUS: Up (healthy)
docker inspect jenkins --format='{{.Config.Image}}'
# Zeigt das aktuell verwendete Image-Tag

Backup des Jenkins-Volumes

Da Jenkins alle Daten in /var/jenkins_home ablegt, reicht ein Backup des Named Volumes für eine vollständige Datensicherung:

# Container stoppen (empfohlen fuer konsistentes Backup)
docker compose down

# Volume-Inhalt als tar.gz sichern
docker run --rm \
  -v jenkins_home:/data:ro \
  -v /opt/backups:/backup \
  alpine tar czf /backup/jenkins_home_$(date +%Y%m%d).tar.gz -C /data .

# Container wieder starten
docker compose up -d

Eine systematische Backup-Strategie mit Rotation und Off-Site-Kopie beschreibt die Anleitung 3-2-1-Backup-Strategie umsetzen.

Troubleshooting / Typische Fehler

  1. Container startet und stoppt sofort – Logs zeigen java.lang.OutOfMemoryError: Zu wenig RAM. Passe in der .env den Wert JAVA_OPTS an: -Xmx1g -Xms256m für Hosts mit 1–2 GB RAM. Mindestens 1 GB sollte für Jenkins reserviert sein.
  2. Web-UI nach dem Start nicht erreichbar: Jenkins benötigt 2–3 Minuten zum vollständigen Hochfahren. docker compose logs -f jenkins zeigt den Fortschritt. Erst wenn „Jenkins is fully up and running" erscheint, ist Port 8080 bereit.
  3. Initiales Passwort nicht gefunden: Prüfe mit docker exec jenkins ls /var/jenkins_home/secrets/ ob die Datei initialAdminPassword existiert. Wenn nicht, ist Jenkins noch nicht fertig initialisiert – kurz warten.
  4. Permission denied auf /var/jenkins_home bei Bind Mount: Wenn du statt des Named Volumes einen Bind Mount nutzt (./jenkins_home:/var/jenkins_home), muss das Host-Verzeichnis vorab angelegt werden: mkdir -p ./jenkins_home && chown 1000:1000 ./jenkins_home. Mit Named Volumes (empfohlene Methode) entfällt dieses Problem.
  5. Plugin-Installation schlägt beim Setup-Wizard fehl: Jenkins versucht Plugins vom Update-Center zu laden. Bei eingeschränktem Internetzugang oder Proxy: JAVA_OPTS in der .env um -Dhttps.proxyHost=proxy.intern -Dhttps.proxyPort=3128 ergänzen.
  6. Reverse-Proxy-Warnung „It appears that your reverse proxy set up is broken": Beim Betrieb hinter nginx oder Traefik müssen die Header X-Forwarded-For, X-Forwarded-Proto und X-Forwarded-Host korrekt weitergeleitet werden. Zusätzlich JENKINS_OPTS=--prefix=/jenkins setzen, wenn Jenkins unter einem Subpfad läuft.
  7. Veraltetes Image jenkins (ohne Namespace) verwendet: Das Image unter hub.docker.com/_/jenkins ist seit Jahren als „deprecated" markiert und hat bekannte Sicherheitslücken. Ausschließlich jenkins/jenkins:lts-jdk21 verwenden.
  8. Datenverlust nach docker compose down -v: Das Flag -v löscht alle Volumes. Nie down -v ausführen, solange keine Datensicherung vorliegt. Der volumes-Block in der compose.yaml stellt sicher, dass ein Named Volume (kein anonymes) verwendet wird.

Häufige Fragen

Braucht Jenkins eine Datenbank wie PostgreSQL oder MySQL?

Nein. Jenkins ist ein dateibasiertes System und speichert die gesamte Konfiguration, alle Plugins, Workspaces und Build-Logs im Verzeichnis /var/jenkins_home. Eine externe Datenbank ist für die Standardinstallation weder erforderlich noch empfohlen.

Wie bekomme ich das initiale Admin-Passwort?

Es gibt zwei Wege: Entweder direkt aus dem Container mit docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword oder aus den Logs mit docker compose logs jenkins | grep -A 2 "password". Das Passwort erscheint beim ersten Start prominent in den Logs und ist 32 Zeichen lang (hexadezimal).

Wie installiere ich Plugins automatisch ohne Setup-Wizard?

Über ein eigenes Dockerfile: FROM jenkins/jenkins:lts-jdk21 und dann RUN jenkins-plugin-cli --plugins pipeline-model-definition github-branch-source. Dieses Muster eignet sich für unveränderliche Deployments, bei denen der Setup-Wizard nicht interaktiv durchlaufen werden kann.

Kann Jenkins auf einem Raspberry Pi oder ARM-Server laufen?

Ja. Das offizielle Image jenkins/jenkins:lts-jdk21 ist ein Multiarch-Image und unterstützt nativ linux/arm64 (aarch64). Auf einem Raspberry Pi 4 oder 5 mit 64-Bit-Betriebssystem läuft das Standard-Image ohne jegliche Anpassungen. Für den Pi empfiehlt sich mindestens das 4-GB-RAM-Modell.

Wie verbinde ich externe Build-Agenten (Nodes)?

Port 50000 muss vom Agenten-Host erreichbar sein (ggf. in der Firewall freigeben). In Jenkins unter „Manage Jenkins → Nodes → New Node" einen neuen Agenten anlegen, den JNLP-Startbefehl kopieren und auf dem Agenten-Host ausführen. Der Agenten-Host benötigt Java und Netzwerkzugang zu Jenkins auf Port 50000.

Wie aktualisiere ich Jenkins auf eine neue LTS-Version?

Da das Tag lts-jdk21 automatisch auf die neueste LTS-Version zeigt, reicht docker compose pull && docker compose up -d. Alle Daten im Volume bleiben erhalten. Vor jedem Update das Volume sichern – danach bei Bedarf unter „Manage Jenkins → Manage Plugins" etwaige Plugin-Updates abschließen.

Was ist der Unterschied zwischen Jenkins und Woodpecker CI?

Jenkins ist das flexibelste und ausgereifteste System mit über 1.800 Plugins – ideal für komplexe Anforderungen und heterogene Technologie-Stacks. Für schlanke, Pipeline-as-Code-zentrierte Setups ohne Plugin-Overhead ist Woodpecker CI mit Docker eine interessante leichtgewichtige Alternative.

Fazit

Jenkins per Docker Compose zu betreiben ist überraschend unkompliziert: eine compose.yaml, eine .env und docker compose up -d – fertig. Das Named Volume erledigt die Berechtigungsproblematik automatisch, der Healthcheck berücksichtigt Jenkins' längere Startzeit, und LTS-Updates sind auf drei Befehle reduziert. Der initiale Setup-Wizard mag für Einsteiger nach vielen Klicks aussehen, er ist aber einmalig und danach vollständig scriptbar.

Der eigentliche Mehrwert von Jenkins liegt in den 1.800+ Plugins und der Jenkinsfile-Syntax: Sobald Build-Pipelines als Code in der Versionsverwaltung liegen, werden Deployments reproduzierbar, nachvollziehbar und teamtauglich. Wer darüber hinaus Container-Images innerhalb von Pipelines bauen will, kann Docker-in-Docker (dind) als separaten Compose-Service hinzufügen – das ist jedoch ein optionaler Fortgeschrittenen-Schritt, der für die Basis-Installation nicht notwendig ist.

Für Secrets-Management, Non-Root-Container und sichere Healthcheck-Konfiguration in der Produktion lohnt sich ein Blick in Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren (Ubuntu/Debian) – die Self-Hosting-Grundlage
  2. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS – Jenkins sicher über HTTPS erreichbar machen
  3. Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only
  4. Woodpecker CI mit Docker installieren: schlanke CI/CD-Pipeline – leichtgewichtige Alternative
  5. 3-2-1-Backup-Strategie umsetzen – Jenkins-Volume sicher sichern

Offizielle Quellen: Jenkins-Dokumentation: Installation mit Docker · GitHub: jenkinsci/docker · Docker Hub: jenkins/jenkins