Jenkinsfile 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /**
  2. * alien_py_cloud production deploy (canonical Jenkinsfile at repo root)
  3. *
  4. * Jenkins: 39.106.135.88 | Target: 39.105.153.68
  5. * Job Script Path: Jenkinsfile
  6. *
  7. */
  8. def DEFAULT_PROD_SSH_TARGET = 'alien_store@39.105.153.68'
  9. def DEFAULT_PROD_SSH_CREDENTIALS_ID = 'e611a045-2fdc-4613-babd-a72d69bf9814'
  10. pipeline {
  11. agent any
  12. options {
  13. buildDiscarder(logRotator(numToKeepStr: '10'))
  14. timestamps()
  15. }
  16. parameters {
  17. string(name: 'PROD_SSH_TARGET', defaultValue: DEFAULT_PROD_SSH_TARGET,
  18. description: 'Production host SSH target')
  19. string(name: 'PROD_SSH_CREDENTIALS_ID', defaultValue: DEFAULT_PROD_SSH_CREDENTIALS_ID,
  20. description: 'Jenkins SSH Username with private key credential ID')
  21. string(name: 'GIT_BRANCH', defaultValue: 'produ',
  22. description: 'alien_py_cloud branch to deploy')
  23. }
  24. environment {
  25. CODE_DIR_REMOTE = '/alien_produ/python/alien_py_cloud'
  26. ENV_FILE_REMOTE = '/alien_produ/python/alien_py_cloud/.env.produ'
  27. LOG_ROOT_REMOTE = '/alien_produ/python/alien_py_cloud/logs'
  28. IMAGE_STORE = 'alien_store:local'
  29. IMAGE_GATEWAY = 'alien_gateway:local'
  30. IMAGE_CONTRACT = 'alien_contract:local'
  31. CONTAINER_NAME_STORE = 'alien_store_produ'
  32. CONTAINER_NAME_GATEWAY = 'alien_gateway_produ'
  33. CONTAINER_NAME_CONTRACT = 'alien_contract_produ'
  34. PORT_STORE_INTERNAL = '48001'
  35. PORT_GATEWAY_INTERNAL = '43333'
  36. PORT_CONTRACT_INTERNAL = '8002'
  37. PORT_GATEWAY_HOST = '33333'
  38. PORT_CONTRACT_HOST = '8002'
  39. DOCKER_NET = 'alien_net_produ'
  40. }
  41. stages {
  42. stage('Verify SSH') {
  43. steps {
  44. script {
  45. def sshTarget = (params.PROD_SSH_TARGET ?: DEFAULT_PROD_SSH_TARGET).trim()
  46. def credId = (params.PROD_SSH_CREDENTIALS_ID ?: DEFAULT_PROD_SSH_CREDENTIALS_ID).trim()
  47. env.SSH_TARGET = sshTarget
  48. env.SSH_CRED_ID = credId
  49. sshagent(credentials: [credId]) {
  50. sh """
  51. set -e
  52. ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${sshTarget}' \\
  53. 'test -f ${ENV_FILE_REMOTE} && sudo docker info >/dev/null'
  54. echo ">>> SSH OK: ${sshTarget}"
  55. """
  56. }
  57. }
  58. }
  59. }
  60. stage('Git Pull on Production') {
  61. steps {
  62. sshagent(credentials: [env.SSH_CRED_ID]) {
  63. sh """
  64. set -e
  65. ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${env.SSH_TARGET}' bash -s <<'REMOTE_EOF'
  66. set -e
  67. cd '${CODE_DIR_REMOTE}'
  68. if [ ! -d .git ]; then
  69. echo "ERROR: ${CODE_DIR_REMOTE} is not a git repo. Clone manually first."
  70. exit 1
  71. fi
  72. git fetch origin
  73. git checkout '${params.GIT_BRANCH}'
  74. git pull origin '${params.GIT_BRANCH}'
  75. echo ">>> git at \$(git rev-parse --short HEAD) on \$(hostname)"
  76. REMOTE_EOF
  77. """
  78. }
  79. }
  80. }
  81. stage('Build Images on Production') {
  82. steps {
  83. sshagent(credentials: [env.SSH_CRED_ID]) {
  84. sh """
  85. set -e
  86. ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${env.SSH_TARGET}' bash -s <<'REMOTE_EOF'
  87. set -e
  88. cd '${CODE_DIR_REMOTE}'
  89. sudo docker build -f alien_store/Dockerfile -t ${IMAGE_STORE} .
  90. sudo docker build -f alien_gateway/Dockerfile -t ${IMAGE_GATEWAY} .
  91. sudo docker build -f alien_contract/Dockerfile -t ${IMAGE_CONTRACT} .
  92. echo ">>> images built on \$(hostname)"
  93. sudo docker images | grep -E 'alien_store|alien_gateway|alien_contract' | head -10
  94. REMOTE_EOF
  95. """
  96. }
  97. }
  98. }
  99. stage('Deploy on Production') {
  100. steps {
  101. sshagent(credentials: [env.SSH_CRED_ID]) {
  102. sh """
  103. set -e
  104. ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${env.SSH_TARGET}' bash -s <<'REMOTE_EOF'
  105. set -e
  106. sudo docker network create ${DOCKER_NET} 2>/dev/null || true
  107. mkdir -p ${LOG_ROOT_REMOTE}/store ${LOG_ROOT_REMOTE}/gateway ${LOG_ROOT_REMOTE}/contract
  108. sudo docker rm -f ${CONTAINER_NAME_STORE} ${CONTAINER_NAME_GATEWAY} ${CONTAINER_NAME_CONTRACT} 2>/dev/null || true
  109. sudo docker run -d --name ${CONTAINER_NAME_STORE} \\
  110. --network ${DOCKER_NET} \\
  111. --env-file ${ENV_FILE_REMOTE} \\
  112. -v ${ENV_FILE_REMOTE}:/app/.env.produ:ro \\
  113. -v ${LOG_ROOT_REMOTE}/store:/app/common/logs/alien_store \\
  114. --restart unless-stopped \\
  115. ${IMAGE_STORE}
  116. sudo docker run -d --name ${CONTAINER_NAME_CONTRACT} \\
  117. --network ${DOCKER_NET} \\
  118. -p ${PORT_CONTRACT_HOST}:${PORT_CONTRACT_INTERNAL} \\
  119. --env-file ${ENV_FILE_REMOTE} \\
  120. -v ${ENV_FILE_REMOTE}:/app/.env.produ:ro \\
  121. -v ${LOG_ROOT_REMOTE}/contract:/app/common/logs/alien_contract \\
  122. --restart unless-stopped \\
  123. ${IMAGE_CONTRACT}
  124. sudo docker run -d --name ${CONTAINER_NAME_GATEWAY} \\
  125. --network ${DOCKER_NET} \\
  126. -p ${PORT_GATEWAY_HOST}:${PORT_GATEWAY_INTERNAL} \\
  127. --env-file ${ENV_FILE_REMOTE} \\
  128. -v ${ENV_FILE_REMOTE}:/app/.env.produ:ro \\
  129. -v ${LOG_ROOT_REMOTE}/gateway:/app/common/logs/alien_gateway \\
  130. -e STORE_BASE_URL=http://${CONTAINER_NAME_STORE}:${PORT_STORE_INTERNAL} \\
  131. --restart unless-stopped \\
  132. ${IMAGE_GATEWAY}
  133. sleep 3
  134. curl -sf http://127.0.0.1:${PORT_GATEWAY_HOST}/health || (echo 'gateway /health failed' && exit 1)
  135. curl -sf http://127.0.0.1:${PORT_CONTRACT_HOST}/health || (echo 'contract /health failed' && exit 1)
  136. sudo docker ps --filter name=${CONTAINER_NAME_STORE} --filter name=${CONTAINER_NAME_GATEWAY} --filter name=${CONTAINER_NAME_CONTRACT}
  137. REMOTE_EOF
  138. """
  139. }
  140. }
  141. }
  142. }
  143. post {
  144. success {
  145. echo ">>> alien_py_cloud deployed on ${env.SSH_TARGET}"
  146. }
  147. failure {
  148. echo '>>> failed: check SSH, .env.produ, sudo docker, and remote git path'
  149. }
  150. always {
  151. cleanWs()
  152. }
  153. }
  154. }