10

我有一个约 300Mb 的压缩本地文件,我将其添加到 docker 映像中。然后下一个状态提取图像。

问题是 ADD 语句导致提交导致新的文件系统层使图像比它需要的大约 300Mb。

ADD /files/apache-stratos.zip /opt/apache-stratos.zip
RUN unzip -q apache-stratos.zip && \
    rm apache-stratos.zip && \
    mv apache-stratos-* apache-stratos

问题:是否有解决方法来添加本地文件而不导致提交?

一种选择是在启动 docker 构建之前运行一个简单的 Web 服务器(例如python -m SimpleHTTPServer),然后使用wget它来检索文件,但这似乎有点混乱:

RUN wget http://localhost:8000/apache-stratos.zip && \
    unzip -q apache-stratos.zip && \
    rm apache-stratos.zip && \
    mv apache-stratos-* apache-stratos

另一种选择是在容器启动而不是构建时提取压缩文件,但我希望尽可能快地启动。

4

4 回答 4

13

根据文档,如果您将本地文件系统(不是 URL)中的存档文件传递到 Dockerfile 中的 ADD(带有目标路径,而不是路径 + 文件名),它会将文件解压缩到给定的目录中。

如果 <src> 是可识别压缩格式(identity、gzip、bzip2 或 xz)的本地 tar 存档,则将其解压缩为目录。来自远程 URL 的资源不会被解压缩。当一个目录被复制或解包时,它的行为与 tar -x 相同:结果是以下内容的并集:

1) 目标路径中存在的任何内容和 2) 源树的内容,冲突已解决,有利于“2”。逐个文件。

尝试:

ADD /files/apache-stratos.zip /opt/

并查看文件是否存在,无需进一步解压缩。

于 2014-08-30T22:41:20.507 回答
5

使用 Docker 17.05+,您可以使用多阶段构建来避免创建额外的层。

FROM ... as stage1
# No need to clean up here, these layers will be discarded
ADD /files/apache-stratos.zip /opt/apache-stratos.zip
RUN unzip -q apache-stratos.zip
    && mv apache-stratos-* apache-stratos

FROM ...
COPY --from=stage1 apache-stratos/ apache-stratos/
于 2019-02-27T00:12:31.667 回答
3

您可以使用docker-squash来压缩新创建的图层。这应该会显着减小图像大小。

不幸的是,提到的解决方法(RUN curl ... && unzip ... & rm ...,在容器启动时解包)是目前唯一的选择(docker 1.11)。

于 2016-05-31T10:16:21.920 回答
1

目前我能想到的有3个选项。


选项 1:您可以从 zip 文件切换到 tar 或压缩的 tar 格式,然后允许ADD为您解压缩文件。

ADD /files/apache-stratos.tgz /opt/

唯一的缺点是任何其他更改,例如目录重命名,都会在再次写入时触发复制,因此您需要确保您的 tar 文件具有最终目录结构中的内容。


选项 2:使用多阶段构建。在早期阶段提取文件,执行任何更改,然后将生成的目录复制到最后阶段。对于任何无法使用 BuildKit 的构建引擎来说,这是一个不错的选择。augurar 的回答涵盖了这一点,所以我不会重复他已经拥有的同一个 Dockerfile。


选项 3:BuildKit(在 18.09 和更新版本中可用)允许您在RUN命令中从其他位置(包括您的构建上下文)挂载文件。这目前需要实验语法。生成的 Dockerfile 如下所示:

# syntax=docker/dockerfile:experimental
FROM ...
...
RUN --mount=type=bind,source=/files/apache-stratos.zip,target=/opt/apache-stratos.zip \
    unzip -q apache-stratos.zip && \
    rm apache-stratos.zip && \
    mv apache-stratos-* apache-stratos

然后要构建它,您在运行构建之前导出一个变量(您也可以将它导出到您的 .bashrc 或等效文件中):

DOCKER_BUILDKIT=1 docker build -t your_image .

有关 BuildKit 实验功能的更多详细信息,请访问:https ://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md

于 2019-06-06T19:19:47.837 回答