Jenkins+Pipline+Docker 自动部署SpringBoot项目流程

以下所有内容 仅做日常笔记,如有错误 请自行排查

一、运行环境及版本

  • Ubuntu 20.x.x
  • Docker 20.x
  • Docker-compose

二、Jenkins安装

1.目录结构

服务器上 文件存放路径(根路径下): /jenkins (也可以放在其他路径这个随意)

 jenkins
      |-- data # 用户存放数据的目录
      |-- docker-compose.yml 

2.编写docker-compose.yml

version: "3"

networks:
  jenkins-net:
    driver: bridge

services:
  # 安装jenkins
  jenkins:
    image: jenkinsci/blueocean:latest
    user: root # root 用户运行 否则会有权限问题
    container_name: jenkins
    restart: always
    volumes:
      - ./data:/var/jenkins_home
      - /home/ubuntu:/home
      - /var/run/docker.sock:/var/run/docker.sock:rw # jenkins 容器内部调用宿主机docker 运行环境
    ports:
      - "8080:8080"
      - "50000:50000"
    networks:
      - jenkins-net

3. 服务器上运行docker-compose 安装Jenkins服务

# 1. 上传jenkins 目录到服务器根目录(或者用户家目录等 自由选择)
# 2. 确保服务器已经安装docker运行环境
# 3. 运行
cd /jenkins 
docker-composer up -d

三、安装并配置插件

1. 安装插件

可选插件中 搜索 SSH Pipeline Steps 并安装

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第1张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第2张图片

2. 安装 maven 包到 Jenkins 容器中

下载maven安装包到服务器上(下载链接: https://maven.apache.org/download.cgi
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第3张图片

	wget https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz
	# 解压
	tar -zxvf apache-maven-3.8.6-bin.tar.gz 
	# 重命名
	mv apache-maven-3.8.6 maven

替换 maven 中的settings.xml 配置 阿里云镜像






<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
    

    

    

    
    <pluginGroups>
        
    pluginGroups>

    
    <proxies>
        
    proxies>

    
    <servers>
        

        
    servers>

    
    <mirrors>
        
        <mirror>
            <id>aliyunmavenid>
            <mirrorOf>*mirrorOf>
            <name>阿里云公共仓库name>
            <url>https://maven.aliyun.com/repository/publicurl>
        mirror>
        <mirror>
            <id>maven-default-http-blockerid>
            <mirrorOf>external:http:*mirrorOf>
            <name>Pseudo repository to mirror external repositories initially using HTTP.name>
            <url>http://0.0.0.0/url>
            <blocked>trueblocked>
        mirror>
    mirrors>

    
    <profiles>
        

        
    profiles>

    
settings>

复制 maven 到Jenkins容器中

# docker cp  宿主机目录文件  容器:容器中的目录
docker cp maven jenkins:/maven

3. 设置Jenkins 中 maven 配置

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第4张图片

设置 maven中 settings.xml 在Jenkins 容器中的位置

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第5张图片

设置 maven 在容器中的路径

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第6张图片

4. 配置Git 管理工具 (假设使用的码云的Gitee管理工具)

安装 Gitee Plugin 工具

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第7张图片

配置 Gitee

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第8张图片

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第9张图片

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第10张图片

Gitee API V5 的私人令牌 (获取地址 https://gitee.com/profile/personal_access_tokens

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第11张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第12张图片

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第13张图片

5. 保存服务器以及Docker镜像仓库用户名密码等

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第14张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第15张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第16张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第17张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第18张图片

四、部署Pipline 流水线

1. 配置 Gitee WebHook

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第19张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第20张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第21张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第22张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第23张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第24张图片

2. 配置 pipline 脚本

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第25张图片
Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第26张图片

3. Jenkinsfile 模板(仅做参考)

模板仅做参考 本人也不熟悉 ,不对的地方 请自行修改

#!/usr/bin/env groovy


def ipList = ['45.x.x.x']

def getServer(ip){
    def remote = [:]
    remote.name = "server-${ip}"
    remote.host = ip
    remote.port = 22
    remote.allowAnyHosts = true
    withCredentials([usernamePassword(credentialsId: ip, passwordVariable: 'password', usernameVariable: 'username')]) {
        remote.user = "${username}"
        remote.password = "${password}"
    }
    return remote
}


def maven_package(){
    sh """
        mvn clean package -D maven.test.skip=true -P prod
        echo '---------------- maven-package complete ! ----------------'
    """
}
// username: docker仓库用户名 password:docker仓库密码 registry_addr:docker仓库地址 namespace:docker仓库命名空间
// project_name:项目名称 docker_file:Dockerfile 所在的项目目录

def push_docker(username,password,registry_addr,namespace,project_name,docker_file){
    def docker_image = "${registry_addr}/${namespace}/${project_name}:${env.BUILD_NUMBER}"
    sh """
        docker build -t ${docker_image} ${docker_file}
        docker login -u ${username} -p '${password}' ${registry_addr}
        docker push ${docker_image}
        echo '---------------- docker-push complete ! ----------------'
    """
}

// username: docker仓库用户名 password:docker仓库密码 registry_addr:docker仓库地址 namespace:docker仓库命名空间
// project_name:项目名称 server_docker_path:服务器上docker目录 start_containers: 需要启动的容器名称

def deploy(username,password,registry_addr,namespace,project_name,server_docker_path,start_containers){
    def docker_image = "${registry_addr}/${namespace}/${project_name}"
    def replaceVersion = "sed -i 's#^${project_name}=.*#${project_name}=${registry_addr}/${namespace}/${project_name}:${env.BUILD_NUMBER}#' ${server_docker_path}/.env"
    // 获取指定的容器是否存在
    def stopRemoveContainers = "container_num=`docker ps -a | grep -w ${docker_image} | awk 'NR>0'|wc -l`; if [ \$container_num -gt 0 ]; then docker stop `docker ps -a | grep -w ${docker_image} | awk '{print \$1}'` && docker rm `docker ps -a | grep -w ${docker_image} | awk '{print \$1}'`; fi"
    // 强制删除滚动更新残留的镜像(保留3个最近的docker镜像版本)
    def removeImages = "images_num=`docker images | grep -w ${docker_image} | awk 'NR>3'|wc -l`; if [ \$images_num -gt 0 ]; then docker rmi --force `docker images | grep -w ${docker_image} | awk 'NR>3 {print \$3}'`; fi"
    // 启动容器
    def restartContainers="cd ${server_docker_path} && docker-compose up -d ${start_containers}"
    return """
        #拉取最新镜像
        docker login -u ${username} -p '${password}' ${registry_addr}
        docker pull ${docker_image}:${env.BUILD_NUMBER}
        # 替换版本号
        ${replaceVersion}
        # 停止并删除指定的容器
        ${stopRemoveContainers}
        # 启动新容器
        ${restartContainers}
        # 强制删除滚动更新残留的镜像
        ${removeImages}
    """
}

pipeline {
    agent any
    tools {
        maven 'M3'
    }
    stages {
        stage('部署项目') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'docker-tencent', passwordVariable: 'password', usernameVariable: 'username')]) {
                    maven_package()
                    push_docker("${username}","${password}","ccs.tencentyun.com","mall-pro",'voice_server','voice-admin')
                    script {
                        for(ip in ipList){
                            def remote = getServer(ip)
                            sshCommand remote: remote, command: deploy("${username}","${password}","ccs.tencentyun.com","mall-pro","voice_server","/data/project/voice/docker","voice-server1 voice-server2")
                        }
                    }
                }
            }
        }
    }
}


4. 立即构建

Jenkins+Pipline+Docker 自动部署SpringBoot项目流程_第27张图片

你可能感兴趣的:(Jenkins,jenkins,docker,spring,boot)