Bladeren bron

feat: 新增Jenkinsfile

天空之城 3 weken geleden
bovenliggende
commit
5d1d2909ea
1 gewijzigde bestanden met toevoegingen van 169 en 0 verwijderingen
  1. 169 0
      Jenkinsfile

+ 169 - 0
Jenkinsfile

@@ -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()
+    }
+  }
+}