🏆(不要错过!)【CI/CD技术专题】「Jenkins实战系列」(3)Jenkinsfile+DockerFile实现自动部署
每日一句
没有人会因学问而成为智者。学问或许能由勤奋得来,而机智与智慧却有懒于天赋。
前提概要
- Jenkins下用DockerFile自动部署Java项目,项目的部署放心推向容器化时代机制。
- 本节需要对jenkinsfile有点了解,对dockerfile有点了解,对shell有点了解,对docker有点了解
环境准备
新建-构建一个Maven项目

需要提一下,现在新安装的没有这个选项,需要在插件里安装一下 Maven Integration


java配置,其他配置查看以前文章

发布到服务器,DockerFile部署自动构建
Publish SSH配置

执行流程
- jenkins拉取代码仓库中的代码
- jenkins执行jenkinsfile文件(可指定文件名)
- 先在jenkins所在的服务器将拉取的项目build成docker镜像
- 将镜像发布到镜像仓库
- 在应用服务器的节点上将该镜像拉取下来(私有仓库需要用户名/密码)
- 在应用服务器上执行该镜像
jenkins配置
创建一个Pipeline SCM项目 jenkins项目名为sample-tezst (和发布的工程名保持一致)

Definition选择 【Pipeline Script from SCM】
Branch Specifier(blank for 'any'):选择分支
Additional Behaviours: 添加邮箱通知的发送者
Script Path: 填写使用项目中的Jenkinsfile文件的名字
应用工程配置
在工程的根目录下创建Dockerfile文件和Jenkins_docker文件
jenkinsfile_docker文件内容如下:
docker集成docker部署
pipeline {
agent {label 'master'}
tools{
maven 'maven'
}
environment {
GIT_PROJECT_ADDR="git@gitee.com:uncleqiao/springboot-test.git" //项目的git地址
JENKINS_WORKSPACE="/root/.jenkins/workspace" //jenkins存放文件的地址
PROJECT_NAME="${JOB_NAME}" // 项目名
JAR_NAME="sample-tezst-0.0.1-SNAPSHOT.jar" // 项目生成的jar的名字
IMAGE_NAME="sample-tezst" // 镜像名一般和项目名相同
IMAGE_ADDR="repository/qiao_namespace/${IMAGE_NAME}" // 镜像的位置
VERSION_ID="${BUILD_ID}"
}
stages {
stage('pullCode'){
steps{
echo 'This is a pullCode step'
//git branch: "${BRANCH}", credentialsId: '1001', url: "${GIT_PROJECT_ADDR}"
checkout scm
}
}
stage('Build') {
steps{
echo 'This is a Build step'
// 在有Jenkinsfile同一个目录下(项目的根目录下)
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
// 创建目录(如果不存在),并把jar文件上传到该目录下
stage('ssh') {
steps{
echo 'push jar to target server'
sh '''
ole_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'`
if [[ -n "${ole_image_id}" ]]; then
docker rmi -f ${ole_image_id}
fi
docker build -f Dockerfile --build-arg jar_name=${JAR_NAME} -t ${IMAGE_NAME}:${VERSION_ID} .
new_image_id=`docker images|grep ${IMAGE_NAME}|grep ${VERSION_ID}|awk '{print $3}'`
sudo docker tag ${new_image_id} ${IMAGE_ADDR}:${VERSION_ID}
sudo docker push ${IMAGE_ADDR}:${VERSION_ID}
'''
}
}
stage('run') {
// 在应用服务器节点 test
agent {
node {
label 'test'
//customWorkspace "${SERVER_TARGET_PATH}" //此参数会初始化目录 注意填写
}
}
options {
// 不让它切换到节点上自动从仓库拉取项目
skipDefaultCheckout()
}
steps {
echo 'pull image and docker run'
withEnv(['JENKINS_NODE_COOKIE=dontKillMe']) {
sh '''
sudo docker login --username=yourusername --password=yourpassword ccr.ccs.tencentyun.com
sudo docker pull ${IMAGE_ADDR}:${VERSION_ID}
container_id=`docker ps|grep ${IMAGE_ADDR}:${VERSION_ID}|awk '{print $1}'`
if [ -n "${container_id}" ]; then
docker rm -f "${container_id}"
fi
old_pid=`ps -ef|grep ${JAR_NAME}|grep -v grep|awk '{print $2}'`
if [[ -n $old_pid ]]; then
kill -9 $old_pid
fi
old_image=`docker images|grep ${IMAGE_ADDR}|grep ${VERSION_ID}`
if [[ -n $old_image ]]; then
old_image_id=`echo ${old_image}|awk '{print $3}'`
docker rmi -f ${old_image_id}
fi
sudo docker run --name "${PROJECT_NAME}_${VERSION_ID}" -p 9001:8081 -d ${IMAGE_ADDR}:${VERSION_ID}
'''
}
}
}
}
}
注意:
if [ -n str ] 这个命令在使用的时候如果str为空,也是true,可以使用 if [ -n ${str} -a "${str}x" != "x" ]或者使用if [[ -n ${str} ]]来判断
shell语法中,$()` 和 `` (两个单引号) 可以在子shell中执行命令,但是这儿$()不支持
idea没有jenkinsfile的语法提示,很容易出错,这个很难受
步骤一:拉取项目 在【pullCode】步骤中
checkout scm , 这个scm是创建jenkins流水线时选择的,属于特殊变量,代表了你的仓库信息,自动从仓库中获取项目
步骤二: 【Build】
将拉取下来的项目进行编译并打包
步骤三:【build_image】
将打包好的项目build成docker镜像,然后推送到镜像仓库(这里可以分成两步)
获取已经存在的镜像
ole_image_id=`docker images| grep ${IMAGE_NAME} | grep ${VERSION_ID}|awk '{print $3}'`
删掉存在的镜像
if [[ -n "${ole_image_id}" ]]; then
docker rmi -f ${ole_image_id}
fi
- 通过项目根目录下的Dockerfile来构建镜像
- -f:[filename] --build-arg <key=value> 给Dockerfile传递参数
- -t:镜像的名称:版本 这里我将jenkins的构建次数当作镜像的版本
docker build -f Dockerfile --build-arg jar_name=${JAR_NAME} -t ${IMAGE_NAME}:${VERSION_ID} .
获取构建好的镜像的id
new_image_id=`docker images | grep ${IMAGE_NAME} | grep ${VERSION_ID} | awk '{print $3}'`
根据生成的镜像,tag出一个名称空间不同的镜像
sudo docker tag ${new_image_id} repoistory/qiao_namespace/${IMAGE_NAME}:${VERSION_ID}
将镜像仓库能够识别的镜像推送到仓库
sudo docker push repoistory/qiao_namespace/${IMAGE_NAME}:${VERSION_ID}
步骤四:【run】
应用服务器拉取项目并且运行, 这一步要选择节点(应用服务器,如果是集群,就不用节点用scp登陆吧)
登陆到镜像仓库
sudo docker login --username=yourusername --password=yourpassword repository
从仓库中拉取刚才生成的镜像
sudo docker pull repository/qiao_namespace/${IMAGE_NAME}:${VERSION_ID}
查看已经存在的容器, 存在则删掉 存在则删掉 这里应该是一个数组,有点小问题,待修改
container_id=`docker ps | grep ${IMAGE_ADDR}:${VERSION_ID} | awk '{print $1}'`
if [ -n "${container_id}" ]; then
docker rm -f "${container_id}"
fi
查看已经运行的同版本的项目, 存在则删掉
pid=`ps -ef | grep ${JAR_NAME}| grep -v grep | awk '{print $2}'`
if [[ -n $pid ]]; then
kill -9 $pid
fi
查看已经存在的镜像
old_image=`docker images|grep ${IMAGE_ADDR}|grep ${VERSION_ID}`
if [[ -n $old_image ]]; then
old_image_id=`echo ${old_image}|awk '{print $3}'`
docker rmi -f ${old_image_id}
fi
运行容器
sudo docker run --name "${PROJECT_NAME}_${VERSION_ID}" -p 9001:8081 -d ${IMAGE_ADDR}:${VERSION_ID}
Dockerfile
文件内容如下
FROM repository/qiao_namespace/myjdk8:v1
默认jar包的名字 注意分隔符为 :- 这里是由jenkinsfile中build dockerfile时传递过来的
ARG jar_name={jar_name:-sample-teszt-0.0.1-SNAPSHOT.jar}
RUN 用于容器内部执行命令
RUN mkdir -p /usr/local/project
WORKDIR /usr/local/project
将项目放到/usr/local/project下
COPY ./target/sample-teszt-0.0.1-SNAPSHOT.jar ./
EXPOSE 8081
CMD java -jar -Dserver.port=8081 springboot-test-0.0.1-SNAPSHOT.jar
执行完毕后我们登陆到应用服务器,看到容器已经启动
🏆(不要错过!)【CI/CD技术专题】「Jenkins实战系列」(3)Jenkinsfile+DockerFile实现自动部署的更多相关文章
- 🏆【CI/CD技术专题】「Docker实战系列」(1)本地进行生成镜像以及标签Tag推送到DockerHub
背景介绍 Docker镜像构建成功后,只要有docker环境就可以使用,但必须将镜像推送到Docker Hub上去.创建的镜像最好要符合Docker Hub的tag要求,因为在Docker Hub注册 ...
- CI/CD之Gitlab集成Jenkins多分支pipeline实现质量检测和自动发布
本次实施主要实现: 代码提交gitlab,自动触发Jenkins构建 gitlab发起Merge Request, 需要Jenkins检查通过才可以merge,实现代码review和质量管控 gitl ...
- Jenkins介绍和安装及配合GitLab代码自动部署
Jenkins是什么? 基于JAVA的开源的自动化系统平台 加速自动化CI,CD任务及流水线,所有类型的任务:构建,测试,部署等 丰富的插件生态系统支持功能扩展,1400+插件和SCM,测试,通知,报 ...
- 「Netty实战 02」手把手教你实现自己的第一个 Netty 应用!新手也能搞懂!
大家好,我是 「后端技术进阶」 作者,一个热爱技术的少年. 很多小伙伴搞不清楚为啥要学习 Netty ,今天这篇文章开始之前,简单说一下自己的看法: @ 目录 服务端 创建服务端 自定义服务端 Cha ...
- CI/CD版本回滚Jenkins解决方案
一.创建项目 填写项目名,关系到项目路径对应请谨慎命名 二.项目配置 1.配置字符串参数和选项参数 2.代码仓库配置 3.构建环境 4.构筑脚本配置 5.点击左下方的保存或者应用 三.使用方法 1.发 ...
- 【Java技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路
序列化和反序列化 序列化就是指把对象转换为字节码: 对象传递和保存时,保证对象的完整性和可传递性.把对象转换为有字节码,以便在网络上传输或保存在本地文件中: 反序列化就是指把字节码恢复为对象: 根据字 ...
- 【分布式技术专题】「OSS中间件系列」Minio的文件服务的存储模型及整合Java客户端访问的实战指南
Minio的元数据 数据存储 MinIO对象存储系统没有元数据数据库,所有的操作都是对象级别的粒度的,这种做法的优势是: 个别对象的失效,不会溢出为更大级别的系统失效. 便于实现"强一致性& ...
- 【Netty技术专题】「原理分析系列」Netty强大特性之ByteBuf零拷贝技术原理分析
零拷贝Zero-Copy 我们先来看下它的定义: "Zero-copy" describes computer operations in which the CPU does n ...
- 【SpringCloud技术专题】「Gateway网关系列」(3)微服务网关服务的Gateway全流程开发实践指南(2.2.X)
开发指南须知 本次实践主要在版本:2.2.0.BUILD-SNAPSHOT上进行构建,这个项目提供了构建在Spring生态系统之上API网关. Spring Cloud Gateway的介绍 Spri ...
随机推荐
- Golang通过反射拼接一个结构体所有字段
golang通过反射拼接一个结构体所有字段 需求 将一个结构体所有字段以"|"连接拼接成字符串 golang 不同类型拼接成string使用Sprintf比较麻烦,如果一个结构体有 ...
- 精尽Spring Boot源码分析 - 支持外部 Tomcat 容器的实现
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- 测试开发:推荐一款阿里最新 Python 自动化开源工具!
大家好,我是麦小米,是狂师老师全栈测开训练营中的一名学员. 如果之前做过iOS自动化的同学相信都知道,一直以来,iOS自动化的实现&执行都必须依赖 Mac 系统,其主要原因是因为需要通过 xc ...
- Python | 更换pip源到国内镜像
pip国内的一些镜像 阿里云 https://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simpl ...
- Series 1 java秒组合数
Series 1 举几个例子发现, 系数中间对称,很容易想到组合数 c(n,m)==c[n,n-m).此题就是高精度求组合数,java秒之. time:1825ms ,接近时限,如果n还稍微大一 ...
- 13.7Cloneable接口
要点提示:Cloneable接口给出了一个可克隆对象.
- 企业如何通过CRM系统使销售周期缩短
企业为什么要缩短销售周期?因为这意味着可以节约更多开支,从而达到企业利润最大化.但是有不少企业尤其是B2B行业,销售周期都在三个月以上.通过调查发现,很多企业在客户信息和销售管道上缺乏管理和策略.Zo ...
- 不带Anchors和NMS的目标检测
前言: 目标检测是计算机视觉中的一项传统任务.自2015年以来,人们倾向于使用现代深度学习技术来提高目标检测的性能.虽然模型的准确性越来越高,但模型的复杂性也增加了,主要是由于在训练和NMS后处理过 ...
- 《Do Neural Dialog Systems Use the Conversation History Effectively? An Empirical Study》
https://zhuanlan.zhihu.com/p/73723782 请复制粘贴到markdown 查看器查看! Do Neural Dialog Systems Use the Convers ...
- Macbook(M1版)的用户看过来,.net 6 Preview 6支持Apple Silicon for macOS
本文由葡萄城技术团队翻译 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 我们很高兴发布.NET6预览的第6版,本次预览是倒数第二次预览了.在本次预览发布之 ...