【发布时间】:2021-10-05 12:39:15
【问题描述】:
问题
我必须在 Jenkins(以及 DockerHub 作为 CD 目标)的帮助下为多个 Git 存储库配置 CI/CD。我在 Docker 多阶段构建的帮助下做到了这一点(请参阅注意事项)。我害怕误解/过度复杂化一个简单的想法。
Jenkins + Docker 多阶段构建 = 最佳/良好实践吗?我是否以正确的方式应用了这个想法?
注意事项
来自this presentation 我认为在 Jenkins 中使用 Docker 是个好主意。看了一篇文章Using Multi-Stage Builds to Simplify and Standardize Build Processes,Docker 多阶段构建看起来是使用 Jenkins + Docker 的下一步。
similar question 的回答还说 Docker 多阶段是有意义的,但没有提供实现示例。
实施
Jenkins 从 SCM 存储库创建管道。
Git 存储库
Dockerfile
Jenkinsfile
project-folder
|-src
|-pom.xml
Dockerfile
FROM alpine as source
RUN apk --update --no-cache add git
COPY project-folder repo
FROM maven:3.6.3-jdk-8 as test
COPY --from=source repo repo
WORKDIR repo
RUN mvn clean test
FROM maven:3.6.3-jdk-8 as build
COPY --from=test repo repo
WORKDIR repo
RUN mvn clean package
FROM openjdk:8 as final
MAINTEINER xxx <xxx@gmail.com>
LABEL owner="xxx"
COPY --from=build repo/target/some-lib-1.8.jar /usr/local/some-lib.jar
ENTRYPOINT ["java", "-jar", "/usr/local/some-lib.jar"]
Jenkins 文件
我使用docker build --target 来获得更精细的 Jenkins UI。
#!/usr/bin/env groovy
def imageId = "use-name/image-name:1.$BUILD_NUMBER"
pipeline {
agent {
label 'docker' # separate agent (launched as JAR on host machine) to avoid running docker inside docker
}
stages {
stage('Test') {
steps {
script {
sh "docker build --no-cache --target test -t ${imageId} ."
}
}
}
stage('Build') {
steps {
script {
sh "docker build --target build -t ${imageId} ."
}
}
}
stage('Image') {
steps {
script {
sh "docker build --target final -t ${imageId} ."
}
}
}
stage('Deploy') {
steps {
script {
docker.withRegistry('' , 'dockerhub') {
dockerImage = docker.build("${imageId}")
dockerImage.push()
}
}
}
}
stage('Clean') {
steps{
sh "docker rmi ${imageId}"
}
}
}
}
【问题讨论】:
-
是的,多阶段构建是目前的最佳实践。您的实现很好,但我个人认为在 Jenkinsfile 中拆分步骤没有多大意义,尤其是在您处理多个项目时。只需做一个完整的 docker 构建,如果出现故障 - 你会从日志中知道它发生在哪里。
-
@taleodor 非常感谢您的 asnwer!
-
我计划创建一个类似的设置。你是否从 docker 镜像构建中获取测试和覆盖数据,如果是,如何获取?