Jenkins CI/CD-Pipelines automatisieren den gesamten Software-Delivery-Prozess — vom Kompilieren des Codes über das Ausführen von Tests bis hin zum Deployment in die Produktion. Als meistgenutzter Open-Source-Automationsserver integriert sich Jenkins nahtlos mit nahezu jedem Entwicklungswerkzeug, Cloud-Anbieter und Versionskontrollsystem. Egal ob du eine Python-API, eine Node.js-Anwendung oder Infrastruktur mit Terraform deployest — Jenkins Pipelines legen den Delivery-Prozess als Code fest, der direkt neben deiner Anwendung im Repository lebt. Dieser Leitfaden führt dich durch die Einrichtung von Jenkins, das Schreiben deiner ersten Pipeline und die Konfiguration einer produktionsreifen Automatisierung.

Voraussetzungen

  • Ein Server mit mindestens 2 GB RAM und 10 GB Festplattenspeicher (Ubuntu 22.04 oder neuer empfohlen)
  • Java 17 oder neuer installiert (Jenkins benötigt ein JDK)
  • Docker installiert (optional, aber für containerisierte Agents empfohlen)
  • Ein Git-Repository mit Anwendungscode, der gebaut werden soll
  • Grundkenntnisse in YAML, Groovy und Shell-Scripting

Jenkins installieren

Mit Docker (Empfohlen)

# Docker-Volume für persistente Daten anlegen
docker volume create jenkins-data

# Jenkins mit Docker-Socket-Zugriff starten (für Docker-basierte Agents)
docker run -d \
  --name jenkins \
  --restart unless-stopped \
  -p 8080:8080 \
  -p 50000:50000 \
  -v jenkins-data:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  jenkins/jenkins:lts

# Initiales Admin-Passwort abrufen
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

Über das offizielle Repository (Ubuntu/Debian)

# Jenkins-Repository-Schlüssel und -Quelle hinzufügen
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null

echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian-stable binary/" | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null

# Jenkins installieren
sudo apt update
sudo apt install jenkins

# Jenkins startet automatisch — Status prüfen
sudo systemctl status jenkins

# Initiales Admin-Passwort abrufen
sudo cat /var/lib/jenkins/secrets/initialAdminPassword

Öffne http://dein-server:8080 im Browser, füge das initiale Passwort ein und folge dem Setup-Assistenten. Installiere die vorgeschlagenen Plugins — sie enthalten Git, Pipeline und die am häufigsten benötigten Integrationen.

Dein erstes Jenkinsfile schreiben

Ein Jenkinsfile definiert deine Pipeline als Code. Es liegt im Stammverzeichnis deines Git-Repositorys und Jenkins liest es bei jedem Build ein.

Deklarative Pipeline-Syntax

// Jenkinsfile
pipeline {
    agent any

    environment {
        APP_NAME = 'my-web-app'
        DEPLOY_ENV = 'staging'
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Install Dependencies') {
            steps {
                sh 'npm ci'
            }
        }

        stage('Lint') {
            steps {
                sh 'npm run lint'
            }
        }

        stage('Test') {
            steps {
                sh 'npm test'
            }
            post {
                always {
                    junit 'test-results/**/*.xml'
                }
            }
        }

        stage('Build') {
            steps {
                sh 'npm run build'
                archiveArtifacts artifacts: 'dist/**', fingerprint: true
            }
        }

        stage('Deploy to Staging') {
            when {
                branch 'main'
            }
            steps {
                sh './deploy.sh ${DEPLOY_ENV}'
            }
        }
    }

    post {
        failure {
            mail to: 'team@example.com',
                 subject: "Pipeline Failed: ${APP_NAME} #${BUILD_NUMBER}",
                 body: "Check: ${BUILD_URL}"
        }
        success {
            echo 'Pipeline completed successfully!'
        }
    }
}

Pipeline mit Docker-Agents

pipeline {
    agent none    // Kein globaler Agent — jede Stage wählt ihren eigenen

    stages {
        stage('Build') {
            agent {
                docker {
                    image 'node:18-alpine'
                    args '-v $HOME/.npm:/root/.npm'    // npm-Pakete cachen
                }
            }
            steps {
                sh 'npm ci && npm run build'
                stash includes: 'dist/**', name: 'build-output'
            }
        }

        stage('Test') {
            agent {
                docker { image 'node:18-alpine' }
            }
            steps {
                sh 'npm ci && npm test'
            }
        }

        stage('Docker Image') {
            agent any
            steps {
                unstash 'build-output'
                sh 'docker build -t myapp:${BUILD_NUMBER} .'
                sh 'docker push registry.example.com/myapp:${BUILD_NUMBER}'
            }
        }
    }
}

Jede Stage läuft in einem frischen Docker-Container mit dem angegebenen Image. Die Befehle stash und unstash übergeben Build-Artefakte zwischen Stages, die auf unterschiedlichen Agents laufen.

Zugangsdaten und Secrets verwalten

Hardcode niemals Secrets in Jenkinsfiles. Nutze stattdessen den Jenkins Credentials Manager:

  1. Navigiere zu Manage Jenkins > Credentials > System > Global credentials
  2. Klicke auf Add Credentials
  3. Wähle den Typ (Username/Password, SSH Key, Secret Text usw.)
  4. Vergib eine ID wie docker-registry-creds

Zugangsdaten in der Pipeline verwenden:

stage('Deploy') {
    steps {
        withCredentials([
            usernamePassword(
                credentialsId: 'docker-registry-creds',
                usernameVariable: 'DOCKER_USER',
                passwordVariable: 'DOCKER_PASS'
            )
        ]) {
            sh 'docker login -u $DOCKER_USER -p $DOCKER_PASS registry.example.com'
            sh 'docker push registry.example.com/myapp:${BUILD_NUMBER}'
        }
    }
}

Die Zugangsdaten werden nur innerhalb des withCredentials-Blocks als Umgebungsvariablen injiziert und im Build-Log maskiert.

Jenkins im Vergleich zu CI/CD-Alternativen

FeatureJenkinsGitHub ActionsGitLab CICircleCI
Self-hostedJa (primär)Ja (Runner)JaNein
Cloud-hostedNein (Community)JaJaJa
KonfigurationJenkinsfile (Groovy)YAMLYAMLYAML
Plugin-Ökosystem1800+ PluginsActions MarketplaceIntegrierte FeaturesOrbs
Docker-UnterstützungVia PluginsNativNativNativ
Preis (self-hosted)Kostenlos (Open Source)Kostenlos (self-hosted Runner)Kostenlos (CE)N/A
LernkurveSteilFlachFlachFlach
Geeignet fürKomplexe Enterprise-WorkflowsGitHub-native ProjekteGitLab-native ProjekteSaaS-first Teams

Verwende Jenkins, wenn du vollständige Kontrolle über die Build-Infrastruktur benötigst, komplexe Multi-Branch-Workflows hast oder in einem Enterprise-Umfeld mit strengen Sicherheitsanforderungen arbeitest. Verwende GitHub Actions für Projekte, die bereits auf GitHub liegen und einfaches CI/CD ohne eigene Infrastrukturverwaltung benötigen.

Praxisszenario: Multi-Branch-Pipeline

Dein Team arbeitet mit Feature-Branches. Du möchtest, dass Jenkins automatisch jeden Branch baut und testet, main nach Staging deployt und nur getaggte Releases in die Produktion überführt.

pipeline {
    agent { docker { image 'node:18' } }

    stages {
        stage('Build & Test') {
            steps {
                sh 'npm ci && npm test && npm run build'
            }
        }

        stage('Deploy Staging') {
            when { branch 'main' }
            steps {
                sh './deploy.sh staging'
            }
        }

        stage('Deploy Production') {
            when { tag 'v*' }
            steps {
                input message: 'Deploy to production?', ok: 'Deploy'
                sh './deploy.sh production'
            }
        }
    }
}

Der input-Schritt hält die Pipeline an und wartet auf eine menschliche Freigabe für das Produktions-Deployment — ein Sicherheitsschalter, der versehentliche Releases verhindert.

Stolperfallen und Sonderfälle

Jenkins geht der Festplattenspeicher aus: Alte Builds häufen Artefakte und Logs an. Konfiguriere die Build-Aufbewahrung in den Job-Einstellungen (Alte Builds verwerfen) und richte einen Cron-Job ein, um den Workspace zu bereinigen: jenkins-cli delete-builds job-name --range 1-100.

Pipeline hängt beim input-Schritt: Wenn niemand die Eingabe bestätigt, blockiert die Pipeline dauerhaft einen Build-Executor. Setze einen Timeout: timeout(time: 30, unit: 'MINUTES') { input ... }.

Docker-Socket-Berechtigungen: Wenn Jenkins in Docker mit eingebundenem Docker-Socket läuft, benötigt der Jenkins-Benutzer Zugriff auf /var/run/docker.sock. Füge den jenkins-Benutzer zur docker-Gruppe hinzu oder passe die Socket-Berechtigungen an.

Groovy-Sandbox-Einschränkungen: Deklarative Pipelines laufen in einer Groovy-Sandbox, die bestimmte Operationen blockiert. Wenn du uneingeschränktes Groovy benötigst (Datei-I/O, Netzwerkaufrufe), muss die Pipeline durch einen Admin unter Manage Jenkins > Script Approval freigegeben werden.

Plugin-Versionskonflikte: Jenkins hat 1800+ Plugins, die gelegentlich in Konflikt geraten. Fixiere Plugin-Versionen und teste Upgrades in einer Staging-Jenkins-Instanz, bevor du die Produktion aktualisierst.

Fehlerbehebung

Pipeline schlägt fehl mit “No such DSL method”

// Dieser Fehler bedeutet, dass ein benötigtes Plugin nicht installiert ist
// Sicherstellen, dass Pipeline, Git und Docker Pipeline Plugins installiert sind
// Manage Jenkins > Plugins > Installed plugins

Build-Workspace wird zu groß

// Aufräumschritt zur Pipeline hinzufügen
post {
    always {
        cleanWs()    // Workspace nach dem Build löschen
    }
}

Webhook-Trigger funktionieren nicht

# Prüfen, ob Jenkins vom Git-Anbieter erreichbar ist
curl -I http://dein-jenkins:8080/github-webhook/

# Jenkins-Systemprotokoll auf Webhook-Ereignisse prüfen
# Manage Jenkins > System Log > All Jenkins Logs

Zusammenfassung

  • Jenkins-Pipelines definieren den CI/CD-Prozess als Code in einem Jenkinsfile, das neben der Anwendung im Git-Repository liegt
  • Deklarative Syntax mit pipeline-, stages- und steps-Blöcken ist der empfohlene Ansatz — sie ist leichter lesbar, validierbar und wartbar als Scripted Pipelines
  • Docker-Agents führen jede Pipeline-Stage in einem frischen Container aus und sorgen so für konsistente Build-Umgebungen ohne “funktioniert nur bei mir”-Probleme
  • Nutze den Credentials Manager für alle Secrets — Passwörter, Tokens und SSH-Keys gehören nie ins Jenkinsfile
  • Multi-Branch-Pipelines mit when { branch } und when { tag } wenden automatisch unterschiedliche Deployment-Regeln je Branch an
  • Build-Aufbewahrung und Workspace-Bereinigung verhindern, dass Jenkins über die Zeit den gesamten verfügbaren Festplattenspeicher verbraucht

Verwandte Artikel