Are you still sending packages manually? Teach you step by step how to automatically deploy SpringBoot in Jenkins


Hello everyone, I am Yihang!

The daily work of programmers almost revolves around these points 开发, , 打包, 发布, 测试but in these processes, there is a large part of repetitive hard work, which not only consumes a lot of our time, but also has to be done; pure manual work Integration and deployment are hard work and error-prone; at this time, automation is needed to free up hands.

Before doing automated integration and deployment, we first introduce two concepts CI/CD, the core of which is divided into three points:

  • Continuous integration

    Integrate code into trunk frequently (multiple times a day). Each integration is verified through automated builds (including compilation, release, and automated testing) to detect integration errors as quickly as possible.

  • Continuous delivery

    Frequently deliver new versions of the software to the quality team or users for review. If the review passes, the code goes into production.

  • Continuous deployment

    Continuous deployment is the next step of continuous delivery, which means that after the code passes the review, it is automatically deployed to the production environment.

Jenkins is a Java open source software specifically designed for CI/CD. It is deeply loved by everyone because of its features such as 功能强大, 跨平台, 插件丰富, 扩展性强, and so on;分布式

However, it is easy to use, but it is a little unfriendly to novices. Environment deployment will always encounter some inexplicable problems. Even if I have deployed it so many times, every time I redeploy it, Sometimes, we always encounter various different problems; there are often people talking about Jenkins in the communication group. Here we will simply start from 0 and guide everyone to fully deploy a Jenkins automation environment.

The goal this time is to free us from the hard work of integration and deployment, and just focus on writing code.

The article is as detailed as possible down to every detail, and is a bit long. It is recommended to save it for future viewing;

Prepare

All deployments in this article are completed on CentOS 7, and Docker is used for software installation. If you want to follow this tutorial, you need to prepare the environment:

  • 2 CentOS 7 computers/virtual machines

    If there is no physical machine, you can use a virtual machine to build it. This article uses a virtual machine to configure it;

    CentOS 7 virtual machine building tutorial: https://blog.lupf.cn/articles/2020/04/04/1586001434581.html

    The IP and function points of the following two test machines

    • 192.168.1.253 Install Jenkins and GitLab
    • 192.168.1.237 Run the packaged project
  • Docker installation

    Service orchestration usesdocker-compose

    Installation tutorial: https://blog.lupf.cn/articles/2019/11/23/1574503815568.html

  • JDK installation

    Full version JDK download: https://blog.lupf.cn/category/jdkdl

  • Maven installation

    Download address: https://maven.apache.org/download.cgi

    wget http://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 /usr/local/
    
  • SSH tools

    Used for remote Linux servers and virtual machines, it is more troublesome to operate directly;

    I have recommended many SSH tools to you before; [5 SSH tools], []

Software Installation

Since it is a tool software, in order to reduce the intrusion into the machine, Jenkins and the code warehouse GitLab are installed using Docker, so please install Docker in advance.

Jenkins

Install

  • Prepare to mount directory

    Used to persist data

    mkdir -p /var/jenkins/data
    chmod 777 /var/jenkins/data
    cd /var/jenkins/data
    
  • View Docker’s group ID

    **important! **This step is very important, because later Jenkins uses the Docker of the host machine, so when starting, you need to do the mapping of Docker and the configuration of the permission group ID;

    cat /etc/group | grep docker
    

    Each computer will be different. Below are the IDs corresponding to my two virtual machines;

    Remember the ID of the machine where you installed Jenkins. When configuring docker-compose in the next step, you need to group_addconfigure the corresponding ID in it;

    Be sure to configure it correctly here, otherwise when you use the Docker command in the Jenkins container later, an error of insufficient permissions will be reported.

  • Prepare docker-compose-jenkins.yml configuration file

    vim docker-compose-jenkins.yml  
    

    Add the following configuration

    version: '2'
    services:
      jenkins:
        container_name: 'jenkins'
        image: 'jenkins/jenkins'
        restart: always
        environment:
          TZ: 'Asia/Shanghai'
        ports:
          - '8880:8080'
          - '50000:50000'
        group_add:
          - 994
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - /usr/bin/docker:/usr/bin/docker
          - /var/jenkins/data:/var/jenkins_home
          - /usr/local/apache-maven-3.8.6:/usr/local/apache-maven-3.8.6
    

    Parameter Description

    • portsmapped port

    • restartself start

    • group_addDocker's group ID is the ID obtained in the previous step.

    • volumeshang in directory

      /usr/bin/docker:/usr/bin/docker, hang the host's Docker to Jenkins to facilitate subsequent use of the host's Docker in Jenkins, and there is no need to install another Docker in the Jenkins container;

      /var/jenkins/data:/var/jenkins_homeHang the Jenkins working directory /var/jenkins_homein the host /var/jenkins/datadirectory;

      /usr/local/apache-maven-3.8.6:/usr/local/apache-maven-3.8.6The Maven hanging on can be adjusted according to personal use;

  • start up

    # 启动
    docker-compose -f docker-compose-jenkins.yml up -d
    # 查看容器
    docker ps | grep jenkins
    

initialization

The container starts. After about 1 minute, you can initialize Jenkins.

  • Visit jenkins

    Access directly in the browser http://你jenkins机器的ip:8880, my local address:http://192.168.1.253:8880

  • View initial password

    The default password is saved in/var/jenkins_home/secrets/initialAdminPassword

    The acquisition command is as follows:

    docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
    

    The command means jenkinsto execute it in the Docker container named cat /var/jenkins_home/secrets/initialAdminPassword; it can also be searched in the directory where it is hung locally;

Install recommended plugins

Install plugin

During initialization, some plug-ins are installed for us by default. We will need to use some plug-ins later. Install them in advance here;

Installation entrance: System Management–>Plug-in Management–>Optional Plug-in

Notice! All plug-ins will not take effect until restarted

  • Chinese plug-in

  • Maven plugin

    The project demonstrated in this article is managed through Maven. Search Maven Integrationand install Maven related plug-ins.

  • Git plugin

  • GitLab plugin

  • SSH plugin

    Used to upload files to remote server

  • webhook

Global configuration

It mainly configures some basic environments, such as Maven, Git, JDK and other tools, so that these global basic configurations can be directly used during subsequent builds.

  • Maven configuration

    Maven here is the host package mapped when the container is started. If you downloaded other versions or mapped other paths, please adjust according to the actual situation;

    Maven optimization

    You can configure MAVEN_OPTS to avoid memory leaks and other problems when compiling complex projects.

  • JDK configuration

    The Jenkins container installed by Docker comes with its own JDK, so here you only need to get the JDK path in the container and configure it; the acquisition is as follows:

    # 进去容器
    docker exec -it jenkins /bin/bash
    # 输出JDK的环境变量
    echo $JAVA_HOME
    

  • SSH Server configuration

    What is configured here is the information of the remote server (that is, the server information where the code runs);

Gitlab

GitLab is an open source project for warehouse management systems. It uses Git as a code management tool and builds a web service based on it.

Since many people use GitLab to build private code warehouses in actual work, GitLab is used here to demonstrate; of course, you can use it, but since the local Jenkins does not have a public IP, when configuring Githubwebhook Giteelater , if you use Github or Gitee, you need to penetrate the intranet, which will add some trouble, so here we simply install a local GitLab to facilitate subsequent use. Anyway, Docker is relatively easy to install.

Install

  • Search the Chinese version of gitlab-ce-zh

    docker search gitlab-ce-zh
    

    twang2218/gitlab-ce-zhMirroring is used here

  • Prepare persistence directory

    mkdir -p /var/gitlab
    
  • Prepare docker-compose

    version: '2'
    services:
        gitlab:
          container_name: 'gitlab-ce-zh'
          image: 'twang2218/gitlab-ce-zh'
          restart: unless-stopped
          hostname: 'gitlab'
          environment:
            TZ: 'Asia/Shanghai'
            GITLAB_OMNIBUS_CONFIG: |
              external_url 'http://192.168.1.253:880'
          ports:
            - '880:880'
            - '8443:443'
            - '2212:22'
          volumes:
            - /var/gitlab/etc:/etc/gitlab
            - /var/gitlab/log:/var/log/gitlab
            - /var/gitlab/data:/var/opt/gitlab
    

    The IP in it external_urlis the IP of your local machine; the port in it must be consistent with the port mapped by the container, otherwise it will be inaccessible.

  • start up

    docker-compose -f docker-compose-gitlab.yml up -d
    docker ps | grep gitlab
    

    The status changes healthy, indicating that the service is normal.

initialization

  • access

    Access the previous step external_url(this machine: http://192.168.1.253:880)

  • Set administrator password

    After setting it up, use rootyour newly set password to log in to the gitlab homepage.

Configure Jenkins and GitLab association

Since Jenkins needs to automatically obtain the latest code in Gitlab later, the authentication token needs to be configured in advance.

GitLab token

  • create

    hYw-Qy6KxGFsdzGA96Ux
    

    It will be different every time it is created; moreover, this token will only be displayed once and will not be displayed again, so please save it; otherwise, it will have to be regenerated;

Jenkins configures GitLab credentials

Configure the GitLab token generated in the previous step as the global credentials of Jenkins to facilitate subsequent use.

  • Select administrative credentials

  • Click on Jenkins

  • Click Global Credentials

  • Click Add Credentials

  • EnterToken

    Select GitLab API tokenand enter the token created in GitLab in the previous step

  • Created successfully

    CreateCreate credentials with the click of a button

Basic information for configuring GitLab in Jenkins

Build Maven project

Prepare project

  • Test source code

    Source code used in this tutorial: https://github.com/vehang/ehang-spring-boot

  • Create a project in local GitLab

    The source code creates a jenkinsbranch and pushes it to the local Gitlab repository.

Prepare script

The function of this script is to transfer Jenkins to the Jar package of the running server for running;

Single-module project scripts are relatively simple to write; when I said in the group that I was writing a Jenkins tutorial, some group friends specifically @ me and asked me to write multi-module ones, and then the script here became longer; Because the situation of multi-modules is slightly more complicated, for example: a project has 10 modules. In this submission, only 1 module has been modified, and the other 9 modules have not been changed at all. There is no need to release those 9 modules, only the modifications have been updated. Which package will be fine;

The following is just a basic script, and individuals can make adjustments based on the actual usage process;

#!/bin/sh

# JDK的环境变量
export JAVA_HOME=/usr/local/jdk-11.0.14
export PATH=$JAVA_HOME/bin:$PATH

# 基础路径,由参数传入
# 多模块的时候,需要在路径中使用*统配一下多模块
# 比如/opt/ehang-spring-boot是多模块,下面由module1和module2
# 那么执行shell的时候使用:sh restart.sh /opt/ehang-spring-boot/\*  注意这里的*需要转义一下
JAR_BATH=$1
echo "基础路径:"$JAR_BATH
JAR_PATH=${JAR_BATH}/target/*.jar

# 获取所有的JAR 开始遍历
for JAR_FILE in $JAR_PATH
do
if [ -f $JAR_FILE ]
then
  echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
  echo "JAR路径:"$JAR_FILE
  JAR_FILE_MD5=${JAR_FILE}.md5

  # 用于标记是否需要重启的标识
  RESTART=false

  # 判断MD5文件是否存在,存在就校验MD5值
  if [ -f $JAR_FILE_MD5 ]; then
    # 校验MD5
    md5sum --status -c $JAR_FILE_MD5
    # = 0表示校验成功 =1 表示校验失败
    if [ $? = 1 ];then
      echo "MD5校验失败,安装包已经更新!"
      RESTART=true
    else
      echo "安装包没有更新!"
    fi
  else
    echo "没有MD5值,说明是第一次启动"
    RESTART=true
  fi

  # 获取进程号
  PROCESS_ID=`ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}'`
  # 如果不需要重启,但是进程号没有,说明当前jar没有启动,同样也需要启动一下
  if [ $RESTART == false ] && [ ${
    
    #PROCESS_ID} == 0 ] ;then
     echo "没有发现进程,说明服务未启动,需要启动服务"
     RESTART=true
  fi

  # 如果是需要启动
  if [ $RESTART == true ]; then
      # kill掉原有的进程
      ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}' | xargs kill -9

      #如果出现Jenins Job执行完之后,进程被jenkins杀死,可尝试放开此配置项
      #BUILD_ID=dontKillMe
      #启动Jar
      nohup java -jar $JAR_FILE  > ${JAR_FILE}.log 2>&1 &
      # =0 启动成功 =1 启动失败
      if [ $? == 0 ];then
          echo "restart success!!! process id:" `ps -ef | grep $JAR_FILE | grep -v grep | awk '{print $2}'`
      else
          echo "启动失败!"
      fi

      # 将最新的MD5值写入到缓存文件
      echo `md5sum $JAR_FILE` > $JAR_FILE_MD5
  fi
  echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
  echo ""
fi
done

The script details and comments have been written very clearly; let’s briefly talk about the script process:

  1. Execute the script and pass in the path of single module/multi-module

    Note: When using multiple modules, you need to use * to wildcard each module. When executing the command, you need to \*escape it; see the figure below for details.

  2. Traverse targetall jar packages in the directory

  3. Verify MD5. If MD5 does not match or does not match, it means it has been updated. Otherwise, the corresponding package has not been updated.

  4. When no update is required, verify whether the process exists. If the process does not exist, it also needs to be started.

  5. start jar

  6. Cache the latest MD5 value

The following are just screenshots of subsequent tests. You can skip this and continue to the next step.

Jenkins creates Maven task

  • Create a Maven task

Maven task configuration

Set gitlab credentials

Select the credentials configured in the previous steps

Set GitLab project address

For first-time configuration, you need to add the credential information of the Git warehouse first. The steps are as follows:

Configure build commands

clean package  -DskipTests=true

Note that this is the Maven build itself, so the command does not need to be added in frontmvn

Upload the file after building

Upload script

Before uploading the Jar package, we need to transfer the startup/restart script of the project to the server so that it can be executed directly after the subsequent jar is uploaded.

  • Transfer Set Source files : Represents files/file rules to be transferred

  • Remove prefix : To remove the prefix of the file, such as the above configuration, the default file path is: script/jenkins/abc.sh, configuring script/jenkins/ here will only copy abc.sh to the remote directory, otherwise, script/ Copy the complete jenkins/abc.sh.

  • Remote directory : The remote path of the copy. If not configured, there is the path configured in the SSH Server. The remote path configured in my ssh server is/opt/jenkins/package

  • Exec command : script to be executed after copying

Upload Jar package

Since the project is multi-module, after packaging, each module will generate a jar package and place it in the target directory of each module; what we need to do is to copy the Jars of all modules to the server and start them;

After the upload is successful, you will /opt/jenkins/packagesee all package information in the directory:

After copying, shellthe script will be executed. The difference between the commands executed by single module and multi-module is only in the parameters:

  • single module

    Tospring-boot-001-hello-world/target/spring-boot-001-hello-world-0.0.1-SNAPSHOT.jar test a single-module package, the restart script executed is:

    sh /opt/jenkins/package/jenkins_restart.sh /opt/jenkins/package/spring-boot-001-hello-world
    

    The parameter /opt/jenkins/package/spring-boot-001-hello-worldis the root directory of the single module

  • Multiple modules

    Multiple modules only have different paths

    sh /opt/jenkins/package/jenkins_restart.sh /opt/jenkins/package/\*
    

    It /opt/jenkins/package/\*is used to indicate that all submodule Jar packages under the /opt/jenkins/package path are to be restarted; where it \*indicates wildcarding.

Note: Since the shell script is executed here, you must check it in the advanced options when configuring Exec in pty, otherwise the shell command execution will not terminate until the timeout ends, as shown in the following log:

....
SSH: Connecting with configuration [centos_server] ...
SSH: Disconnecting configuration [centos_server] ...
ERROR: Exception when publishing, exception message [Exec timed out or was interrupted after 120,000 ms]
Build step 'Send files or execute commands over SSH' changed build result to UNSTABLE
Finished: UNSTABLE

Enable console output logging

When configuring for the first time, exceptions are likely to occur. In order to facilitate troubleshooting, you can check the option on the left side of the figure below to output the remote server execution log; the log on the right side of the figure below is the output of the remote execution of the shell script; uncheck it. There will be no logs for these.

Manual build

Select the project and click "Build Now" to start. If it is green after execution, it means the build was successful, and red means it failed.

Automatic build

Jenkins task starts monitoring

The previous manual build has been completed. Our ultimate goal is to automatically build and publish the code as soon as it is submitted.

Enable Gitlab monitoring in Jenkins and set a token (optional)

After configuring, I got the following information:

  • Hook address
    http://192.168.1.253:8880/project/ehang-spring-boot

  • token

    97a6a4c1601cebe83241a08a67fd3755

    The token is for security, you can also not set it, it depends on your personal needs.

GitLab configuration hook

After finding the project, follow the steps in the picture above, configure the Jenkins address, token and trigger conditions, and click the Add button;

Manually trigger events

After successfully adding, you can manually test the event trigger through the Test button. If a reminder of 10 appears, it means the trigger is successful;

Then go to Jenkins to check, and you will find that an additional build task is automatically added, and the trigger condition is: Started by GitLab push by Administator;

Automatically trigger events

The above manual triggering method has been able to build normally. Now let's submit a piece of code through git to see if it can be triggered automatically.

As you can see in the animation, push2 seconds after the code is successful, Jenkins has automatically started the build task.

After the execution, check the Jenkins log and the Linux service process. The service has started normally.

Deploy using Docker

The above demonstrates the construction and deployment of Maven + SSH, which is deployed to the server by running Jar directly. After the service is containerized, it will be more convenient to manage using Docker. Let’s talk about how to build the project into a Docker image. , to deploy services;

Alibaba Cloud Image Warehouse

If you have a Docker image, you need warehouse management. For local LAN use, you can build a private warehouse through Harbor. However, if you want to use it on the public network, you must have a public IP;

In fact, we don’t need to be so troublesome. Alibaba Cloud provides us with a free image warehouse. The Jenkins server can push the prepared image directly to the Alibaba Cloud warehouse. The business server can directly pull the image from the Alibaba Cloud warehouse and run it;

  • address

    https://cr.console.aliyun.com/cn-shenzhen/instances

  • Create namespace

    3 free

  • Create warehouse

  • Docker login to Alibaba Cloud warehouse

    In the previous step, after creating the warehouse, log in to the Alibaba Cloud Docker warehouse on the server according to the guidance.

    docker login --username=你的用户名 registry.cn-guangzhou.aliyuncs.com
    

    Docker shared by Jenkins also needs to enter the container class to log in. Since the users in the container are different, logging in on the host machine cannot be used in the container.

    # 进入容器
    docker exec -it jenkins /bin/bash
    # 容器内登录
    docker login --username=你的用户名 registry.cn-guangzhou.aliyuncs.com
    

Prepare script

After Maven is built, you need to build the corresponding Docker image and push the image to the remote server. Therefore, you need to prepare some scripts in advance to facilitate use during the build. The process is as follows:

  • Jenkins builds Docker image locally
  • Alibaba Cloud warehouse to push the image to
  • Push download scripts and startup scripts to the running server
  • Execute download and startup scripts

The script details are as follows:

Dockerfile

Used when building images

FROM openjdk:8

# 同步时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 将当前目录下的jar拷贝到容器类
ADD ./*.jar /app.jar

# 监听端口
EXPOSE 8081

# 启动
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom" \
,"-XX:+UnlockExperimentalVMOptions","-XX:+UseCGroupMemoryLimitForHeap" \
,"-jar", "/app.jar" ]

Build script

Use Jenkins tasks!

docker-image-build.sh

Shell script executed when building the image;

# 考虑到多模块的情况 这里创建一个临时目录,来汇总配置
rm -rf ./tmp
mkdir ./tmp

# 将脚本 jar包拷贝的临时目录中
cp ./spring-boot-001-hello-world/docker/* ./tmp
cp ./spring-boot-001-hello-world/target/*.jar ./tmp
cd ./tmp

# 构建镜像
docker build -t registry.cn-guangzhou.aliyuncs.com/ehang_jenkins/ehang-sping-boot-hello-world:latest .
# 将镜像推送到阿里云
docker push registry.cn-guangzhou.aliyuncs.com/ehang_jenkins/ehang-sping-boot-hello-world:latest

# 删除临时文件
cd ..
rm -rf ./tmp

Mirror download script

Run the server to use;

docker-image-pull.sh; Used to run the server to download the latest image script

# 更新最新的镜像
docker pull registry.cn-guangzhou.aliyuncs.com/ehang_jenkins/ehang-sping-boot-hello-world:latest

docker-compose configuration

Run the server to use;

docker-compose.yaml

Service orchestration configuration of the module, used to start/restart Docker containers

version: '2'
services:
  ehang-hello-world:
    container_name: ehang-hello-world
    image: registry.cn-guangzhou.aliyuncs.com/ehang_jenkins/ehang-sping-boot-hello-world:latest
    restart: always
    volumes:
      - /opt/ehang:/opt/ehang
    ports:
      - "8081:8081"
    environment:
      - --spring.profiles.active=dev

Multi-module build script

Use Jenkins tasks!

Used to traverse and build all submodules

#!/bin/sh

BUILD_SHELL_PATH=./*/docker/docker-image-build.sh

# 获取所有的JAR 开始遍历
for BUILD_SHELL in $BUILD_SHELL_PATH
do
if [ -f $BUILD_SHELL ]
then
  echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
  echo "构建脚本:"$BUILD_SHELL
  sh $BUILD_SHELL
  echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
  echo ""
fi
done

Start/restart script

Run the server to use;

jenkins_restart_docker.sh

A script used to start/restart the Docker container after all modules are packaged and sent to the Docker warehouse;

#!/bin/sh

# 基础路径,由参数传入
# 多模块的时候,需要在路径中使用*统配一下多模块
# 比如/opt/ehang-spring-boot是多模块,下面由module1和module2
# 那么执行shell的时候使用:sh restart.sh /opt/ehang-spring-boot/\*  注意这里的*需要转义一下
BASE_PATH=$1
echo "基础路径:"$BASE_PATH
DOCKER_COMPOSE_FILES=${BASE_PATH}/docker/docker-compose.yaml

DOCKER_PULL_SHELL=${BASE_PATH}/docker/docker-image-pull.sh

# 获取最新的镜像
for PULL_SHELL in $DOCKER_PULL_SHELL
do
if [ -f $PULL_SHELL ]
then
  echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
  echo "更新最新的镜像:"$PULL_SHELL
  sh $PULL_SHELL
  echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
  echo ""
fi
done

# 启动镜像
for DOCKER_COMPOSE_FILE in $DOCKER_COMPOSE_FILES
do
if [ -f $DOCKER_COMPOSE_FILE ]
then
  echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
  echo "docker compose 配置路径:"$DOCKER_COMPOSE_FILE

  docker-compose -f $DOCKER_COMPOSE_FILE up -d

  echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
  echo ""
fi
done

All scripts have a single function and relatively simple logic. It is easy to understand by looking at the comments;

Maven task configuration

The steps to deploy using Docker are similar to the previous steps to upload using SSH. The only difference is the difference in script execution after Maven packaging is completed, so about, , 创建Maven任务and 设置GitLab凭据these 设置GitLab地址same 配置构建命令configurations, I will not repeat them here. If you forget, you can Turn back and look;

Let’s talk about the differences in detail here!

Post-build actions

Build Docker image

Jenkins executes a script to build all submodule Docker images locallyjenkins_docker_build.sh

Upload basic script

Upload the script to start/restart the module . The configuration here uses wildcards to upload all scripts, but the server uses only jenkins_restart_docker.sh;

Upload all module Docker related scripts

What is uploaded here is mainly various sub-modules 服务编排的配置and downloads 最新镜像的脚本;

After the upload is successful, execution starts jenkins_restart_docker.sh. The subsequent parameters need to be determined according to the project structure. For a single module, directly transfer the root path of the project; for multiple modules, \*wildcard all sub-modules need to be used.

Manual build, automatic trigger

Manual construction and automatic triggering are the same as the previous configuration, so they will not be repeated here;

Due to limited resources, two sub-modules are used below for build testing; after success, the following two containers appear in Docker on the server side, indicating that the service is normal.

abnormal situation

  • Docker command permissions are not allowed

    dial unix /var/run/docker.sock: connect: permission denied
    

    Solution: When Jenkins is started, group_addit is not configured or the configuration is incorrect. After the configuration is correct, it will be normal;

  • denied: requested access to the resource is denied

    Error when uploading/downloading image

    Solution: You need to enter the Jenkins container and log in to the Docker warehouse;

Pipeline

After operating the Maven task above, it can be regarded as a framework, based on which to fill in personalized things; this construction method can almost meet most of our demand scenarios; the Pipeline assembly line provides only one More flexible construction methods;

What is a Pipeline?

Pipeline, that is, pipeline, is a new feature of jenkins2.X and is the continuous integration solution officially recommended by jenkins. Unlike traditional free-style projects, it is jenkins DSLimplemented by writing code. Compared with the previous way where users could only define Jenkins tasks through configuration through the web interface, now by writing programs using the jenkins DSLand languages, users can define pipelines and perform various tasks.Groovy

Simple test

Pipeline is a relatively large function point of Jenkins and involves a lot of content. Due to time constraints, we will not go into depth here. We will explain Pipeline in detail later.

Let’s briefly demonstrate the process of building a Docker image through Pipeline compilation and packaging;

  • Create Pipeline tasks

  • Placement script

    pipeline {
          
          
        agent any
        stages {
          
          
            stage('下载源码'){
          
          
                options {
          
           timeout(time: 60, unit: 'SECONDS') }
                steps {
          
          
                    git branch: 'jenkins',
                    credentialsId: '6b7f5874-52b0-4859-ab83-14b20d68db50',
                    url: 'http://192.168.1.253:880/root/ehang-spring-boot.git'
                }
                
            }
            stage('Maven编译'){
          
          
                steps {
          
          
                    sh '''
                      /usr/local/apache-maven-3.8.6/bin/mvn clean package -DskipTests=true
                    '''
                }
            }
            
            stage("构建/上传镜像"){
          
          
                steps {
          
          
                    sh '''
                      sh ./script/jenkins/jenkins_docker_build.sh
                    '''
                }
            }
        }
    }
    
    • git branch represents the name of the code branch
    • credentialsId GitLab credentials ID, add or view it in System Management->Credentials
  • test

Summarize

Although it took such a long time to write this tutorial, it only explained some of the most basic and commonly used functions; the functions of Jenkins are too powerful. It was originally planned that this article would organize Pipeline and automated testing together, but After writing all the way, I found that the basic content took up so much space, so I decided to leave the rest for the next article!

I hope this article can make your daily work more "silky";

I am a flight! Coding is not easy! Ask for a threesome!

Guess you like

Origin blog.csdn.net/lupengfei1009/article/details/126495241