diff --git a/Jenkinsfile b/Jenkinsfile index 81e2db2..6cf89c8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,9 +1,20 @@ // BuildFlow buildflow-portal CI/CD -// 链路:①拉取代码 → ②编译打包(docker build) → 推送 Harbor → ③部署(cd-target SSH) → HealthCheck -// 注:飞书通知逻辑已移除(凭证未配齐);部署通过 ssh 直连 cd-target 执行。 +// 链路:①拉取代码 → ②编译打包(docker build) → 推送 Harbor → ③部署(cd-target docker compose) → HealthCheck +// 自动触发:Gitea push → Generic Webhook Trigger(token=buildflow-portal) +// Gitea webhook 指向:http://jenkins:8080/generic-webhook-trigger/invoke?token=buildflow-portal pipeline { agent any + triggers { + GenericTrigger( + token: 'buildflow-portal', + causeString: 'Gitea push 触发', + printContributedVariables: false, + printPostContent: false, + regexpFilterText: '', + regexpFilterExpression: '' + ) + } environment { HARBOR = "43.134.235.58:58080" IMAGE = "${HARBOR}/buildflow/buildflow-portal" @@ -11,6 +22,8 @@ pipeline { // Jenkins 容器内无 ssh 别名,直接用 IP;ubuntu 用户 sudo 免密(NOPASSWD) DEPLOY_HOST = "ubuntu@110.42.240.10" APP_PORT = "5173" + DEPLOY_DIR = "/home/ubuntu/deploy" + SERVICE = "buildflow-portal" } options { timeout(time: 30, unit: "MINUTES") @@ -43,36 +56,38 @@ pipeline { } 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-portal 2>/dev/null || true - sudo docker run -d --name buildflow-portal --restart unless-stopped -p ${APP_PORT}:${APP_PORT} ${IMAGE}:latest - " - """ - } - echo "部署完成" - } catch (e) { - echo "警告:部署节点 ${DEPLOY_HOST} 暂不可用,跳过自动部署(镜像已推送 Harbor)。原因:${e.getMessage()}" - } + withCredentials([usernamePassword(credentialsId: "harbor-credentials", usernameVariable: "HUSER", passwordVariable: "HPASS")]) { + sh """ + ssh -o StrictHostKeyChecking=accept-new ${DEPLOY_HOST} " + cd ${DEPLOY_DIR} + echo '${HPASS}' | sudo docker login ${HARBOR} -u ${HUSER} --password-stdin + sudo docker compose pull ${SERVICE} + sudo docker compose up -d --no-deps ${SERVICE} + " + """ } + echo "部署完成" } } stage("HealthCheck") { steps { script { - try { - sh """ - sleep 5 - ssh -o StrictHostKeyChecking=accept-new ${DEPLOY_HOST} 'wget -q --spider http://127.0.0.1:${APP_PORT}/ && echo HEALTHCHECK_OK' - """ - echo "=== HealthCheck OK: portal http://110.42.240.10:${APP_PORT} ===" - } catch (e) { - echo "警告:HealthCheck 探测失败(容器可能仍在启动)。镜像已推送 Harbor,可手动检查。" + def healthy = false + for (int i = 1; i <= 6; i++) { + sleep 5 + try { + sh """ + ssh -o StrictHostKeyChecking=accept-new ${DEPLOY_HOST} 'wget -q --spider http://127.0.0.1:${APP_PORT}/ && echo HEALTHCHECK_OK' + """ + healthy = true + echo "=== HealthCheck OK: portal http://110.42.240.10:${APP_PORT} ===" + break + } catch (e) { + echo "HealthCheck 第 ${i}/6 次探测未就绪,5s 后重试..." + } + } + if (!healthy) { + unstable("HealthCheck 30s 内未通过,查日志:ssh cd-target 'sudo docker logs ${SERVICE} --tail 50'") } } }