我想在dockerfile成功构建时获取一些文件,但它不会将文件从容器复制到主机。
这意味着当我构建了dockerfile时,文件已经是主机。
答案 0 :(得分:20)
自2019年7月Docker 19.03.0引入“自定义构建输出”以来,现在这是可能的。请参阅有关custom build outputs的官方文档。
要想在构建过程中将结果从构建映像输出到主机中,您需要激活 BuildKit ,这是一种较新的建议向后兼容的引擎方式完成构建阶段。请参阅enabling BuildKit的官方文档。
这可以通过两种方式完成:
DOCKER_BUILDKIT=1
"features": { "buildkit": true }
来在docker引擎中进行设置。摘自有关custom build outputs的官方文档:
自定义导出器允许您将构建工件导出为本地文件系统上的文件,而不是Docker映像,这对于生成本地二进制文件,代码生成等非常有用。
...
本地导出器将生成的生成文件写入客户端的目录中。 tar导出器与此类似,但是将文件作为单个tarball(.tar)写入。
如果未指定任何类型,则该值默认为本地导出器的输出目录。
...
仅导出特定文件的常见模式是执行多阶段构建,然后使用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
答案 1 :(得分:5)
构建时,您可以将文件从主机复制到您正在构建的图像(使用COPY
directive或ADD
)
您还可以使用docker cp将文件从容器(已docker run
'd的图像)复制到主机(通常,cp可以从也是容器的主机)
但你无法复制“来自Dockerfile”:Dockerfile只是一个指定如何构建图像的配方。
如果您想要回复主机中某些可能在构建期间生成的文件(例如calling a script 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
1}}。
这意味着每次您在容器中的${HOME}/b2d/apache
上复制任何内容时,实际上是在主机上复制<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/dialog_margin_title"
android:layout_marginBottom="@dimen/dialog_margin"
android:layout_marginLeft="@dimen/dialog_margin"
android:layout_marginStart="@dimen/dialog_margin"
android:layout_marginRight="@dimen/dialog_margin"
android:layout_marginEnd="@dimen/dialog_margin"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Please enter the email address of the person you would like to follow, this person will be notified." />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textEmailAddress" />
</LinearLayout>
</FrameLayout>
!
答案 2 :(得分:2)
尽管Dockerfile
功能不直接支持它,但是您可以从内置的Docker映像中复制文件。
containerId=$(docker create example:latest)
docker cp "$containerId":/source/path /destination/path
docker rm "$containerId"
答案 3 :(得分:1)
也许您可以将主机上的文件夹作为卷挂载并放在其中?除非您在安装时指定了只读选项,否则通常可以从容器内写入已安装的卷。
docker run -v ${PWD}:/<somewritablepath> -w <somewritablepath> <image> <action>
答案 4 :(得分:0)
使用 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