Docker如何添加文件而不将其提交给图像?

时间:2014-08-30 21:48:31

标签: docker dockerfile

我有一个~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

问题:ADD本地文件是否有解决办法而不会导致提交?

一种选择是在启动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 个答案:

答案 0 :(得分:15)

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

  

如果< src>是一种公认​​的压缩格式的本地tar存档   (identity,gzip,bzip2或xz)然后将其解压缩为目录。   远程URL中的资源不会被解压缩。当目录是   复制或解压缩,它具有与tar -x相同的行为:结果是   联盟:

     

1)目的地路径上存在的任何东西和2)目的地的内容   源代码树,冲突得到解决,有利于“2”。在逐个文件的基础上。

尝试:

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

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

使用Docker 17.05+,您可以使用multi-stage build来避免创建额外的层。

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/

答案 3 :(得分:0)

我现在可以想到3种选择。


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

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

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


选项2:使用多阶段构建。尽早提取文件,进行任何更改,然后将结果目录复制到最终阶段。对于任何不能使用BuildKit的构建引擎来说,这都是一个不错的选择。 augurar's answer covers this,所以我不会重复他已经拥有的相同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