Jenkins通过pipeline编译springboot项目并部署到docker容器

635 阅读7分钟

Jenkins通过pipeline编译springboot项目并部署到docker容器

1、环境准备

1.1、创建项目

首先创建一个springboot项目jenkins-demo,然后上传到gitlab私服,仓库地址【gitlabs.jianjang.com/zhangjian_s…

@RestController
public class HelloController {
    @GetMapping("hello")
    public String hello() {
        return "hello world";
    }
}

1.2、编写Dockerfile文件

在项目根目录下创建一个docker目录,在docker目录下创建Dockerfile文件用于构建项目docker镜像,Dockerfile内容如下:

FROM java:8
MAINTAINER JianJang
LABEL name="jenkins-demo" version="1.0.0" author="JianJang"
VOLUME /tmp
COPY jenkins-demo.jar /jenkins-demo.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/jenkins-demo.jar"]
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
EXPOSE 8081

1.3、Jenkins项目ssh凭证配置

略,请参考教程 Jenkins安装教程

2、编译部署

2.1、环境准备

首先需要在进行部署的jenkins服务器上安装sshpass工具,用于连接应用部署的的服务器安装命令如下:

yum install sshpass -y

2.2、应用服务准备

准备一台应用服务器,需要安装docker,并使用阿里云镜像加速,用于从镜像仓库中拉取需要部署的应用镜像和运行容器。

类型IP软件安装备注
应用服务器192.168.2.71、docker
镜像仓库registry.cn-shanghai.aliyuncs.com阿里云个人镜像仓库

2.3、Pipeline脚本配置

pipeline脚本分为五个阶段,分别如下:

  1. 从gitlab仓库拉取项目代码
  2. Jar包构建
  3. docker镜像构建
  4. docker镜像上传到阿里云镜像仓库
  5. 项目部署到应用服务器

pipeline脚本如下:

node {
    //镜像名
	def dockerImageName='jenkins-demo'
	//镜像版本
	def version='1.0.1'
	//容器名
    def dockerName='jenkins-demo'
    //第三方docker容器镜像服务账号
	def dockerLoginName = 'zhangjian20200721'
	//第三方docker容器镜像服务密码
	def dockerLoginPassword = 'zwx123456'
	//第三方docker容器镜像服务地址
	def dockerLoginUrl = 'registry.cn-shanghai.aliyuncs.com'
	//第三方docker容器镜像服务命名空间
	def nameSpace='zhangjian_sh'
	//项目端口
	def port=8080
	//docker映射端口
	def dockerPort=8081
	//Git URL
	def gitUrl='git@gitlabs.jianjang.com:zhangjian_sh/jenkins-demo.git'
	//Git 凭据,在jenkins后台创建的凭据ID
	def gitToken='git-ssh-key'

	stage('拉取代码'){
		git credentialsId: "${gitToken}", url: "${gitUrl}"
	}
	stage('Jar包构建') {              
		sh "mvn clean install -Dmaven.test.skip=true"
            
    }
	//这里需要修改,改成自己的路径,没有抽出来(懒得抽.jpg)
	stage('docker镜像构建') {
		//这里是将jar包复制到Dockerfile同一目录,跟上面的方式相反
		sh "cp ${WORKSPACE}/target/jenkins-demo.jar ${WORKSPACE}/docker"
		sh "mvn clean"
		//这里他默认是指向当前工作区的路径,Dockerfile的内容跟上面maven部署的内容保持不变,
		//docker build 上面那种方式 最后是 用的 . 表示当前目录,所以这个地方要改一下 指向Dockerfile所在目录
		//关于目录所在问题 如果目录填的不正确,可能Dockerfile文件里COPY 或 ADD命令的目标文件找不到,那么就会报 fiel does not exist,下面有截图
		//如果出现这种问题 首先检查目标文件是否跟dockerfile在同一目录,如果在,那么就是你最后的路径设置的有问题
		//可以在执行build命令之前,先执行一下pwd命令,输出当前所在目录,再来确定docker build最后的文件目录该怎么填
		//sh "pwd"
		sh "sudo docker build -f ${WORKSPACE}/docker/Dockerfile  -t ${dockerImageName}:${version} ./docker/"  
		echo 'docker镜像构建'
    }
	stage('docker镜像上传') {
		sh "sudo docker login --username=${dockerLoginName}  --password=${dockerLoginPassword} ${dockerLoginUrl}"
		sh "sudo docker tag ${dockerImageName}:${version} ${dockerLoginUrl}/${nameSpace}/${dockerImageName}:${version}"
		sh "sudo docker push ${dockerLoginUrl}/${nameSpace}/${dockerImageName}:${version}"
		sh "sudo docker logout ${dockerLoginUrl}"
		sh "sudo docker rmi -f ${dockerImageName}"  
		echo "docker镜像上传"
    }
    
	//这种方式不能使用${},但是reallsh生效
	stage('项目部署') {	  
		sh '''
		sshpass -p 'zwx123456' ssh -p 22 -o StrictHostKeyChecking=no root@192.168.2.7 << reallsh
		sudo docker rm -f jenkins-demo 
		sudo docker rmi registry.cn-shanghai.aliyuncs.com/zhangjian_sh/jenkins-demo:1.0.1
		sudo docker login --username=zhangjian20200721  --password=zwx123456 registry.cn-shanghai.aliyuncs.com
		sudo docker pull registry.cn-shanghai.aliyuncs.com/zhangjian_sh/jenkins-demo:1.0.1
		sudo docker run -d -p 8081:8080 --name jenkins-demo registry.cn-shanghai.aliyuncs.com/zhangjian_sh/jenkins-demo:1.0.1
		sudo docker logout registry.cn-shanghai.aliyuncs.com
		exit'''
		echo '项目部署'		
	}
}

2.4、创建Pipeline任务

在Jenkins中创建一个pipeline任务,取名为new-pipeline,如下图。

image-20220509151624103

任务流水线配置

image-20220509152502625

将上面准备的pipeline脚本复制到流水线的脚本中,如下图:

image-20220509152427141

任务构建

image-20220509153123863

构建前应用服务器容器及镜像情况如下,无镜像及运行中的容器

image-20220509153635185

根据阶段过程进度图如下:

image-20220509153927579

构建日志如下:

Started by user 张健
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /root/.jenkins/workspace/new-pipeline
[Pipeline] {
[Pipeline] stage
[Pipeline] { (拉取代码)
[Pipeline] git
The recommended git tool is: NONE
using credential git-ssh-key
 > /usr/bin/git rev-parse --resolve-git-dir /root/.jenkins/workspace/new-pipeline/.git # timeout=10
Fetching changes from the remote Git repository
 > /usr/bin/git config remote.origin.url git@gitlabs.jianjang.com:zhangjian_sh/jenkins-demo.git # timeout=10
Fetching upstream changes from git@gitlabs.jianjang.com:zhangjian_sh/jenkins-demo.git
 > /usr/bin/git --version # timeout=10
 > git --version # 'git version 1.8.3.1'
using GIT_SSH to set credentials git仓库ssh秘钥
[INFO] Currently running in a labeled security context
[INFO] Currently SELinux is 'enforcing' on the host
 > /usr/bin/chcon --type=ssh_home_t /root/.jenkins/workspace/new-pipeline@tmp/jenkins-gitclient-ssh4907159492752831295.key
 > /usr/bin/git fetch --tags --progress git@gitlabs.jianjang.com:zhangjian_sh/jenkins-demo.git +refs/heads/*:refs/remotes/origin/* # timeout=10
 > /usr/bin/git rev-parse refs/remotes/origin/master^{commit} # timeout=10
Checking out Revision 2716a24fa4bd546a6b0386d9a92a759b6929f674 (refs/remotes/origin/master)
 > /usr/bin/git config core.sparsecheckout # timeout=10
 > /usr/bin/git checkout -f 2716a24fa4bd546a6b0386d9a92a759b6929f674 # timeout=10
 > /usr/bin/git branch -a -v --no-abbrev # timeout=10
 > /usr/bin/git branch -D master # timeout=10
 > /usr/bin/git checkout -b master 2716a24fa4bd546a6b0386d9a92a759b6929f674 # timeout=10
Commit message: "feat: 测试类"
First time build. Skipping changelog.
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Jar包构建)
[Pipeline] sh
+ mvn clean install -Dmaven.test.skip=true
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------< com.jianjang.demo:jenkins-demo >-------------------
[INFO] Building jenkins-demo 1.0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ jenkins-demo ---
[INFO] Deleting /root/.jenkins/workspace/new-pipeline/target
[INFO] 
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ jenkins-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ jenkins-demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /root/.jenkins/workspace/new-pipeline/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ jenkins-demo ---
[INFO] Not copying test resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ jenkins-demo ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ jenkins-demo ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ jenkins-demo ---
[INFO] Building jar: /root/.jenkins/workspace/new-pipeline/target/jenkins-demo.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.3.1.RELEASE:repackage (repackage) @ jenkins-demo ---
[INFO] Replacing main artifact with repackaged archive
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ jenkins-demo ---
[INFO] Installing /root/.jenkins/workspace/new-pipeline/target/jenkins-demo.jar to /root/.m2/repository/com/jianjang/demo/jenkins-demo/1.0.1/jenkins-demo-1.0.1.jar
[INFO] Installing /root/.jenkins/workspace/new-pipeline/pom.xml to /root/.m2/repository/com/jianjang/demo/jenkins-demo/1.0.1/jenkins-demo-1.0.1.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  8.924 s
[INFO] Finished at: 2022-05-09T15:32:03+08:00
[INFO] ------------------------------------------------------------------------
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (docker镜像构建)
[Pipeline] sh
+ cp /root/.jenkins/workspace/new-pipeline/target/jenkins-demo.jar /root/.jenkins/workspace/new-pipeline/docker
[Pipeline] sh
+ mvn clean
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------< com.jianjang.demo:jenkins-demo >-------------------
[INFO] Building jenkins-demo 1.0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ jenkins-demo ---
[INFO] Deleting /root/.jenkins/workspace/new-pipeline/target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.411 s
[INFO] Finished at: 2022-05-09T15:32:09+08:00
[INFO] ------------------------------------------------------------------------
[Pipeline] sh
+ sudo docker build -f /root/.jenkins/workspace/new-pipeline/docker/Dockerfile -t jenkins-demo:1.0.1 ./docker/
Sending build context to Docker daemon   16.5MB

Step 1/9 : FROM java:8
 ---> d23bdf5b1b1b
Step 2/9 : MAINTAINER JianJang
 ---> Using cache
 ---> 2ec11b101878
Step 3/9 : LABEL name="jenkins-demo" version="1.0.0" author="JianJang"
 ---> Using cache
 ---> ea5bd996759a
Step 4/9 : VOLUME /tmp
 ---> Using cache
 ---> 8b927a674c5e
Step 5/9 : COPY jenkins-demo.jar /jenkins-demo.jar
 ---> c32360f23838
Step 6/9 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/jenkins-demo.jar"]
 ---> Running in 47e79fac4ba4
Removing intermediate container 47e79fac4ba4
 ---> 7d42a92f3d4f
Step 7/9 : ENV TZ=Asia/Shanghai
 ---> Running in f7a4c487f03c
Removing intermediate container f7a4c487f03c
 ---> 655f600a09ff
Step 8/9 : RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
 ---> Running in 40cdf826e12d
Removing intermediate container 40cdf826e12d
 ---> 03275f13a50b
Step 9/9 : EXPOSE 8081
 ---> Running in 9fb73a9a4cb9
Removing intermediate container 9fb73a9a4cb9
 ---> af55a3427295
Successfully built af55a3427295
Successfully tagged jenkins-demo:1.0.1
[Pipeline] echo
docker镜像构建
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (docker镜像上传)
[Pipeline] sh
+ sudo docker login --username=zhangjian20200721 --password=zwx112435 registry.cn-shanghai.aliyuncs.com
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[Pipeline] sh
+ sudo docker tag jenkins-demo:1.0.1 registry.cn-shanghai.aliyuncs.com/zhangjian_sh/jenkins-demo:1.0.1
[Pipeline] sh
+ sudo docker push registry.cn-shanghai.aliyuncs.com/zhangjian_sh/jenkins-demo:1.0.1
The push refers to repository [registry.cn-shanghai.aliyuncs.com/zhangjian_sh/jenkins-demo]
7e44f0803096: Preparing
31ef84129737: Preparing
35c20f26d188: Preparing
c3fe59dd9556: Preparing
6ed1a81ba5b6: Preparing
a3483ce177ce: Preparing
ce6c8756685b: Preparing
30339f20ced0: Preparing
0eb22bfb707d: Preparing
a2ae92ffcd29: Preparing
a3483ce177ce: Waiting
ce6c8756685b: Waiting
30339f20ced0: Waiting
0eb22bfb707d: Waiting
a2ae92ffcd29: Waiting
6ed1a81ba5b6: Layer already exists
35c20f26d188: Layer already exists
c3fe59dd9556: Layer already exists
ce6c8756685b: Layer already exists
a3483ce177ce: Layer already exists
30339f20ced0: Layer already exists
0eb22bfb707d: Layer already exists
a2ae92ffcd29: Layer already exists
7e44f0803096: Pushed
31ef84129737: Pushed
1.0.1: digest: sha256:f1e0a5b6d492ebbfdc6162f87187e3c93bc8d903325789592d7d7bd31ea03916 size: 2419
[Pipeline] sh
+ sudo docker logout registry.cn-shanghai.aliyuncs.com
Removing login credentials for registry.cn-shanghai.aliyuncs.com
[Pipeline] sh
+ sudo docker rmi -f jenkins-demo
Error: No such image: jenkins-demo
[Pipeline] echo
docker镜像上传
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (项目部署)
[Pipeline] sh
/root/.jenkins/workspace/new-pipeline@tmp/durable-e835ffbd/script.sh:行9: 警告:立即文档在第 2 行被文件结束符分隔 (需要 `reallsh')
+ sshpass -p zwx123456 ssh -p 22 -o StrictHostKeyChecking=no root@192.168.2.7
Pseudo-terminal will not be allocated because stdin is not a terminal.
Error: No such container: jenkins-demo
Error: No such image: registry.cn-shanghai.aliyuncs.com/zhangjian_sh/jenkins-demo:1.0.1
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

1.0.1: Pulling from zhangjian_sh/jenkins-demo
7448db3b31eb: Pulling fs layer
c36604fa7939: Pulling fs layer
29e8ef0e3340: Pulling fs layer
a0c934d2565d: Pulling fs layer
a360a17c9cab: Pulling fs layer
cfcc996af805: Pulling fs layer
2cf014724202: Pulling fs layer
4bc402a00dfe: Pulling fs layer
4dd75c1fd89c: Pulling fs layer
d362213e9a2c: Pulling fs layer
cfcc996af805: Waiting
2cf014724202: Waiting
4bc402a00dfe: Waiting
4dd75c1fd89c: Waiting
d362213e9a2c: Waiting
a0c934d2565d: Waiting
a360a17c9cab: Waiting
c36604fa7939: Verifying Checksum
c36604fa7939: Download complete
a0c934d2565d: Verifying Checksum
a0c934d2565d: Download complete
a360a17c9cab: Verifying Checksum
a360a17c9cab: Download complete
cfcc996af805: Verifying Checksum
cfcc996af805: Download complete
29e8ef0e3340: Verifying Checksum
29e8ef0e3340: Download complete
4bc402a00dfe: Verifying Checksum
4bc402a00dfe: Download complete
7448db3b31eb: Verifying Checksum
7448db3b31eb: Download complete
d362213e9a2c: Verifying Checksum
d362213e9a2c: Download complete
7448db3b31eb: Pull complete
c36604fa7939: Pull complete
29e8ef0e3340: Pull complete
a0c934d2565d: Pull complete
a360a17c9cab: Pull complete
cfcc996af805: Pull complete
4dd75c1fd89c: Verifying Checksum
4dd75c1fd89c: Download complete
2cf014724202: Verifying Checksum
2cf014724202: Download complete
2cf014724202: Pull complete
4bc402a00dfe: Pull complete
4dd75c1fd89c: Pull complete
d362213e9a2c: Pull complete
Digest: sha256:f1e0a5b6d492ebbfdc6162f87187e3c93bc8d903325789592d7d7bd31ea03916
Status: Downloaded newer image for registry.cn-shanghai.aliyuncs.com/zhangjian_sh/jenkins-demo:1.0.1
registry.cn-shanghai.aliyuncs.com/zhangjian_sh/jenkins-demo:1.0.1
08a078df58d4c68d340fbc06f15cba891a482d332a93ff0bd22442a1333bdf7b
Removing login credentials for registry.cn-shanghai.aliyuncs.com
[Pipeline] echo
项目部署
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

2.5、部署结果验证

登录应用服务器192.168.2.7查看部署情况,镜像及容器情况如下图:

image-20220509154210084

通过访问应用api接口进行验证服务是否部署成功

curl localhost:8081/hello

image-20220509154355005

经验证,服务部署成功。

3、参考资料