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

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

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

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

情况1

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

docker run --rm --interactive=true --tty=true $IMAGE make

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

cannot enable tty mode on non tty input

案例2

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

docker run --rm $IMAGE make

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

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

问题

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

不能使用任何 Jenkins 插件,因为 Docker 调用位于脚本内部,无法轻松提取。

答案1

在 Jenkins 中运行 docker 构建的最简单方法是使用管道作业。它有很多内置插件可以控制你的 Docker 环境和容器。

几个例子是

    docker.image("image-name").run() -Runs the container from the image 
    docker.image("image-name").inside(){//your commands} -Runs your commands inside the docker container and also removes your container as soon as your commands are executed.

更多信息:https://www.cloudbees.com/blog/orchestrating-workflows-jenkins-and-docker

答案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

有关使用此工作流程的真实示例,您可以查看此.travis.yml文件,实际的CI 脚本, 这脚本在容器内运行码头工人文件所使用的图像。

相关内容