Jenkins Example Jenkinsfile
Dateiname: Jenkinsfile
Glossar zu den wichtigsten Begriffen
- Pipeline: Definiert den gesamten CI/CD-Prozess in Jenkins.
- Agent: Bestimmt, wo die Pipeline oder ein Stage ausgeführt wird (z.B. auf einem beliebigen verfügbaren Knoten).
agent any
Gibt an, dass der Job auf einem beliebigen verfügbaren Jenkins-Agent/Node läuft. - Environment: Definiert Umgebungsvariablen, die in der Pipeline verwendet werden.
- Options: Konfiguriert verschiedene Optionen für die Pipeline, wie z.B. Farbausgabe, Zeitstempel, Build-Aufbewahrung und gleichzeitige Builds.
- Parameters: Definiert Eingabeparameter, die vor dem Build gesetzt werden können (z. B. Version, Registry, Deploy Host).
- Stages: Unterteilt die Pipeline in verschiedene Abschnitte (z.B. Build, Test, Deploy).
- stage checkout: Holt den Quellcode aus dem Versionskontrollsystem (z.B. Git).
- stage Build & Test (Maven): Führt den Build- und Testprozess mit Maven in einem Docker-Container aus.
- stage Build Docker Image: Baut ein Docker-Image basierend auf dem Dockerfile im Repository.
- stage Login & Push: Meldet sich bei der Container-Registry an und pusht das gebaute Image (optional).
- stage Deploy (SSH → docker compose up): Führt das Deployment auf einem Remote-Host via SSH und Docker Compose
- Steps: Einzelne Aktionen innerhalb einer Stage (z.B. Shell-Befehle ausführen).
pipeline {
agent any
environment {
// --- Adjust to your registry ---
REGISTRY_URL = credentials('docker-registry-url') // optional; use if your registry needs URL auth (e.g., https://ghcr.io)
REGISTRY = "${REGISTRY ?: ''}" // e.g., ghcr.io/<org> or docker.io/<user>; can be set in job params
IMAGE_NAME = "refcard01" // image/repository name
REGISTRY_CRED = "docker-registry-cred" // Jenkins Credentials ID (username/password or token)
SSH_CRED = "deploy-ssh" // Jenkins Credentials ID for SSH deploy
DEPLOY_HOST = "${DEPLOY_HOST ?: 'your-server.example.com'}"
DEPLOY_PATH = "${DEPLOY_PATH ?: '/opt/refcard01'}" // remote dir with docker-compose.yml
DOCKER_CONFIG = "${WORKSPACE}/.docker" // prevents polluting jenkins home
}
options {
ansiColor('xterm')
timestamps()
buildDiscarder(logRotator(numToKeepStr: '20'))
disableConcurrentBuilds()
}
parameters {
string(name: 'REGISTRY', defaultValue: '', description: 'Registry prefix (e.g. ghcr.io/yourorg or docker.io/youruser). Leave empty for local only.')
string(name: 'VERSION', defaultValue: '', description: 'Optional image tag. Empty -> auto from Git describe or commit hash.')
string(name: 'DEPLOY_HOST', defaultValue: '', description: 'Deploy target host (SSH). Leave empty to skip remote deploy.')
string(name: 'DEPLOY_PATH', defaultValue: '', description: 'Remote deploy folder with docker-compose.yml.')
}
stages {
stage('Checkout') {
steps {
checkout scm
script {
// Compute version/tag
def tag = params.VERSION?.trim()
if (!tag) {
// Try git describe, fallback to short SHA + build number
tag = sh(script: "git describe --tags --always --dirty || true", returnStdout: true).trim()
if (!tag) {
tag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
}
if (!tag) { tag = "build-${env.BUILD_NUMBER}" }
}
env.APP_VERSION = tag.replaceAll('[^a-zA-Z0-9_.-]', '-')
echo "Using APP_VERSION: ${env.APP_VERSION}"
}
}
}
stage('Build & Test (Maven)') {
agent {
docker {
image 'maven:3.9-eclipse-temurin-17'
args '-v $HOME/.m2:/root/.m2'
reuseNode true
}
}
steps {
sh 'mvn -B -ntp -DskipTests=false clean verify'
stash name: 'jar', includes: 'target/*.jar'
}
post {
always {
junit testResults: '**/target/surefire-reports/*.xml', allowEmptyResults: true
}
}
}
stage('Build Docker Image') {
when { expression { return fileExists('Dockerfile') } }
steps {
unstash 'jar'
script {
def fullImage = env.REGISTRY ? "${env.REGISTRY}/${env.IMAGE_NAME}:${env.APP_VERSION}" : "${env.IMAGE_NAME}:${env.APP_VERSION}"
sh '''
mkdir -p "${DOCKER_CONFIG}"
echo "Building image: ${fullImage}"
docker build -t "${fullImage}" .
'''
env.FULL_IMAGE = fullImage
}
}
}
stage('Login & Push') {
when { expression { return env.REGISTRY?.trim() } }
steps {
withCredentials([usernamePassword(credentialsId: env.REGISTRY_CRED, usernameVariable: 'REG_USER', passwordVariable: 'REG_PASS')]) {
sh '''
mkdir -p "${DOCKER_CONFIG}"
if [ -n "${REGISTRY_URL}" ]; then
echo "${REG_PASS}" | docker login "${REGISTRY_URL}" -u "${REG_USER}" --password-stdin
else
# For Docker Hub and registries that take server from tag
echo "${REG_PASS}" | docker login -u "${REG_USER}" --password-stdin
fi
docker push "${FULL_IMAGE}"
'''
}
}
}
stage('Deploy (SSH → docker compose up)') {
when { expression { return params.DEPLOY_HOST?.trim() } }
steps {
sshagent (credentials: [env.SSH_CRED]) {
sh '''
ssh -o StrictHostKeyChecking=no "${DEPLOY_HOST}" "mkdir -p ${DEPLOY_PATH}"
scp -o StrictHostKeyChecking=no docker-compose.yml "${DEPLOY_HOST}:${DEPLOY_PATH}/docker-compose.yml"
ssh -o StrictHostKeyChecking=no "${DEPLOY_HOST}" "cd ${DEPLOY_PATH} && DOCKER_IMAGE=${FULL_IMAGE} docker compose pull && DOCKER_IMAGE=${FULL_IMAGE} docker compose up -d"
'''
}
}
}
}
post {
success {
echo "Build OK. Image: ${env.FULL_IMAGE ?: '(no image)'}"
}
failure {
echo "Build FAILED."
}
}
}