feat(cicd): 接入自动触发 + docker compose 部署

- Jenkinsfile 加 GenericTrigger(token=buildflow-portal)
- 部署 stage 改 docker compose
- HealthCheck 改轮询,失败标 unstable
This commit is contained in:
xiangning 2026-07-17 15:22:51 +08:00
parent ba3727723e
commit 501f70d489

41
Jenkinsfile vendored
View File

@ -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} "
cd ${DEPLOY_DIR}
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
sudo docker compose pull ${SERVICE}
sudo docker compose up -d --no-deps ${SERVICE}
"
"""
}
echo "部署完成"
} catch (e) {
echo "警告:部署节点 ${DEPLOY_HOST} 暂不可用,跳过自动部署(镜像已推送 Harbor)。原因:${e.getMessage()}"
}
}
}
}
stage("HealthCheck") {
steps {
script {
def healthy = false
for (int i = 1; i <= 6; i++) {
sleep 5
try {
sh """
sleep 5
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 探测失败(容器可能仍在启动)。镜像已推送 Harbor,可手动检查。"
echo "HealthCheck 第 ${i}/6 次探测未就绪,5s 后重试..."
}
}
if (!healthy) {
unstable("HealthCheck 30s 内未通过,查日志:ssh cd-target 'sudo docker logs ${SERVICE} --tail 50'")
}
}
}