如何将文件从 dockerfile 复制到主机?

How to copy files from dockerfile to host?

我想在 dockerfile 构建成功时获取一些文件,但它不会将文件从容器复制到主机。

这意味着当我构建 dockerfile 时,文件已经是宿主。

复制文件 "from the Dockerfile" 到主机 支持。 Dockerfile 只是一个指定如何构建镜像的配方。

构建时,您有机会将文件从主机复制到您正在构建的映像(使用 COPY directive or ADD

您还可以将文件从 容器(已 docker run 处理过的图像)复制到 docker cp 的主机(实际上, cp 也可以从主机复制到容器)

如果您想将构建期间可能生成的一些文件返回给您的主机(例如 calling a script that generates ssl),您可以 运行 一个容器,从您的文件夹中安装一个文件夹主机和执行 cp 命令。

例如,参见 getcrt script

docker run -u root --entrypoint=/bin/sh --rm -i -v ${HOME}/b2d/apache:/apache apache << COMMANDS
pwd
cp crt /apache
cp key /apache
echo Changing owner from $(id -u):$(id -g) to $(id -u):$(id -u)
chown -R $(id -u):$(id -u) /apache/crt
chown -R $(id -u):$(id -u) /apache/key
COMMANDS

COMMANDS 之间的所有命令都是在容器上执行的命令,包括 cp 在主机 ${HOME}/b2d/apache 文件夹上复制的命令,作为 /apache 安装在容器内-v ${HOME}/b2d/apache:/apache.

这意味着每次在容器中复制 /apache 上的任何内容时,实际上是在主机上复制 ${HOME}/b2d/apache

也许您可以将主机上的文件夹挂载为一个卷并将文件放在那里?通常可以从容器内写入已安装的卷,除非您在安装时指定只读选项。

docker run -v ${PWD}:/<somewritablepath> -w <somewritablepath> <image> <action>

尽管 Dockerfile 功能不直接支持它,但您可以从内置的 docker 图像复制文件。

containerId=$(docker create example:latest)
docker cp "$containerId":/source/path /destination/path
docker rm "$containerId"

自从 2019 年 7 月的 Docker 19.03.0 引入了“自定义构建输出”以来,这现在是可能的。请参阅有关 custom build outputs.

的官方文档

要在构建过程中启用从构建映像到主机的自定义构建输出,您需要激活 BuildKit,这是为引擎推荐的一种较新的向后兼容方式做构建阶段。请参阅 enabling BuildKit.

的官方文档

这可以通过两种方式完成:

  1. 设置环境变量DOCKER_BUILDKIT=1,或者
  2. 默认情况下在 docker 引擎中设置它,方法是将 "features": { "buildkit": true } 添加到配置的根目录 json。

来自关于custom build outputs的官方文档:

custom exporters allow you to export the build artifacts as files on the local filesystem instead of a Docker image, which can be useful for generating local binaries, code generation etc.

...

The local exporter writes the resulting build files to a directory on the client side. The tar exporter is similar but writes the files as a single tarball (.tar).

If no type is specified, the value defaults to the output directory of the local exporter.

...

The --output option exports all files from the target stage. A common pattern for exporting only specific files is to do multi-stage builds and to copy the desired files to a new scratch stage with COPY --from.

例如一个例子 Dockerfile

FROM alpine:latest AS stage1
WORKDIR /app
RUN echo "hello world" > output.txt

FROM scratch AS export-stage
COPY --from=stage1 /app/output.txt .

运行

DOCKER_BUILDKIT=1 docker build --file Dockerfile --output out .

输出的尾部是:

 => [export-stage 1/1] COPY --from=stage1 /app/output.txt .
0.0s
 => exporting to client
0.1s
 => => copying files 45B
0.1s

这会生成一个由 RUN 命令创建的本地文件 out/output.txt

$ cat out/output.txt
hello world

所有文件都从目标阶段输出

--output 选项将从目标阶段导出 所有 文件。因此,使用带 COPY --from 的非临时阶段将导致无关文件被复制到输出。建议使用带有 COPY --from.

的临时阶段

使用 Dockerfile 完成 Docker Build 后,以下对我有效:

其中 /var/lib/docker/Docker 根目录: 在我的设置中。

sudo find /var/lib/docker/ -name DESIRED_FILE -type f | xargs sudo ls -hrt | tail -1 | grep tgz | xargs  -i  sudo cp -v  '{}' PATH_ON_HOST

您也可以使用网络。从这个答案的脚本开始:

  • 我 运行 我主机上的这个脚本在我希望输出的文件夹中

  • 在我的docker里面我有:

    运行 apt-get install -y curl 运行 curl -F 'file=@/path/to/file' http://172.17.0.1:44444/

请注意,至少对我而言,172.17.0.1 始终是构建 docker 文件

时主机的 IP