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

时间:2015-10-27 19:39:02

标签: linux docker dockerfile

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

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

5 个答案:

答案 0 :(得分:20)

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

要想在构建过程中将结果从构建映像输出到主机中,您需要激活 BuildKit ,这是一种较新的建议向后兼容的引擎方式完成构建阶段。请参阅enabling BuildKit的官方文档。

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

  1. 设置环境变量DOCKER_BUILDKIT=1
  2. 默认情况下,通过在配置json的根目录中添加"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 directiveADD

您还可以使用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