如何将文件从dockerfile复制到主机?
- 2024-10-25 08:42:00
- admin 原创
- 56
问题描述:
我想在 dockerfile 成功构建时获取一些文件,但它不会将文件从容器复制到主机。
这意味着当我构建dockerfile时,这些文件已经是主机了。
解决方案 1:
自 2019 年 7 月 Docker 19.03.0 引入“自定义构建输出”以来,这一点已成为可能。请参阅有关自定义构建输出的官方文档。
要在构建过程中将构建映像中的自定义构建输出启用到主机,您需要激活 BuildKit ,这是引擎执行构建阶段的一种较新的推荐向后兼容方式。请参阅官方文档以了解如何启用 BuildKit。
可以通过两种方式实现:
设置环境变量
DOCKER_BUILDKIT=1
,或者"features": { "buildkit": true }
通过添加到配置 json 的根目录,默认在 docker 引擎中设置它。
来自有关自定义构建输出的官方文档:
自定义导出器允许您将构建工件导出为本地文件系统上的文件而不是 Docker 镜像,这对于生成本地二进制文件、代码生成等非常有用。
...
本地导出器将生成的构建文件写入客户端的目录中。tar 导出器类似,但将文件写入单个 tarball (.tar)。
如果未指定类型,则该值默认为本地导出器的输出目录。
...
--output 选项会从目标阶段导出所有文件。仅导出特定文件的常见模式是进行多阶段构建,并使用 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
out/output.txt
这将生成由该命令创建的本地文件RUN
。
$ cat out/output.txt
hello world
所有文件均从目标阶段输出
该--output
选项将从目标阶段导出所有文件。因此,使用非临时阶段COPY --from
会导致无关文件被复制到输出。建议使用临时阶段COPY --from
。
目前不支持 Windows:
解决方案 2:
不支持将文件“从 Dockerfile”复制到主机。Dockerfile 只是指定如何构建映像的配方。
当你构建时,你有机会将文件从主机复制到你正在构建的图像(使用COPY
指令或ADD
)
您还可以使用docker cp将文件从容器(已被'd' 的图像docker run
)复制到主机(实际上,cp 也可以从主机复制到容器)
如果您想要将构建期间可能生成的一些文件返回到您的主机(例如调用生成 ssl的脚本),您可以运行一个容器,从您的主机挂载一个文件夹并执行 cp 命令。
例如,请参阅此getcrt 脚本。
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
在主机上进行复制!
解决方案 3:
虽然它不直接通过Dockerfile
功能支持,但您可以从构建的 docker 镜像中复制文件。
containerId=$(docker create example:latest)
docker cp "$containerId":/source/path /destination/path
docker rm "$containerId"
解决方案 4:
现在,使用 Docker 的插件buildx及其Local Exporter可以更轻松地实现此目的。
如果您已经按照 Docker 的教程安装了 Docker Engine 或 Desktop,那么 buildx 应该已经安装并激活为默认构建器。
它将所有内容从容器的根目录导出到主机上的本地路径,但您可以使用临时 Docker 映像进行多阶段构建来仅导出所需的内容:
#Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /build
COPY . .
RUN npm run build:doc
#Stage 2: Copy files to scratch image
FROM scratch AS export
COPY --from=builder /build/docs .
然后您需要做的就是构建--type=local, dest=<desired_path>
:
docker buildx build --output type=local,dest=. .
解决方案 5:
也许您可以将主机上的文件夹挂载为卷并将文件放在那里?通常,挂载的卷可以从容器内写入,除非您在挂载时指定只读选项。
docker run -v ${PWD}:/<somewritablepath> -w <somewritablepath> <image> <action>
解决方案 6:
使用Dockerfile完成Docker Build后,我做了以下工作:
其中/var/lib/docker/是Docker Root Dir:在我的设置中。
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
解决方案 7:
您也可以使用网络。从这个答案中的脚本开始:https ://stackoverflow.com/a/58255859/836450
我在主机上运行此脚本,将其放在我希望输出到的文件夹中
在我的docker里面有:
运行 apt-get install -y curl 运行 curl -F 'file=@/path/to/file' http://172.17.0.1:44444/
请注意,至少对我来说,在构建 dockerfile 时,172.17.0.1 始终是主机的 IP
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件