Jenkins 流水线构建 Docker 镜像
第一步:新建一个 Pipline JOB
第二步:新增 branch 变量
第三步:配置 pipeline 脚本
import java.util.UUID
// 模块名称
projectName = "gift-web"
// Git 仓库地址
reporsitoryURL = "https://gitee.com/bigcoder84/gift-web.git"
// 是否是多模块应用
multiModule = false
// 打包参数
mvnPackageParams = "-Dmaven.test.skip=true"
/***不需要配置的参数***/
// 工作区间路径
workspace = "/opt/jenkins-git/${JOB_NAME}"
// docker 仓库地址
dockerHost = "172.18.10.22:10001"
node{
stage("准备工作"){
dir(workspace){
// branch 是流水线定义的变量,用户在构建时会选择需要构建的分支
git branch: '${branch}', credentialsId: 'd1035200-6318-47e5-bd94-87ea83ea60ed', url: reporsitoryURL
// 获取当前分支最新的 commit hash
commitShortHash = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
println("commitShortHash: ${commitShortHash}")
// 获取当前分支最新的 commit 时间
commitTime = sh(returnStdout: true, script: "git show --pretty=format:'%ci' | head -1").trim()
println("commitTime: ${commitTime}")
// 此次构建的随机值
randomTag = UUID.randomUUID().toString().substring(0, 8)
println("randomTag: ${randomTag}")
// 镜像名称
dockerImageName = "${projectName}-${branch}"
// 镜像版本
dockerImageTag = "${commitShortHash}-${randomTag}"
println("imageName: ${dockerImageName}")
}
}
stage("构建 Maven"){
// maven 打包脚本
def packageScript
if (java.lang.Boolean.valueOf(multiModule)) {
// 多模块应用,只打包指定模块
packageScript = "mvn clean package -pl ./${projectName} -am ${mvnPackageParams}"
} else {
packageScript = "mvn clean package ${mvnPackageParams}"
}
dir(workspace){
sh "${packageScript}"
}
}
stage("构建镜像"){
dir(workspace){
// target 目录
def targetDir
if (java.lang.Boolean.valueOf(multiModule)) {
targetDir = "${workspace}/${projectName}/target"
} else {
targetDir = "${workspace}/target"
}
dir(targetDir){
// 打包完成 jar 的文件名称
def jarFileName = sh(returnStdout: true, script: "ls *.jar | head -1").trim()
// 构建 docker 镜像
sh "docker build -t ${dockerImageName}:${dockerImageTag} --build-arg JAR_FILE_NAME=${jarFileName} -f /opt/jenkins-git/dockerfile/dockerfile ."
}
}
}
stage("镜像推送"){
// 重命名 docker tag
sh "docker tag ${dockerImageName}:${dockerImageTag} ${dockerHost}/${dockerImageName}:${dockerImageTag}"
withCredentials([usernamePassword(credentialsId: 'docker-registry', passwordVariable: 'dockerPassword', usernameVariable: 'dockerUser')]) {
sh "docker login -u ${dockerUser} -p ${dockerPassword} http://${dockerHost}"
sh "docker push ${dockerHost}/${dockerImageName}:${dockerImageTag}"
}
}
stage("即将完成"){
// 上报构建结果
}
}
在脚本中经常会用到 ${}
去引用变量,这实际是 groovy 插值字符串的语法。
在 Groovy 中字符串有两种类型,一种是 Java 原生的 java.lang.String;另一种是 groovy.lang.GString,又叫插值字符串(interpolated strings)。
单引号字符串(Single quoted string)
在 Groovy 中,使用单引号括住的字符串就是 java.lang.String,不支持插值:
def name = 'yjiyjgie'
println name.class // class java.lang.String
三单引号字符串(Triple single quoted string)
使用三单引号括住字符串支持多行,也是 java.lang.String 实例,在第一个’‘’起始处加一个反斜杠\可以在新一行开始文本:
def strippedFirstNewline = '''line one line two line three '''
双引号字符串(Double quoted string)
如果双引号括住的字符串中没有插值表达式(interpolated expression),那它就是 java.lang.String;如是有插值表达式,那它就是 groovy.lang.GString:
def normalStr = "yjiyjige" // 这是一个 java.lang.String def interpolatedStr = "my name is ${normalStr}" // 这是一个 groovy.lang.GString
字符串插值(String interpolation)
在 Groovy 所有的字符串字面量表示中,除了单引号字符串和三单引号字符串,其他形式都支持字符串插值。字符串插值,也即将占位表达式中的结果最终替换到字符串相应的位置中:
def name = 'Guillaume' // a plain string def greeting = "Hello ${name}" // name 变量的值会被替换进去
在“准备工作”阶段,主要完成了代码拉取,和一些常用信息的获取。如果想要读取 pom 文件中的信息,可以安装 Pipeline Utility Steps 插件来获取 pom 信息。例如:version、artifictId
在 镜像构建 阶段,会依赖于 Dockerfile
文件,可以把该文件托管在 git 中,或者直接放在 jenkins 所在服务器的文件系统中,上述引用了 /opt/jenkins-git/dockerfile/dockerfile
文件。文件内容如下:
# 该镜像需要依赖的基础镜像
FROM openjdk:8
ARG JAR_FILE_NAME=libary
# 将当前目录下的 jar 包复制到 docker 容器的/目录下
COPY ${JAR_FILE_NAME} /www/app-boot.jar
# 声明服务运行在 8080 端口
EXPOSE 8080
# 指定 docker 容器启动时运行 jar 包
ENTRYPOINT ["java", "-jar","/www/app-boot.jar"]
# 指定维护者的名字
MAINTAINER bigcoder
在 即将完成 阶段,我们可以进行一些后处理,例如钉钉通知,因为 Pipeline 编写的是 groovy 脚本,所以可以在脚本中发起 http 请求,调用第三方平台,上报镜像版本信息。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Jenkins 配置参数构建
下一篇: 谈谈自己对于 AOP 的了解
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论