我们java项目除了一般的jar包部署外,还可以运用工具jenkins部署,既方便又稳定。
所以在一次部门同事在给新的前端项目配置jenkins的时候,我在旁边学习,特此记录下。
一、在原有的项目上添加jenkins的配置文件 jenkins file。
// ==================== ↓↓↓↓↓↓ docker ↓↓↓↓↓↓ ==================== // 镜像仓库地址 def DOCKER_REGISTRY_URL = "10.66.53.51" // 镜像仓库命名空间名称 def DOCKER_REGISTRY_NAMESPACE = "justech" // ==================== ↓↓↓↓↓↓ git ↓↓↓↓↓↓ ==================== // git凭证 => jenkins全局凭证中配置 def GIT_AUTH = "Jenkins-gitlab" // ==================== ↓↓↓↓↓↓ project ↓↓↓↓↓↓ ==================== // 项目-git地址 def PROJECT_GIT_URL = "git@10.66.52.95:micro-service/justech-mfg.git" // 项目-基础目录 def PROJECT_BASE_HOME = "/data/justech/soft/justech-mfg" // 项目-服务日志目录 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,局域网取ens192的内网ip] ETH_VALUE = sh(script: "( [[ \"${JAVA_OPTS}\" = *'-Dspring.cloud.nacos.discovery.ip'* ]] && echo eth0 || echo ens192 )", 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/', '') } sh label: '', script: '''java -version mvn -v git version docker -v''' echo "当前工作空间:${JENKINS_WORKSPACE}" echo "使用分支:${GIT_BRANCH}" echo "使用分支tag:${GIT_BRANCH_TAG}" echo "当前时间:${CURRENT_TIME}" echo "使用网卡:${ETH_VALUE}" sh "mkdir -p ${PROJECT_SERVICE_LOG_HOME}" sh "mkdir -p ${PROJECT_JAR_HOME}" sh "mkdir -p ${PROJECT_DOCKER_HISTORY_JAR_HOME}" echo '****************************** 镜像仓库认证 ******************************' // 登录镜像仓库 DOCKER_REGISTRY_AUTH_CMD = "docker login -u admin -p MoodAir. 10.66.53.51:5000" sh "${DOCKER_REGISTRY_AUTH_CMD}" } stage('拉取代码') { echo '****************************** 拉取代码 ******************************' checkout([$class: 'GitSCM', branches: [[name: "${GIT_BRANCH}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${GIT_AUTH}", url: "${PROJECT_GIT_URL}"]]]) } 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}" script { switch (current_app_name) { case "mfg-dms": current_app_parent = "mfg-service/" current_app_port = "50003,50103" break case "mfg-dms-moon": current_app_parent = "mfg-service/" current_app_port = "50004,50104" break } } echo "当前操作项目: ${current_app_name} 端口:${current_app_port}" sh "mvn -f ${current_app_parent}${current_app_name} clean install ${MVN_OPTS} -Dmaven.test.skip=true" sh "cp ${current_app_parent}${current_app_name}/target/${current_app_jar} ${JENKINS_WORKSPACE}/docker" // app镜像 def app_docker_image_name = "${current_app_name}" def app_docker_image_tag = "${current_app_name}_${GIT_BRANCH_TAG}" def app_docker_image = "${DOCKER_REGISTRY_URL}:5000/${DOCKER_REGISTRY_NAMESPACE}/${app_docker_image_name}:${app_docker_image_tag}" echo "app镜像: ${app_docker_image}" // 删除旧容器 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 JAR_OPTS=${JAR_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}/" // 遍历所有服务器,分别部署 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}" \ "${current_app_port}" \ "${JAVA_OPTS}" "${JAR_OPTS}" "${ETH_VALUE}" > ssh.log 2>&1 """, // 超时时间1000ms*60*2=2分钟 execTimeout: 600000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', // ===================== ↓↓↓↓↓↓ 传输文件 ↓↓↓↓↓↓ ===================== // 传输文件 sourceFiles: 'ssh-publish.sh', // 远程服务器目录 remoteDirectory: "${PROJECT_SERVICE_LOG_HOME}", remoteDirectorySDF: false)], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } } } }
选取其中一个项目的jenkinsfile文件,作为记录参考。
二、在jenkin新建项目配置相关参数。
主要这边是项目的git分支,以及发布主分支。