Jenkinsfile 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #!/usr/bin/env groovy
  2. pipeline {
  3. agent any
  4. // using the Timestamps plugin we can add timestamps to the console log
  5. options {
  6. timestamps()
  7. }
  8. environment {
  9. GROUPID = readMavenPom().getGroupId()//com.storlead
  10. ARTIFACTID = readMavenPom().getArtifactId()//sp-salary-management
  11. VERSION = readMavenPom().getVersion()//1.0
  12. }
  13. // 参数
  14. parameters {
  15. choice(
  16. name: 'modulePrefix',
  17. choices: 'api\nui',
  18. description: '选择要部署 API or UI'
  19. )
  20. choice(
  21. name: 'module',
  22. choices: 'sp-salary-management',
  23. description: '选择要部署的项目'
  24. )
  25. choice(
  26. name: 'profile',
  27. choices: ['test', 'prod'],
  28. description: '选择要部署的配置文件'
  29. )
  30. }
  31. stages {
  32. stage('处理参数') {
  33. steps {
  34. script {
  35. echo "处理参数"
  36. script {
  37. //服务器配置
  38. SERVER_SSH_PORT = 53023
  39. SERVER_HOST = "node1.storlead.com"
  40. SWARM_INIT_REPLICAS_NUM = 1
  41. //服务配置
  42. API_PORT = 8703
  43. API_REMOTE_DEBUG_PORT = 8006
  44. API_NAMESPACE_RESTFUL = "api"
  45. //DOCKER配置
  46. DOCKER_REGISTRY = "reg-aliyun"
  47. DOCKER_HOST = "registry.cn-shenzhen.aliyuncs.com"
  48. //Docker私服登陆url https://registry-vpc.cn-shenzhen.aliyuncs.com
  49. DOCKER_LOGIN_REGISTRY = "https://${DOCKER_HOST}"
  50. BUILD_PREFIX = "storlead-huawei"
  51. //镜像完整名称 registry-vpc.cn-shenzhen.aliyuncs.com/sp-salary-management-prod:1.0
  52. DOCKER_IMG_NAME = "${DOCKER_HOST}/${BUILD_PREFIX}/${ARTIFACTID}-${params.profile}:${VERSION}"
  53. //镜像名 sp-salary-management-prod:1.0
  54. IMG_NAME = "${BUILD_PREFIX}/${params.module}-${params.profile}:${VERSION}"
  55. PUSH_DOCK_IMG = true
  56. if (params.profile == "dev-local") {
  57. SERVER_HOST = "192.168.1.101"
  58. SERVER_SSH_PORT = 22
  59. API_PORT = 8701
  60. API_REMOTE_DEBUG_PORT = 8704
  61. DOCKER_HOST = "192.168.1.101:5000"
  62. DOCKER_LOGIN_REGISTRY = "http://${DOCKER_HOST}"
  63. DOCKER_IMG_NAME = "${DOCKER_HOST}/${BUILD_PREFIX}/${ARTIFACTID}-${params.profile}:${VERSION}"
  64. }
  65. if (params.profile == "test") {
  66. SERVER_HOST = "test1.storlead.com"
  67. API_PORT = 8702
  68. API_REMOTE_DEBUG_PORT = 8705
  69. }
  70. if (params.profile == "prod") {
  71. SERVER_HOST = "110.41.82.21"
  72. API_PORT = 8703
  73. API_REMOTE_DEBUG_PORT = 8706
  74. }
  75. }
  76. }
  77. }
  78. }
  79. stage('Node 编译') {
  80. when {
  81. environment name: 'modulePrefix', value: 'ui'
  82. }
  83. agent {
  84. docker {
  85. image "registry.cn-shenzhen.aliyuncs.com/storlead/node:10-alpine-npm"
  86. args '-v /app:/app/:z -v /etc/localtime:/etc/localtime:ro -u root'
  87. reuseNode true
  88. }
  89. }
  90. steps {
  91. withCredentials([
  92. usernamePassword(credentialsId: 'storleadHW', usernameVariable: 'usernameHW', passwordVariable: 'passwordHW'),
  93. usernamePassword(credentialsId: 'storlead', usernameVariable: 'username', passwordVariable: 'password')
  94. ]) {
  95. script {
  96. echo "发布 UI 代码"
  97. def remote = [:]
  98. remote.allowAnyHosts = true
  99. remote.name = "${SERVER_HOST}"
  100. remote.host = "${SERVER_HOST}"
  101. remote.port = 53023
  102. remote.user = username
  103. remote.password = password
  104. if (params.profile == "prod") {
  105. remote.port = 22
  106. remote.user = "root"
  107. remote.user = usernameHW
  108. remote.password = passwordHW
  109. }
  110. sh """cd ${params.modulePrefix}/${params.module} && npm install && npm run ${params.profile}"""
  111. sshCommand remote: remote, command: "mkdir -p /app/sp/ui/sp-salary-management"
  112. sshCommand remote: remote, command: "rm -rf /app/sp/ui/sp-salary-management/*"
  113. sshPut remote: remote, from: "${params.modulePrefix}/${params.module}/www/", into: "/app/sp/ui/sp-salary-management/"
  114. sshCommand remote: remote, command: "cp -rf /app/sp/ui/sp-salary-management/www/* /app/sp/ui/sp-salary-management/"
  115. }
  116. }
  117. }
  118. }
  119. stage('Maven 编译') {
  120. when {
  121. environment name: 'modulePrefix', value: 'api'
  122. }
  123. agent {
  124. docker {
  125. image 'maven:3-amazoncorretto-11'
  126. //让docker 使用 host 宿主机的 m2仓库 使用root用户来运行 以让指定的~/.m2/config/setting.xml 阿里加速下载maven 依赖生效
  127. args '-v /app:/app:z -v $HOME/.m2:/root/.m2:z -u root'
  128. reuseNode true
  129. }
  130. }
  131. steps {
  132. echo "编译 API 代码"
  133. sh "mvn clean package -U -am -pl ${modulePrefix}/${params.module} -P${params.profile} -Dmaven.test.skip=true"
  134. }
  135. }
  136. // 项目打包到镜像并推送到镜像仓库
  137. stage('构建Docker镜像') {
  138. when {
  139. environment name: 'modulePrefix', value: 'api'
  140. }
  141. steps {
  142. echo "构建Dcoker镜像"
  143. script {
  144. docker.withRegistry(DOCKER_LOGIN_REGISTRY, DOCKER_REGISTRY) {
  145. // BASE_IMAGE = 'registry.cn-shenzhen.aliyuncs.com/storlead/centos7-openjdk8:latest'
  146. // BASE_IMAGE = 'amazoncorretto:11-alpine'
  147. // BASE_IMAGE = 'blankhang/alpine-3.12:openjdk11'
  148. BASE_IMAGE = 'registry.cn-shenzhen.aliyuncs.com/storlead/openjdk:11'
  149. //获取最新的镜像底包
  150. sh "docker pull ${BASE_IMAGE}"
  151. sh """
  152. echo '
  153. FROM ${BASE_IMAGE}
  154. COPY ${modulePrefix}/${params.module}/target/${params.module}-${VERSION}.jar app.jar
  155. EXPOSE ${API_PORT}
  156. EXPOSE ${API_REMOTE_DEBUG_PORT}
  157. HEALTHCHECK --interval=1m --timeout=10s CMD curl -f http://localhost:${API_PORT}/${API_NAMESPACE_RESTFUL}/actuator/health
  158. ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-Djava.awt.headless=true","-Dspring.profiles.active=${params.profile}", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:${API_REMOTE_DEBUG_PORT}","-jar","/app.jar"]' > Dockerfile
  159. docker build -t ${DOCKER_IMG_NAME} .
  160. """
  161. sh "docker push ${DOCKER_IMG_NAME}"
  162. }
  163. }
  164. }
  165. }
  166. stage('启动服务') {
  167. when {
  168. environment name: 'modulePrefix', value: 'api'
  169. }
  170. steps {
  171. withCredentials([
  172. usernamePassword(credentialsId: 'storleadHW', usernameVariable: 'usernameHW', passwordVariable: 'passwordHW'),
  173. usernamePassword(credentialsId: 'storlead', usernameVariable: 'username', passwordVariable: 'password'),
  174. usernamePassword(credentialsId: 'reg-aliyun', usernameVariable: 'aliUsername', passwordVariable: 'aliPassword'),
  175. ]) {
  176. script {
  177. echo "启动服务"
  178. def remote = [:]
  179. remote.name = "${SERVER_HOST}"
  180. remote.host = "${SERVER_HOST}"
  181. remote.port = 53023
  182. remote.user = username
  183. remote.password = password
  184. remote.allowAnyHosts = true
  185. //因为使用 docker swarm 发布 只能在 manage node 执行部署
  186. if (params.profile == "dev") {
  187. remote.port = 22
  188. remote.user = "root"
  189. }
  190. if (params.profile == "prod") {
  191. remote.port = 22
  192. remote.user = "root"
  193. remote.user = usernameHW
  194. remote.password = passwordHW
  195. }
  196. if (PUSH_DOCK_IMG) {
  197. //docker 认证
  198. sshCommand remote: remote, command: "docker login -u ${aliUsername} -p ${aliPassword} ${DOCKER_LOGIN_REGISTRY}"
  199. //如果选择推送才使用远程的版本 如果不选择推送到远程则直接运行本机刚打包的镜像版本即可
  200. sshCommand remote: remote, command: "docker pull ${DOCKER_IMG_NAME}"
  201. }
  202. sh """
  203. echo '
  204. version: "3.7"
  205. services:
  206. ${ARTIFACTID}-${params.profile}:
  207. image: ${DOCKER_IMG_NAME}
  208. restart: always
  209. deploy:
  210. replicas: ${SWARM_INIT_REPLICAS_NUM}
  211. update_config:
  212. parallelism: 1
  213. delay: 1m
  214. restart_policy:
  215. condition: on-failure
  216. # 最多连续重试3次如果仍然失败则放弃重试
  217. max_attempts: 3
  218. healthcheck:
  219. test: ["CMD", "curl", "-f", "http://localhost:${API_PORT}/${API_NAMESPACE_RESTFUL}/actuator/health"]
  220. interval: 1m
  221. timeout: 5s
  222. retries: 3
  223. start_period: 30s
  224. environment:
  225. - "TZ=Asia/Shanghai"
  226. - "SPRING_PROFILES_ACTIVE=${params.profile}"
  227. volumes:
  228. - /app:/app
  229. ports:
  230. - "${API_PORT}:${API_PORT}"
  231. - "${API_REMOTE_DEBUG_PORT}:${API_REMOTE_DEBUG_PORT}"
  232. networks:
  233. - ${ARTIFACTID}
  234. extra_hosts:
  235. - "www.storlead.com:172.18.194.161"
  236. - "node1:110.41.82.21"
  237. - "node2:110.41.174.46"
  238. - "node3:121.37.226.174"
  239. - "test1.storlead.com:172.18.194.168"
  240. - "test2.storlead.com:172.18.194.163"
  241. networks:
  242. ${ARTIFACTID}:
  243. driver: overlay
  244. attachable: true
  245. ' > ${ARTIFACTID}-${params.profile}-stack.yml
  246. """
  247. sshPut remote: remote, from: "${ARTIFACTID}-${params.profile}-stack.yml", into: "/docker/sp/${ARTIFACTID}-${params.profile}-stack.yml"
  248. sshCommand remote: remote, command: "docker stack deploy --resolve-image=always --with-registry-auth -c /docker/sp/${ARTIFACTID}-${params.profile}-stack.yml ${ARTIFACTID}-${params.profile}"
  249. }
  250. }
  251. }
  252. }
  253. }
  254. }