Docker 中的 Jenkins:关于管道中绑定挂载的说明

Jenkins in Docker: clarification about bind mounts in pipelines

我在 Docker 容器中 运行ning Jenkins。在 article 之后,我将绑定安装 Docker 套接字,以便从 dockerized Jenkins 与其进行交互。我还绑定安装容器目录 jenkins_home。这是我的卷的快速回顾:

# Jenkins
volumes:
  - /var/run/docker.sock:/var/run/docker.sock:ro
  - /usr/local/bin/docker-compose:/usr/local/bin/docker-compose
  - ./bar:/var/jenkins_home

我运行这个来自主机的目录/home/foo/,因此在主机文件系统中创建(并挂载)以下目录:

/home/foo/bar

现在,我有一个 Jenkins 管道 (mypipe),它 运行 是一个 docker-compose 文件,它启动了一个具有以下体积的 MySQL 容器:

# MySQL created from Jenkins
volumes:
  - ./data:/var/lib/mysql

奇怪的是,它最终安装了:

/var/jenkins_home/workspace/mypipe/data < /var/lib/mysql

而不是:

/home/foo/bar/workspace/mypipe/data < /var/lib/mysql

这是一个图形回顾:

正在搜索 Whosebug, 它发生于:

The volume source path (left of :) does not refer to the middle container, but to the host filesystem!

没关系,但我的问题是:

为什么?

我的意思是为什么 .data 翻译 正好进入路径:/var/jenkins_home/workspace/…/data,因为 MySQL 容器不知道路径 /var/jenkins_home?

当Docker创建绑定挂载时,它总是从主机文件系统中的绝对路径到容器文件系统中的绝对路径。

当您的 docker-compose.yml 命名一个相对路径时,Compose 首先扩展该路径,然后再将其传递给 Docker 守护程序。在您的示例中,您尝试从文件 /var/jenkins_home/workspace/mypipe/docker-compose.yml 绑定挂载 ./bar,因此 Compose 会填写您在调用 Docker API 时看到的绝对路径。 Compose 不知道当前目录实际上是来自 Docker 守护程序上下文中不同路径的绑定挂载。

如果您在 Jenkins 日志中查看像 docker.inside { ... } 这样的脚本化管道调用所做的事情,请将工作区目录安装到它启动的容器内的相同路径。解决您遇到的映射问题的最简单方法可能是在主机系统上使用相同的 /var/jenkins_home 路径,因此文件系统路径在每个上下文中都是相同的。