如何在 Jenkins 的 Docker 容器中运行构建

mar*_*v81 19 tty jenkins pty docker

我正在尝试使用 Jenkins 在 Docker 容器中构建 C++ 项目。我在 Jenkins 中构建或在 Jenkins 之外的容器中构建都没有问题。

以下是我尝试过的。为清楚起见,我省略了卷映射。

情况1

以下命令在 shell 中成功运行构建。

docker run --rm --interactive=true --tty=true $IMAGE make
Run Code Online (Sandbox Code Playgroud)

但是,当在 Jenkins 中作为“执行 shell”步骤运行时,Docker 会返回以下错误。

cannot enable tty mode on non tty input
Run Code Online (Sandbox Code Playgroud)

案例二

以下命令与前一个命令类似,但禁用交互性。

docker run --rm $IMAGE make
Run Code Online (Sandbox Code Playgroud)

Jenkins 可以成功运行构建。但是,在中止构建时会出现严重的问题。构建会立即标记为中止,但容器会继续运行,直到构建完成。退出后容器也不会被移除。

在 shell 中运行时,命令会成功构建,但无法中断它。退出后容器也会被移除。

有谁知道如何在 Jenkins 的 Docker 容器中干净地运行构建并保留中止构建的能力?

使用任何 Jenkins 插件都不是一种选择,因为 Docker 调用在脚本内部并且无法轻松提取。

max*_*zig 2

您可以实施以下工作流程:

  1. 创建一个 docker 容器并指定一个名称,以便您可以轻松引用它(例如在脚本中)
  2. 启动它并使用某些东西作为保持容器运行的入口点
  3. 用于docker exec container cmd ...发出构建和测试命令
  4. 停止容器
  5. 删除图像

docker exec ...就像对网络机器的远程 shell 访问。默认情况下,它不是交互式的,也不分配 tty。这对于编译和执行测试套件应该没问题。该命令正确转发容器内执行的命令的退出状态。

然后可以通过以下方式中止构建作业:

  • docker stop container(发送 TERM 和 KILL 并在中间等待),或者
  • docker kill container, 甚至
  • docker exec container pkill someexecutable

具体命令的工作流程:

$ docker create --name cxx-devel \
    -v $HOME/src:/srv/src:ro -v $HOME/build:/srv/build \
    gsauthof/fedora-cxx-devel:23
$ docker start cxx-devel     # <- entrypoint is /usr/bin/sleep infinity
$ docker exec cxx-devel /srv/src/projecta/build.sh
$ docker exec cxx-devel /srv/src/projecta/check.sh
$ docker stop cxx-devel
$ docker rm cxx-devel
Run Code Online (Sandbox Code Playgroud)

对于使用此工作流程的真实示例,您可以查看此.travis.yml文件、实际的CI 脚本容器内运行的脚本以及所用映像的docker 文件。