如何在不使用ADD或COPY指令的情况下将文件添加到Dockerfile中的图像

时间:2014-11-01 20:07:17

标签: docker

我需要*.zip容器中的大Docker文件(5 gb)的内容才能编译程序。 *.zip文件驻留在我的本地计算机上。对此的策略是:

COPY program.zip /tmp/
RUN cd /tmp \
&& unzip program.zip \
&& make

完成此操作后,我想删除解压缩的目录和原始的*.zip文件,因为它们不再需要了。问题是COPY(以及ADD指令)会在包含文件program.zip的图像中添加一个图层,这是有问题的,因为图像可能至少有5gb大。有没有办法在不使用COPYADD指令的情况下将文件添加到容器中? wget无法正常工作,因为我提及的*.zip文件位于我的本地计算机上,curl file://localhost/home/user/program.zip -o /tmp/program.zip也无效。

4 个答案:

答案 0 :(得分:18)

这不是直截了当的,但可以通过wgetcurlpython的支持下完成。 (这三个工具通常应该在*nix系统上使用。)

如果没有wget并且

url将无效

 curl file://localhost/home/user/program.zip -o /tmp/

无法在Dockerfile的{​​{1}}指令中使用。因此,我们需要一个RUNwget可以访问并从中下载curl的服务器。

为此,我们设置了一个服务于program.zip请求的python服务器。我们将使用http中的http.server模块进行此操作。 (您可以使用pythonpython。它可以同时使用。)。

python 3

python -m http.server --bind 192.168.178.20 8000 服务器将为其启动的目录中的所有文件提供服务。因此,您应该确保在映像构建期间要下载的文件所在的目录中启动服务器或创建服务器包含程序的临时目录。为了便于说明,让我们创建文件python,我们稍后将通过foo.txt中的wget下载文件:

Dockerfile

启动http服务器时,重要的是我们在LAN上指定本地计算机的IP地址。此外,我们将打开端口8000.完成此操作后,我们应该看到以下输出:

echo "foo bar" > foo.txt

现在我们构建一个python3 -m http.server --bind 192.168.178.20 8000 Serving HTTP on 192.168.178.20 port 8000 ... 来说明这是如何工作的。 (我们假设文件Dockerfile应该下载到foo.txt):

/tmp

现在我们用

开始构建
FROM debian:latest
RUN apt-get update -qq \
&& apt-get install -y wget
RUN cd /tmp \
&& wget http://192.168.178.20:8000/foo.txt

在构建过程中,您将在docker build -t test . 服务器上看到以下输出:

python

我们的图片的构建输出将是:

172.17.0.21 - - [01/Nov/2014 23:32:37] "GET /foo.txt HTTP/1.1" 200 -

然后,您可以通过从刚构建的图像中启动和输入容器来检查它是否真的有效:

Step 2 : RUN cd /tmp && wget http://192.168.178.20:8000/foo.txt
 ---> Running in 49c10e0057d5
--2014-11-01 22:56:15--  http://192.168.178.20:8000/foo.txt
Connecting to 192.168.178.20:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 25872 (25K) [text/plain]
Saving to: `foo.txt'

     0K .......... .......... .....                           100%  129M=0s

2014-11-01 22:56:15 (129 MB/s) - `foo.txt' saved [25872/25872]

 ---> 5228517c8641
Removing intermediate container 49c10e0057d5
Successfully built 5228517c8641

然后,您可以docker run -i -t --rm test bash 查看/tmp

我们现在可以在foo.txt添加任何文件而无需创建新图层。假设您要添加一个大约5 GB的程序,如我们可以做的问题所述:

image

通过这种方式,我们不会留下10 gb的残余。

答案 1 :(得分:2)

没有办法做到这一点。功能请求位于https://github.com/docker/docker/issues/3156

答案 2 :(得分:2)

启动时是否可以将本地文件夹映射到容器,然后复制所需的文件。

sudo docker run -d -P --name myContainerName -v /localpath/zip_extract:/container/path/ yourContainerID

https://docs.docker.com/userguide/dockervolumes/

答案 3 :(得分:0)

我在这里发布了类似的答案:https://stackoverflow.com/a/37542913/909579

您可以使用docker-squash来压制新创建的图层。如果您在后续RUN指令中将其删除,那么这将从最终图像中删除存档。