Parcourir la source

e签宝 Jenkinsfile

dujian il y a 3 semaines
Parent
commit
76ac395777
2 fichiers modifiés avec 177 ajouts et 19 suppressions
  1. 173 0
      Jenkinsfile
  2. 4 19
      docs/jenkins/Jenkinsfile-alien-py-cloud-produ.groovy

+ 173 - 0
Jenkinsfile

@@ -0,0 +1,173 @@
+/**
+ * alien_py_cloud production deploy (canonical Jenkinsfile at repo root)
+ *
+ * Jenkins: 39.106.135.88 | Target: 39.105.153.68
+ * Job Script Path: Jenkinsfile
+ *
+ */
+
+def DEFAULT_PROD_SSH_TARGET = 'alien_store@39.105.153.68'
+def DEFAULT_PROD_SSH_CREDENTIALS_ID = 'e611a045-2fdc-4613-babd-a72d69bf9814'
+
+pipeline {
+  agent any
+
+  options {
+    buildDiscarder(logRotator(numToKeepStr: '10'))
+    timestamps()
+  }
+
+  parameters {
+    string(name: 'PROD_SSH_TARGET', defaultValue: DEFAULT_PROD_SSH_TARGET,
+      description: 'Production host SSH target')
+    string(name: 'PROD_SSH_CREDENTIALS_ID', defaultValue: DEFAULT_PROD_SSH_CREDENTIALS_ID,
+      description: 'Jenkins SSH Username with private key credential ID')
+    string(name: 'GIT_BRANCH', defaultValue: 'produ',
+      description: 'alien_py_cloud branch to deploy')
+  }
+
+  environment {
+    CODE_DIR_REMOTE = '/alien_produ/python/alien_py_cloud'
+    ENV_FILE_REMOTE = '/alien_produ/python/alien_py_cloud/.env.produ'
+    LOG_ROOT_REMOTE = '/alien_produ/python/alien_py_cloud/logs'
+
+    IMAGE_STORE    = 'alien_store:local'
+    IMAGE_GATEWAY  = 'alien_gateway:local'
+    IMAGE_CONTRACT = 'alien_contract:local'
+
+    CONTAINER_NAME_STORE    = 'alien_store_produ'
+    CONTAINER_NAME_GATEWAY  = 'alien_gateway_produ'
+    CONTAINER_NAME_CONTRACT = 'alien_contract_produ'
+
+    PORT_STORE_INTERNAL    = '48001'
+    PORT_GATEWAY_INTERNAL  = '43333'
+    PORT_CONTRACT_INTERNAL = '8002'
+    PORT_GATEWAY_HOST      = '33333'
+    PORT_CONTRACT_HOST     = '8002'
+
+    DOCKER_NET = 'alien_net_produ'
+  }
+
+  stages {
+    stage('Verify SSH') {
+      steps {
+        script {
+          def sshTarget = (params.PROD_SSH_TARGET ?: DEFAULT_PROD_SSH_TARGET).trim()
+          def credId = (params.PROD_SSH_CREDENTIALS_ID ?: DEFAULT_PROD_SSH_CREDENTIALS_ID).trim()
+          env.SSH_TARGET = sshTarget
+          env.SSH_CRED_ID = credId
+          sshagent(credentials: [credId]) {
+            sh """
+              set -e
+              ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${sshTarget}' \\
+                'test -f ${ENV_FILE_REMOTE} && sudo docker info >/dev/null'
+              echo ">>> SSH OK: ${sshTarget}"
+            """
+          }
+        }
+      }
+    }
+
+    stage('Git Pull on Production') {
+      steps {
+        sshagent(credentials: [env.SSH_CRED_ID]) {
+          sh """
+            set -e
+            ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${env.SSH_TARGET}' bash -s <<'REMOTE_EOF'
+set -e
+cd '${CODE_DIR_REMOTE}'
+if [ ! -d .git ]; then
+  echo "ERROR: ${CODE_DIR_REMOTE} is not a git repo. Clone manually first."
+  exit 1
+fi
+git fetch origin
+git checkout '${params.GIT_BRANCH}'
+git pull origin '${params.GIT_BRANCH}'
+echo ">>> git at \$(git rev-parse --short HEAD) on \$(hostname)"
+REMOTE_EOF
+          """
+        }
+      }
+    }
+
+    stage('Build Images on Production') {
+      steps {
+        sshagent(credentials: [env.SSH_CRED_ID]) {
+          sh """
+            set -e
+            ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${env.SSH_TARGET}' bash -s <<'REMOTE_EOF'
+set -e
+cd '${CODE_DIR_REMOTE}'
+sudo docker build -f alien_store/Dockerfile -t ${IMAGE_STORE} .
+sudo docker build -f alien_gateway/Dockerfile -t ${IMAGE_GATEWAY} .
+sudo docker build -f alien_contract/Dockerfile -t ${IMAGE_CONTRACT} .
+echo ">>> images built on \$(hostname)"
+sudo docker images | grep -E 'alien_store|alien_gateway|alien_contract' | head -10
+REMOTE_EOF
+          """
+        }
+      }
+    }
+
+    stage('Deploy on Production') {
+      steps {
+        sshagent(credentials: [env.SSH_CRED_ID]) {
+          sh """
+            set -e
+            ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${env.SSH_TARGET}' bash -s <<'REMOTE_EOF'
+set -e
+sudo docker network create ${DOCKER_NET} 2>/dev/null || true
+mkdir -p ${LOG_ROOT_REMOTE}/store ${LOG_ROOT_REMOTE}/gateway ${LOG_ROOT_REMOTE}/contract
+
+sudo docker rm -f ${CONTAINER_NAME_STORE} ${CONTAINER_NAME_GATEWAY} ${CONTAINER_NAME_CONTRACT} 2>/dev/null || true
+
+sudo docker run -d --name ${CONTAINER_NAME_STORE} \\
+  --network ${DOCKER_NET} \\
+  --env-file ${ENV_FILE_REMOTE} \\
+  -v ${ENV_FILE_REMOTE}:/app/.env.produ:ro \\
+  -v ${LOG_ROOT_REMOTE}/store:/app/common/logs/alien_store \\
+  --restart unless-stopped \\
+  ${IMAGE_STORE}
+
+sudo docker run -d --name ${CONTAINER_NAME_CONTRACT} \\
+  --network ${DOCKER_NET} \\
+  -p ${PORT_CONTRACT_HOST}:${PORT_CONTRACT_INTERNAL} \\
+  --env-file ${ENV_FILE_REMOTE} \\
+  -v ${ENV_FILE_REMOTE}:/app/.env.produ:ro \\
+  -v ${LOG_ROOT_REMOTE}/contract:/app/common/logs/alien_contract \\
+  --restart unless-stopped \\
+  ${IMAGE_CONTRACT}
+
+sudo docker run -d --name ${CONTAINER_NAME_GATEWAY} \\
+  --network ${DOCKER_NET} \\
+  -p ${PORT_GATEWAY_HOST}:${PORT_GATEWAY_INTERNAL} \\
+  --env-file ${ENV_FILE_REMOTE} \\
+  -v ${ENV_FILE_REMOTE}:/app/.env.produ:ro \\
+  -v ${LOG_ROOT_REMOTE}/gateway:/app/common/logs/alien_gateway \\
+  -e STORE_BASE_URL=http://${CONTAINER_NAME_STORE}:${PORT_STORE_INTERNAL} \\
+  --restart unless-stopped \\
+  ${IMAGE_GATEWAY}
+
+sleep 3
+curl -sf http://127.0.0.1:${PORT_GATEWAY_HOST}/health || (echo 'gateway /health failed' && exit 1)
+curl -sf http://127.0.0.1:${PORT_CONTRACT_HOST}/health || (echo 'contract /health failed' && exit 1)
+sudo docker ps --filter name=${CONTAINER_NAME_STORE} --filter name=${CONTAINER_NAME_GATEWAY} --filter name=${CONTAINER_NAME_CONTRACT}
+REMOTE_EOF
+          """
+        }
+      }
+    }
+  }
+
+  post {
+    success {
+      echo ">>> alien_py_cloud deployed on ${env.SSH_TARGET}"
+    }
+    failure {
+      echo '>>> failed: check SSH, .env.produ, sudo docker, and remote git path'
+    }
+    always {
+      cleanWs()
+    }
+  }
+}

+ 4 - 19
docs/jenkins/Jenkinsfile-alien-py-cloud-produ.groovy

@@ -1,26 +1,13 @@
-/**
- * alien_py_cloud production deploy
+/**
+ * alien_py_cloud production deploy (canonical Jenkinsfile at repo root)
  *
- * Jenkins: Docker on 39.106.135.88 (UAT/management)
- * Target:  39.105.153.68 (production Docker host)
+ * Jenkins: 39.106.135.88 | Target: 39.105.153.68
+ * Job Script Path: Jenkinsfile
  *
- * Job setup:
- *   - Pipeline script from SCM -> alien_py_cloud, branch produ,
- *     Script Path: docs/jenkins/Jenkinsfile-alien-py-cloud-produ.groovy
- *   - OR paste this entire file into "Pipeline script" (not recommended for long-term)
- *
- * Prerequisites on 39.105.153.68:
- *   - Git repo: /alien_produ/python/alien_py_cloud (branch produ)
- *   - /alien_produ/python/alien_py_cloud/.env.produ (not in Git)
- *   - alien_store user: sudo docker without password; SSH key in Jenkins credentials
- *   - Nginx on prod.ailien.shop:
- *       /api/contract/ -> 127.0.0.1:8002
- *       /api/store/    -> 127.0.0.1:33333
  */
 
 def DEFAULT_PROD_SSH_TARGET = 'alien_store@39.105.153.68'
 def DEFAULT_PROD_SSH_CREDENTIALS_ID = 'e611a045-2fdc-4613-babd-a72d69bf9814'
-def DEFAULT_GIT_CREDENTIALS_ID = '5e058e17-8089-45e0-a802-596d91758b4d'
 
 pipeline {
   agent any
@@ -44,8 +31,6 @@ pipeline {
     ENV_FILE_REMOTE = '/alien_produ/python/alien_py_cloud/.env.produ'
     LOG_ROOT_REMOTE = '/alien_produ/python/alien_py_cloud/logs'
 
-    GIT_URL = 'http://8.152.195.41:3000/alien/alien_py_cloud'
-
     IMAGE_STORE    = 'alien_store:local'
     IMAGE_GATEWAY  = 'alien_gateway:local'
     IMAGE_CONTRACT = 'alien_contract:local'