【问题标题】:Docker container rebuild inside of a projectDocker 容器在项目内部重建
【发布时间】:2022-07-07 21:47:34
【问题描述】:

我有一个具有以下结构的项目:

  • 码头工人/码头工人文件

  • linux/*.xz(内核源代码)

  • *.sh

  • 詹金斯文件

基本上,这个管道是在 docker 容器内构建一个 linux 内核。

我们将 bitbucket 与 jenkins 和 artifactory 结合用于 CI/CD。

目前 docker 镜像的构建是手动的:开发者在本地构建并推送到 artifactory。

管道仅拉取预构建的 docker 映像以供执行。

由于这种手动交互很烦人,因此应该自动化。

典型场景可能如下所示:开发人员更改 Dockerfile 和其他一些资源。

这要求我们首先重建容器,将其推送到工件,然后开始构建。

是否有使用上述技术的直接方法来做到这一点?

我的方法是(主要是自己的实现)根据 git 版本标记 docker 图像。

当上述管道启动时,它会查询上次更改的 Dockerfile 的 git-rev 并尝试拉取

容器。如果这是可能的 - 很好。否则运行“docker build”并推送新容器。然后在里面运行内核构建。

这是正确的做法吗?

【问题讨论】:

  • 据我了解,这有两个缺点:1)在每次管道运行时构建容器,这似乎有点多余和浪费时间。 2) 不可重现的构建,因为容器在每次运行时都会发生变化。我认为这是容器环境提供稳定条件的主要好处。
  • 如果您的 CI 系统以一致的方式构建它,使用签入存储库的源代码,那应该是相当可重现的。
  • 我的意思主要是 Dockerfile 中定义的工具。例如。 gcc, debootstrap, ...如果我不使用明确的版本,这些可能会以不同的方式工作,或者今天比明天输出其他二进制文件。

标签: docker jenkins bitbucket


【解决方案1】:

可能的选项如下。

选项 1

为了确定是否要构建新镜像,可以依赖 JenkinsChangeset。您可以检查 docker/Dockerfile 文件是否与上次构建相比发生了变化,如果是,则可以执行构建步骤或跳过它。

此外,在构建图像时,您可以创建两个图像标签。一个带有修订版(或任何其他唯一标识符),并将latest 标记替换为最新构建的图像。这将允许您在管道的连续步骤中拥有一个简单的逻辑,因为我们知道最新的构建映像位于最新的标签中。下面是示例管道。

pipeline {
    agent any

    stages {
        stage('BuildImage') {
            when { changeset "**/Dockerfile" }
            steps {
                script {
                 def image = docker.build("my-image:REVISION", "docker/Dockerfile")
                 image.push() // Pushes the tagged image with revision
                 image.push('latest') // Change the tag and push
                }
            }
        }
        
        stage('Other Build') {
            steps {
                 docker.image('my-image:latest').inside {
                    // Do other stuff within the Docker image
                }
            }
        }
        
        stage('Other Build option 2') {
            agent {
                docker { image 'node:16.13.1-alpine' }
            }
            steps {
                // Do other stuff within the Docker image
            }
        }
    }
}

选项 2

另一种选择是始终使用 Docker 文件启动新的 Jenkins 代理,或者始终构建映像,然后使用容器执行构建命令。如果您经常更改 Dockerfile,这可能会很有效。下面是示例管道。

pipeline {
    agent { dockerfile { dir 'docker' } }

        stage('Other Build') {
            steps {
                // Do other stuff within the Docker image
            }
        }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2022-06-13
    • 2023-01-10
    • 2017-01-19
    • 2022-01-09
    • 1970-01-01
    • 2018-07-17
    • 2014-03-28
    • 2021-11-05
    • 1970-01-01
    相关资源
    最近更新 更多