|
@@ -1,100 +1,208 @@
|
|
|
-pipeline {
|
|
|
- agent any
|
|
|
+// ==================== ↓↓↓↓↓↓ docker ↓↓↓↓↓↓ ====================
|
|
|
+// 镜像仓库地址
|
|
|
+def DOCKER_REGISTRY_URL = "registry.cn-shanghai.aliyuncs.com"
|
|
|
+// 镜像仓库命名空间名称
|
|
|
+def DOCKER_REGISTRY_NAMESPACE = "advich-group"
|
|
|
+// 镜像拉取凭证 => jenkins全局凭证中配置
|
|
|
+def DOCKER_REGISTRY_AUTH = "aliyun_docker_registry"
|
|
|
|
|
|
- tools {
|
|
|
- maven 'Maven-3.8.5'
|
|
|
- jdk 'JDK8'
|
|
|
- }
|
|
|
|
|
|
- parameters {
|
|
|
- choice(name: 'ENV', choices: ['prod'], description: '部署环境')
|
|
|
- choice(name: 'SERVICE', choices: ['gateway', 'work', 'oa', 'authorization', 'admin', 'bi', 'crm', 'job', 'examine', 'hrm'], description: '选择要部署的微服务')
|
|
|
+// ==================== ↓↓↓↓↓↓ git ↓↓↓↓↓↓ ====================
|
|
|
+// git凭证 => jenkins全局凭证中配置
|
|
|
+def GIT_AUTH = "git_auth"
|
|
|
+
|
|
|
+
|
|
|
+// ==================== ↓↓↓↓↓↓ project ↓↓↓↓↓↓ ====================
|
|
|
+// 项目-git地址
|
|
|
+def PROJECT_GIT_URL = "https://git.dev.advichcloud.com/wangfan/weichi-crm-server.git"
|
|
|
+// 项目-公共模块名称
|
|
|
+def PROJECT_SERVICE_COMMON_NAME = "core"
|
|
|
+// 项目-基础目录
|
|
|
+def PROJECT_BASE_HOME = "/home/app/weichi-crm-server"
|
|
|
+// 项目-服务日志目录
|
|
|
+def PROJECT_SERVICE_LOG_HOME = "${PROJECT_BASE_HOME}/logs"
|
|
|
+// 项目-jar文件目录
|
|
|
+def PROJECT_JAR_HOME = "${PROJECT_BASE_HOME}/target"
|
|
|
+// 项目-docker部署的历史jar目录
|
|
|
+def PROJECT_DOCKER_HISTORY_JAR_HOME = "${PROJECT_BASE_HOME}/docker-history-jar"
|
|
|
+
|
|
|
+
|
|
|
+node {
|
|
|
+ // jenkins工作空间
|
|
|
+ def JENKINS_WORKSPACE = "${WORKSPACE}"
|
|
|
+ // 取哪一块网卡值
|
|
|
+ def ETH_VALUE = ""
|
|
|
+ // 当前时间
|
|
|
+ def CURRENT_TIME = ""
|
|
|
+ // 获取选择的项目服务名称
|
|
|
+ def PROJECT_SERVICE_NAME_SELECT = "${PROJECT_SERVICE_NAME}".split(",")
|
|
|
+ // 获取选择的服务器名称
|
|
|
+ def PUBLISH_SSH_SERVER_SELECT = "${PUBLISH_SSH_SERVER}".split(",")
|
|
|
+ // git分支tag
|
|
|
+ def GIT_BRANCH_TAG = ""
|
|
|
+ // docker镜像仓库认证命令
|
|
|
+ def DOCKER_REGISTRY_AUTH_CMD = ""
|
|
|
+
|
|
|
+ stage('初始化准备') {
|
|
|
+ echo '****************************** 初始化准备 ******************************'
|
|
|
+ // 网卡值设置 [注:正常liunx取eth0的内网ip,局域网取enp5s0的内网ip]
|
|
|
+ ETH_VALUE = sh(script: "( [[ \"${JAVA_OPTS}\" = *'-Dspring.cloud.nacos.discovery.ip'* ]] && echo enp5s0 || echo eth0 )", returnStdout: true).trim()
|
|
|
+ CURRENT_TIME = sh(script: "echo `date +\"%Y-%m-%d %H:%M:%S\"`", returnStdout: true).trim()
|
|
|
+ script {
|
|
|
+ GIT_BRANCH_TAG = GIT_BRANCH.replaceAll('origin/', '')
|
|
|
+ }
|
|
|
+ echo "当前工作空间:${JENKINS_WORKSPACE}"
|
|
|
+ echo "使用分支:${GIT_BRANCH}"
|
|
|
+ echo "使用分支tag:${GIT_BRANCH_TAG}"
|
|
|
+ echo "使用网卡:${ETH_VALUE}"
|
|
|
+ echo "是否跳过构建,直接运行docker容器(tips:适用于之前已经进行过构建打包的情景):${IS_SKIP_BUILD}"
|
|
|
+ echo "当前时间:${CURRENT_TIME}"
|
|
|
+ sh "mkdir -p ${PROJECT_SERVICE_LOG_HOME}"
|
|
|
+ sh "mkdir -p ${PROJECT_JAR_HOME}"
|
|
|
+ sh "mkdir -p ${PROJECT_DOCKER_HISTORY_JAR_HOME}"
|
|
|
+
|
|
|
+ echo '****************************** 镜像仓库认证 ******************************'
|
|
|
+
|
|
|
+ withCredentials([usernamePassword(credentialsId: "${DOCKER_REGISTRY_AUTH}", passwordVariable: 'password', usernameVariable: 'username')]) {
|
|
|
+ // 登录镜像仓库
|
|
|
+ DOCKER_REGISTRY_AUTH_CMD = "docker login -u ${username} -p ${password} ${DOCKER_REGISTRY_URL}"
|
|
|
+ sh "${DOCKER_REGISTRY_AUTH_CMD}"
|
|
|
+ }
|
|
|
}
|
|
|
- environment {
|
|
|
- DOCKER_REGISTRY = "registry.cn-shanghai.aliyuncs.com"
|
|
|
- DOCKER_NAMESPACE = "advich-group"
|
|
|
- DOCKER_REPO = "weichi-crm-${params.SERVICE}"
|
|
|
- DOCKER_IMAGE = "${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/${DOCKER_REPO}:latest"
|
|
|
- PROJECT_SERVICE_COMMON_NAME = "core"
|
|
|
+
|
|
|
+
|
|
|
+ stage('拉取代码') {
|
|
|
+ echo '****************************** 拉取代码 ******************************'
|
|
|
+ checkout([$class: 'GitSCM', branches: [[name: "${GIT_BRANCH}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${GIT_AUTH}", url: "${PROJECT_GIT_URL}"]]])
|
|
|
+ sh "pwd"
|
|
|
}
|
|
|
|
|
|
- stages {
|
|
|
- stage('拉取Git代码') {
|
|
|
- steps {
|
|
|
- checkout scmGit(branches: [[name: '${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: 'fb3553e7-6ea6-4f34-92a0-6ba34a71c5b5', url: 'https://git.dev.advichcloud.com/wangfan/weichi-crm-server.git']])
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- stage('公共工程打包') {
|
|
|
- steps {
|
|
|
- script {
|
|
|
- echo '****************************** 公共工程打包 ******************************'
|
|
|
- sh """
|
|
|
- mvn -f ${PROJECT_SERVICE_COMMON_NAME} clean install -Dmaven.test.skip=true
|
|
|
- """
|
|
|
- }
|
|
|
- }
|
|
|
+ stage('公共工程打包') {
|
|
|
+ if ("${IS_SKIP_BUILD}" == "true") {
|
|
|
+ echo '****************************** 公共工程打包 - 跳过 ******************************'
|
|
|
+ } else {
|
|
|
+ echo '****************************** 公共工程打包 ******************************'
|
|
|
+ sh "mvn -f ${PROJECT_SERVICE_COMMON_NAME} clean install -Dmaven.test.skip=true"
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ stage('微服务打包&删除旧容器和镜像&推送镜像&部署远程服务器') {
|
|
|
+ echo '****************************** 微服务打包&删除旧容器和镜像&推送镜像&部署远程服务器 ******************************'
|
|
|
+
|
|
|
+ for (int i = 0; i < PROJECT_SERVICE_NAME_SELECT.length; i++) {
|
|
|
+
|
|
|
+ // 当前待处理项目
|
|
|
+ def current_app_name = PROJECT_SERVICE_NAME_SELECT[i];
|
|
|
+ def current_app_jar = "${current_app_name}.jar";
|
|
|
+ // 父工程
|
|
|
+ def current_app_parent = ""
|
|
|
+ // 端口号
|
|
|
+ def current_app_port = ""
|
|
|
+
|
|
|
+ echo "当前操作项目: ${current_app_name}"
|
|
|
|
|
|
- stage('微服务工程打包') {
|
|
|
- steps {
|
|
|
- script {
|
|
|
- echo '****************************** 微服务工程打包 ******************************'
|
|
|
- sh "mvn -f ${params.SERVICE} clean install -Dmaven.test.skip=true"
|
|
|
+ script {
|
|
|
+ switch (current_app_name) {
|
|
|
+ case "admin":
|
|
|
+ current_app_parent = ""
|
|
|
+ current_app_port = "60667"
|
|
|
+ break
|
|
|
+ case "gateway":
|
|
|
+ current_app_port = "8443"
|
|
|
+ current_app_parent = ""
|
|
|
+ break
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- stage('Build and Push Docker Image') {
|
|
|
- steps {
|
|
|
- script {
|
|
|
- withCredentials([usernamePassword(
|
|
|
- credentialsId: '6ec7fc8d-859f-43ba-8ebc-337bedec055b',
|
|
|
- usernameVariable: 'REGISTRY_USERNAME',
|
|
|
- passwordVariable: 'REGISTRY_PASSWORD'
|
|
|
- )]) {
|
|
|
- sh """
|
|
|
- cd ${params.SERVICE}
|
|
|
- echo "\${REGISTRY_PASSWORD}" | docker login ${DOCKER_REGISTRY} -u \${REGISTRY_USERNAME} --password-stdin
|
|
|
- docker build -t ${DOCKER_IMAGE} .
|
|
|
- docker push ${DOCKER_IMAGE}
|
|
|
- """
|
|
|
- }
|
|
|
- }
|
|
|
+ echo "当前操作项目: ${current_app_name} 端口:${current_app_port}"
|
|
|
+
|
|
|
+
|
|
|
+ if ("${IS_SKIP_BUILD}" != "true") {
|
|
|
+ sh "mvn -f ${current_app_parent}/${current_app_name} clean install -Dmaven.test.skip=true"
|
|
|
+
|
|
|
+ sh "cp ${current_app_parent}/${current_app_name}/target/${current_app_jar} ${JENKINS_WORKSPACE}/docker"
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- stage('Deploy to Server') {
|
|
|
- when {
|
|
|
- expression { return params.ENV == 'prod' }
|
|
|
+ // app镜像
|
|
|
+ def app_docker_image_name = "weichi-crm-${current_app_name}"
|
|
|
+// def app_docker_image_tag = "${current_app_name}_${GIT_BRANCH_TAG}"
|
|
|
+ def app_docker_image_tag = "latest"
|
|
|
+ def app_docker_image = "${DOCKER_REGISTRY_URL}/${DOCKER_REGISTRY_NAMESPACE}/${app_docker_image_name}:${app_docker_image_tag}"
|
|
|
+
|
|
|
+ echo "app镜像: ${app_docker_image}"
|
|
|
+
|
|
|
+ if ("${IS_SKIP_BUILD}" != "true") {
|
|
|
+ // 删除旧容器
|
|
|
+ sh "docker ps -a | grep ${app_docker_image_name} | grep ${app_docker_image_tag} | awk '{print \$1}' | xargs -I docker stop {} | xargs -I docker rm {}"
|
|
|
+ // 删除旧镜像
|
|
|
+ sh "docker images | grep -E ${app_docker_image_name} | grep ${app_docker_image_tag}| awk '{print \$3}' | uniq | xargs -I {} docker rmi --force {}"
|
|
|
+ // 构建新镜像 -f:指定Dockerfile文件路径
|
|
|
+ sh "cd ${JENKINS_WORKSPACE}/docker && docker build -f Dockerfile --build-arg JAVA_OPTS=\"${JAVA_OPTS}\" --build-arg APP_NAME=${current_app_name} --build-arg APP_PORT=${current_app_port} -t ${app_docker_image} . --no-cache"
|
|
|
+
|
|
|
+
|
|
|
+ echo '****************************** 推送镜像 ******************************'
|
|
|
+
|
|
|
+ // 推送镜像
|
|
|
+ sh "docker push ${app_docker_image}"
|
|
|
+ sh "echo 镜像推送成功:${app_docker_image}"
|
|
|
+
|
|
|
+
|
|
|
+ // 操作完后移除docker目录下的jar文件,防止下次docker将多个jar一起构建导致镜像过大问题
|
|
|
+ sh "mv -f ${JENKINS_WORKSPACE}/docker/*.jar ${PROJECT_DOCKER_HISTORY_JAR_HOME}/"
|
|
|
}
|
|
|
- steps {
|
|
|
- script {
|
|
|
- echo '****************************** 部署到服务器 ******************************'
|
|
|
- def DOCKER_REGISTRY = "${DOCKER_REGISTRY}"
|
|
|
- def DOCKER_NAMESPACE = "${DOCKER_NAMESPACE}"
|
|
|
- def DOCKER_REPO = "${DOCKER_REPO}"
|
|
|
- sshPublisher(publishers: [sshPublisherDesc(configName:'CRM(阿里云)', transfers: [sshTransfer(cleanRemote: false, excludes: '',
|
|
|
- execCommand: """
|
|
|
- docker login -u wangfan@1934160439855919 -p Initial0 ${DOCKER_REGISTRY}
|
|
|
- docker pull ${DOCKER_IMAGE}
|
|
|
- docker rm -f ${DOCKER_REPO} || true
|
|
|
- docker run -d --name ${DOCKER_REPO} ${DOCKER_IMAGE}
|
|
|
- """,
|
|
|
- execTimeout: 120000, flatten: false, makeEmptyDirs: false,
|
|
|
- noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '',
|
|
|
- remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')],
|
|
|
- usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose:
|
|
|
- false)])
|
|
|
+
|
|
|
+ if ("${PUBLISH_SSH_SERVER_SELECT}" != "[]") {
|
|
|
+ echo '****************************** 项目部署 ******************************'
|
|
|
+ // 遍历所有服务器,分别部署
|
|
|
+ for (int j = 0; j < PUBLISH_SSH_SERVER_SELECT.length; j++) {
|
|
|
+ // 获取当前服务器名称
|
|
|
+ def currentServerName = PUBLISH_SSH_SERVER_SELECT[j]
|
|
|
+ echo '开始发布远程机器'
|
|
|
+ sshPublisher(publishers: [sshPublisherDesc(
|
|
|
+ // `Manage Jenkins` -> `Configure System` -> `Publish over SSH` -> `SSH Servers` 中的name值
|
|
|
+ configName: "${currentServerName}",
|
|
|
+ transfers: [sshTransfer(cleanRemote: false, excludes: '',
|
|
|
+ // ===================== ↓↓↓↓↓↓ 执行命令 ↓↓↓↓↓↓ =====================
|
|
|
+ execCommand: """
|
|
|
+
|
|
|
+ // 传输部署脚本到远程服务器之后,执行该脚本运行程序
|
|
|
+
|
|
|
+ cd ${PROJECT_SERVICE_LOG_HOME}
|
|
|
+
|
|
|
+ // 传输脚本参数时请使用双引号包裹单个参数值,避免单个参数中存在空格等特殊符号被解析为多个参数!
|
|
|
+ sh ssh-publish.sh \
|
|
|
+ "${DOCKER_REGISTRY_AUTH_CMD}" \
|
|
|
+ "${PROJECT_SERVICE_LOG_HOME}" \
|
|
|
+ "${current_app_name}" \
|
|
|
+ "${app_docker_image_name}" \
|
|
|
+ "${app_docker_image_tag}" \
|
|
|
+ "${app_docker_image}" \
|
|
|
+ "${ETH_VALUE}" \
|
|
|
+ "${current_app_port}" \
|
|
|
+ "${JAVA_OPTS}"
|
|
|
+
|
|
|
+ """,
|
|
|
+ // 超时时间1000ms*60*2=2分钟
|
|
|
+ execTimeout: 120000,
|
|
|
+ flatten: false, makeEmptyDirs: false, noDefaultExcludes: false,
|
|
|
+ patternSeparator: '[, ]+',
|
|
|
+ // ===================== ↓↓↓↓↓↓ 传输文件 ↓↓↓↓↓↓ =====================
|
|
|
+ // 传输文件
|
|
|
+ sourceFiles: 'ssh-publish.sh',
|
|
|
+ // 远程服务器目录
|
|
|
+ remoteDirectory: "${PROJECT_SERVICE_LOG_HOME}",
|
|
|
+ remoteDirectorySDF: false,
|
|
|
+ // 传输时移除前缀路径
|
|
|
+ removePrefix: '')],
|
|
|
+ usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
|
|
|
}
|
|
|
+ } else {
|
|
|
+ echo '****************************** 项目不部署 ******************************'
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- stage('Clean Workspace') {
|
|
|
- steps {
|
|
|
- cleanWs()
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-}
|
|
|
+
|
|
|
+}
|