|
@@ -0,0 +1,169 @@
|
|
|
|
|
+pipeline {
|
|
|
|
|
+ agent any
|
|
|
|
|
+ options {
|
|
|
|
|
+ buildDiscarder(logRotator(numToKeepStr: '5'))
|
|
|
|
|
+ timestamps()
|
|
|
|
|
+ }
|
|
|
|
|
+ parameters {
|
|
|
|
|
+ string(name: 'BRANCH', defaultValue: 'uat', description: '要部署到UAT的分支')
|
|
|
|
|
+ booleanParam(name: 'SKIP_APPROVAL', defaultValue: false, description: '跳过人工审批(谨慎使用)')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ environment {
|
|
|
|
|
+ // UAT 代码检出目录
|
|
|
|
|
+ CHECKOUT_BASE = "/docker/python-uat"
|
|
|
|
|
+ CODE_DIR = "/docker/python-uat"
|
|
|
|
|
+
|
|
|
|
|
+ // Dockerfile 路径
|
|
|
|
|
+ DOCKERFILE_STORE = "alien_store/Dockerfile"
|
|
|
|
|
+ DOCKERFILE_GATEWAY = "alien_gateway/Dockerfile"
|
|
|
|
|
+ DOCKERFILE_CONTRACT = "alien_contract/Dockerfile"
|
|
|
|
|
+
|
|
|
|
|
+ // 如需推送远端 Registry,填写地址,否则留空
|
|
|
|
|
+ REGISTRY = ""
|
|
|
|
|
+ REGISTRY_CRED = "registry-cred-id"
|
|
|
|
|
+
|
|
|
|
|
+ // 镜像标签统一使用 uat
|
|
|
|
|
+ IMAGE_STORE = "${REGISTRY ? REGISTRY + '/alien_store:uat-' + env.BUILD_NUMBER : 'alien_store:uat'}"
|
|
|
|
|
+ IMAGE_GATEWAY = "${REGISTRY ? REGISTRY + '/alien_gateway:uat-' + env.BUILD_NUMBER : 'alien_gateway:uat'}"
|
|
|
|
|
+ IMAGE_CONTRACT = "${REGISTRY ? REGISTRY + '/alien_contract:uat-' + env.BUILD_NUMBER : 'alien_contract:uat'}"
|
|
|
|
|
+
|
|
|
|
|
+ // 容器名(store 不要再用 esign-uat,会和真正的 e签宝容器撞名)
|
|
|
|
|
+ CONTAINER_NAME_STORE = "alien_store_py-uat"
|
|
|
|
|
+ CONTAINER_NAME_GATEWAY = "alien_gateway_py-uat"
|
|
|
|
|
+ CONTAINER_NAME_CONTRACT = "alien_contract_py-uat"
|
|
|
|
|
+
|
|
|
|
|
+ // 容器内端口(必须与各服务 Dockerfile 中 uvicorn 监听端口一致)
|
|
|
|
|
+ PORT_STORE = "8001"
|
|
|
|
|
+ PORT_GATEWAY = "43333"
|
|
|
|
|
+ PORT_CONTRACT = "8002"
|
|
|
|
|
+
|
|
|
|
|
+ // 使用独立的 UAT 网络
|
|
|
|
|
+ DOCKER_NET = "alien_net_uat"
|
|
|
|
|
+
|
|
|
|
|
+ // UAT 日志目录
|
|
|
|
|
+ LOG_ROOT = "/docker/python-uat/logs"
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stages {
|
|
|
|
|
+ stage('Checkout') {
|
|
|
|
|
+ steps {
|
|
|
|
|
+ echo ">>> UAT环境:拉取分支 ${params.BRANCH} 到 ${CHECKOUT_BASE} ..."
|
|
|
|
|
+ sh "mkdir -p ${CHECKOUT_BASE}"
|
|
|
|
|
+ dir("${CHECKOUT_BASE}") {
|
|
|
|
|
+ git branch: "${params.BRANCH}",
|
|
|
|
|
+ credentialsId: 'gogs-alien-cloud-uat',
|
|
|
|
|
+ url: 'http://8.152.195.41:3000/alien/alien_py_cloud'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stage('人工审批') {
|
|
|
|
|
+ when {
|
|
|
|
|
+ expression { !params.SKIP_APPROVAL }
|
|
|
|
|
+ }
|
|
|
|
|
+ steps {
|
|
|
|
|
+ script {
|
|
|
|
|
+ def userInput = input(
|
|
|
|
|
+ id: 'UATDeployConfirm',
|
|
|
|
|
+ message: "是否将分支 ${params.BRANCH} 部署到 UAT 环境?",
|
|
|
|
|
+ ok: '确认部署',
|
|
|
|
|
+ submitter: 'admin,release-manager',
|
|
|
|
|
+ parameters: [
|
|
|
|
|
+ booleanParam(name: 'CONFIRM', defaultValue: true, description: '我确认部署到UAT')
|
|
|
|
|
+ ]
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stage('Build Images') {
|
|
|
|
|
+ steps {
|
|
|
|
|
+ script {
|
|
|
|
|
+ if (env.REGISTRY?.trim()) {
|
|
|
|
|
+ withDockerRegistry(credentialsId: env.REGISTRY_CRED, url: "") {
|
|
|
|
|
+ dir(env.CODE_DIR) {
|
|
|
|
|
+ sh "docker build -f ${DOCKERFILE_STORE} -t ${IMAGE_STORE} ."
|
|
|
|
|
+ sh "docker build -f ${DOCKERFILE_GATEWAY} -t ${IMAGE_GATEWAY} ."
|
|
|
|
|
+ sh "docker build -f ${DOCKERFILE_CONTRACT} -t ${IMAGE_CONTRACT} ."
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ dir(env.CODE_DIR) {
|
|
|
|
|
+ sh "docker build -f ${DOCKERFILE_STORE} -t ${IMAGE_STORE} ."
|
|
|
|
|
+ sh "docker build -f ${DOCKERFILE_GATEWAY} -t ${IMAGE_GATEWAY} ."
|
|
|
|
|
+ sh "docker build -f ${DOCKERFILE_CONTRACT} -t ${IMAGE_CONTRACT} ."
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stage('Push Images') {
|
|
|
|
|
+ when { expression { return env.REGISTRY?.trim() as boolean } }
|
|
|
|
|
+ steps {
|
|
|
|
|
+ withDockerRegistry(credentialsId: env.REGISTRY_CRED, url: "") {
|
|
|
|
|
+ sh "docker push ${IMAGE_STORE}"
|
|
|
|
|
+ sh "docker push ${IMAGE_GATEWAY}"
|
|
|
|
|
+ sh "docker push ${IMAGE_CONTRACT}"
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ stage('Deploy') {
|
|
|
|
|
+ steps {
|
|
|
|
|
+ script {
|
|
|
|
|
+ echo ">>> UAT 部署镜像: ${IMAGE_STORE} / ${IMAGE_GATEWAY} / ${IMAGE_CONTRACT}"
|
|
|
|
|
+ sh """
|
|
|
|
|
+ # 创建 UAT 专用网络
|
|
|
|
|
+ docker network create ${DOCKER_NET} 2>/dev/null || true
|
|
|
|
|
+
|
|
|
|
|
+ # 创建日志目录
|
|
|
|
|
+ mkdir -p ${LOG_ROOT}/store ${LOG_ROOT}/gateway ${LOG_ROOT}/contract
|
|
|
|
|
+
|
|
|
|
|
+ # 停止旧容器(不会误删 java 的 gateway-uat / store-uat / 真正的 esign-uat 等)
|
|
|
|
|
+ docker rm -f ${CONTAINER_NAME_STORE} ${CONTAINER_NAME_GATEWAY} ${CONTAINER_NAME_CONTRACT} 2>/dev/null || true
|
|
|
|
|
+
|
|
|
|
|
+ # 1) 先启动下游:store
|
|
|
|
|
+ # 只走 docker 内部网络,不向宿主机暴露端口(避免与 java gateway-uat 抢 8001)
|
|
|
|
|
+ docker run -d --name ${CONTAINER_NAME_STORE} \\
|
|
|
|
|
+ --network ${DOCKER_NET} \\
|
|
|
|
|
+ -v ${LOG_ROOT}/store:/app/common/logs/alien_store \\
|
|
|
|
|
+ --restart unless-stopped \\
|
|
|
|
|
+ ${IMAGE_STORE}
|
|
|
|
|
+
|
|
|
|
|
+ # 2) 再启动下游:contract
|
|
|
|
|
+ # 只走 docker 内部网络,不向宿主机暴露端口
|
|
|
|
|
+ docker run -d --name ${CONTAINER_NAME_CONTRACT} \\
|
|
|
|
|
+ --network ${DOCKER_NET} \\
|
|
|
|
|
+ -v ${LOG_ROOT}/contract:/app/common/logs/alien_contract \\
|
|
|
|
|
+ --restart unless-stopped \\
|
|
|
|
|
+ ${IMAGE_CONTRACT}
|
|
|
|
|
+
|
|
|
|
|
+ # 3) 最后启动网关:gateway(依赖上面两个下游;唯一对外暴露的入口)
|
|
|
|
|
+ docker run -d --name ${CONTAINER_NAME_GATEWAY} \\
|
|
|
|
|
+ --network ${DOCKER_NET} \\
|
|
|
|
|
+ -p ${PORT_GATEWAY}:${PORT_GATEWAY} \\
|
|
|
|
|
+ -v ${LOG_ROOT}/gateway:/app/common/logs/alien_gateway \\
|
|
|
|
|
+ -e STORE_BASE_URL=http://${CONTAINER_NAME_STORE}:${PORT_STORE} \\
|
|
|
|
|
+ -e CONTRACT_BASE_URL=http://${CONTAINER_NAME_CONTRACT}:${PORT_CONTRACT} \\
|
|
|
|
|
+ --restart unless-stopped \\
|
|
|
|
|
+ ${IMAGE_GATEWAY}
|
|
|
|
|
+ """
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ post {
|
|
|
|
|
+ success {
|
|
|
|
|
+ echo "UAT 环境部署成功!"
|
|
|
|
|
+ }
|
|
|
|
|
+ failure {
|
|
|
|
|
+ echo "UAT 环境部署失败,请检查日志。"
|
|
|
|
|
+ }
|
|
|
|
|
+ always {
|
|
|
|
|
+ cleanWs()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|