?Jenkinsfile dsl文件:
pipeline {// 指定任務在哪個集群節點執行agent any// 聲明全局變量environment {key='value'APPLICATION_NAME='springboot-demo' // 項目名稱HOST_PORT='7777' // 宿主機暴露服務端口CONTAINER_PORT='8080' // 容器內部服務端口TOKEN='squ_9aa459d05021a8db7f95e9f0ea9ac9b00d8bdbfb'HARBOR_REPO='repo'HARBOR_ADDR='192.168.208.120:80'SONAR_ADDR='192.168.208.151:9000'JAVA_HOME='/usr/local/share/jdk-1.8.0'MAVEN_HOME='/usr/local/share/maven-3.9.6'}// 流水執行工序,每道工序又有多個小步驟stages {stage('git拉取代碼'){steps{echo '=====================> Git pulling code 'checkout scmGit(branches: [[name: '${branch_tag}']], extensions: [], userRemoteConfigs: [[credentialsId: 'de069ab5-cfa3-490f-9add-a1f79f641cc5', url: 'http://192.168.208.141/root/gitlab-project.git']])}}// ====================== 192.168.208.151 服務器上運行 ========================stage('maven編譯打包'){steps{echo '=====================> Maven building code'sh '''export PATH=${JAVA_HOME}/bin:${MAVEN_HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin# 當前目錄是/var/lib/jenkins/workspace/<jenkins任務名稱> (pipeline)cd ${APPLICATION_NAME}/mvn clean package -Dmaven.test.skip=true'''}}// ====================== 192.168.208.151 服務器上運行 ========================stage('sonar代碼質檢'){steps{echo '=====================> Sonar starting scan'sh '''/usr/local/share/sonar-scanner-cli-7.1.0/bin/sonar-scanner \\-Dsonar.projectName=pipeline \\-Dsonar.projectKey=pipeline \\-Dsonar.sources=/var/lib/jenkins/workspace/pipeline/${APPLICATION_NAME}/target \\-Dsonar.host.url=http://${SONAR_ADDR} \\-Dsonar.login=${TOKEN}'''}}// ====================== 192.168.208.151 服務器上運行 ========================stage('docker構建鏡像'){steps{echo '=====================> Docker building image'sh '''# 鏡像名稱applicationName="${APPLICATION_NAME}"# 進入目錄docker找到 Dockerfile文件cd ${APPLICATION_NAME}/docker/# 將jar包挪到docker目錄下mv ../target/*.jar ./# 構建docker鏡像docker build -t ${APPLICATION_NAME}:${branch_tag} .# 刪除本地的懸空的鏡像docker image prune -f'''}}stage('harbor制品入庫'){steps{echo '=====================> Docker push artifact to harbor'sh '''# 登錄Harbor鏡像倉庫docker login -u admin -p 123456 ${HARBOR_ADDR}# 對構建好鏡像進行打標簽docker tag ${APPLICATION_NAME}:${branch_tag} ${HARBOR_ADDR}/repo/${APPLICATION_NAME}:${branch_tag}# 刪除本地的懸空的鏡像docker image prune -f# 推送Harbor鏡像倉庫docker push ${HARBOR_ADDR}/repo/${APPLICATION_NAME}:${branch_tag}# Harbor有自己的定時清理任務,清理無tag任務'''}}stage('SSH-publisher通知部署'){steps{echo '=====================> SSH-publisher starting deploy'echo "HARBOR_ADDR = ${HARBOR_ADDR}"echo "HARBOR_REPO = ${HARBOR_REPO}"echo "APPLICATION_NAME = ${APPLICATION_NAME}"echo "branch_tag = ${branch_tag}"echo "HOST_PORT = ${HOST_PORT}"echo "CONTAINER_PORT = ${CONTAINER_PORT}"// 注意! 這里的 execCommand 后面要使用""" 而不是 '''sshPublisher(publishers: [sshPublisherDesc(configName: 'app-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: """/usr/bin/deploy.sh ${HARBOR_ADDR} ${HARBOR_REPO} ${APPLICATION_NAME} ${branch_tag} ${HOST_PORT} ${CONTAINER_PORT}""", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])}}}// 調用釘釘的 webhook 接口將部署信息發布到工作群post {success {dingtalk(robot: 'Jenkins-dd',type: 'MARKDOWN',title: "success: ${APPLICATION_NAME}",text: ["- 構建成功: ${APPLICATION_NAME} \n- 版本: ${branch_tag} \n- 持續時間: ${currentBuild.durationString}"])}failure {dingtalk(robot: 'Jenkins-dd',type: 'MARKDOWN',title: "success: ${APPLICATION_NAME}",text: ["- 構建失敗: ${APPLICATION_NAME} \n- 版本: ${branch_tag} \n- 持續時間: ${currentBuild.durationString}"])}}}
目標服務器部署腳本:
?
[root@localhost ~]# cat deploy.sh
#!/bin/bash# ===============================================================================
# Author: ldj
# Date: 2025-07-08 15:37:11
# Description: 首先刪除舊的容器和鏡像,然后登錄到 Harbor 并拉取最新的鏡像進行部署
# ===============================================================================# 顯示每條命令執行情況,便于調試
set -xharbor_addr=$1
harbor_repo=$2
project_name=$3
version=$4
host_port=$5
container_port=$6image_name=${harbor_addr}/${harbor_repo}/${project_name}:${version}echo "鏡像名稱:${image_name}"# 刪除舊容器
container_id=$(docker ps -aq --filter name=${project_name})
if [ -n "${container_id}" ]; thendocker stop ${container_id}docker rm ${container_id}echo "已停止并刪除容器: ${container_id}"
fi# 刪除本地舊鏡像
old_version=$(docker images | grep ${project_name} | awk '{print $2}')if [ "${old_version}" == "${version}" ]; thendocker rmi -f ${old_images}echo "已刪除本地舊鏡像"
fi# 登錄Harbor
docker login -u admin -p 123456 ${harbor_addr} || { echo '登錄Harbor失敗'; exit 1; }# 拉取新鏡像
echo "開始拉取新鏡像"
docker pull ${image_name} || { echo "拉取新鏡像失敗"; exit 1; }# 運行新容器
docker run -d -p ${host_port}:${container_port} --name ${project_name} ${image_name}echo ${project_name} '成功運行!'# 刪除懸空鏡像
docker image prune -f