// BuildFlow buildflow-web CI/CD // 链路:①拉取代码 → ②编译打包(docker build) → 推送 Harbor → ③部署(cd-target SSH) → HealthCheck // 注:飞书通知逻辑已移除(凭证未配齐);部署通过 ssh 直连 cd-target 执行。 pipeline { agent any environment { HARBOR = "43.134.235.58:58080" IMAGE = "${HARBOR}/buildflow/buildflow-web" TAG = "${env.BUILD_NUMBER}" // Jenkins 容器内无 ssh 别名,直接用 IP;ubuntu 用户 sudo 免密(NOPASSWD) DEPLOY_HOST = "ubuntu@110.42.240.10" APP_PORT = "80" // 容器内 nginx 监听 80;宿主映射 5175:80 HOST_PORT = "5175" } options { timeout(time: 30, unit: "MINUTES") buildDiscarder(logRotator(numToKeepStr: "10")) } stages { stage("① 拉取代码") { steps { checkout scm sh "git log --oneline -3" } } stage("② 编译打包") { steps { sh "docker build -t ${IMAGE}:${TAG} -t ${IMAGE}:latest ." sh "docker images | grep ${IMAGE} | head -2" } } stage("推送 Harbor") { steps { withCredentials([usernamePassword(credentialsId: "harbor-credentials", usernameVariable: "HUSER", passwordVariable: "HPASS")]) { sh ''' echo $HPASS | docker login $HARBOR -u $HUSER --password-stdin docker push $IMAGE:$TAG docker push $IMAGE:latest docker logout $HARBOR ''' } } } stage("③ 部署") { steps { script { try { withCredentials([usernamePassword(credentialsId: "harbor-credentials", usernameVariable: "HUSER", passwordVariable: "HPASS")]) { sh """ ssh -o StrictHostKeyChecking=accept-new ${DEPLOY_HOST} " echo '${HPASS}' | sudo docker login ${HARBOR} -u ${HUSER} --password-stdin sudo docker pull ${IMAGE}:latest sudo docker rm -f buildflow-web 2>/dev/null || true sudo docker run -d --name buildflow-web --restart unless-stopped -p ${HOST_PORT}:${APP_PORT} ${IMAGE}:latest " """ } echo "部署完成" } catch (e) { echo "警告:部署节点 ${DEPLOY_HOST} 暂不可用,跳过自动部署(镜像已推送 Harbor)。原因:${e.getMessage()}" } } } } stage("HealthCheck") { steps { script { try { sh """ sleep 5 ssh -o StrictHostKeyChecking=accept-new ${DEPLOY_HOST} 'wget -q --spider http://127.0.0.1:${HOST_PORT}/ && echo HEALTHCHECK_OK' """ echo "=== HealthCheck OK: web http://110.42.240.10:${HOST_PORT} ===" } catch (e) { echo "警告:HealthCheck 探测失败(容器可能仍在启动)。镜像已推送 Harbor,可手动检查。" } } } } } post { success { echo '=== buildflow-web CI/CD SUCCESS ===' } failure { echo '=== buildflow-web CI/CD FAILED ===' } always { sh "docker rmi ${IMAGE}:${TAG} ${IMAGE}:latest 2>/dev/null || true" deleteDir() } } }