如何在不使用ADD或COPY指令的情况下将文件添加到Dockerfile中的图像
我需要在我的Docker
容器中的一个大的*.zip
文件(5 GB)的内容,以编译一个程序。 *.zip
文件驻留在本地机器上。 这个战略是:
COPY program.zip /tmp/ RUN cd /tmp \ && unzip program.zip \ && make
完成这个之后,我想删除解压后的目录和原始的*.zip
文件,因为它们不再需要。 问题是, COPY
(也是ADD
指令)将添加一个图层,该图像将包含文件program.zip
是有问题的,因为可能图像将至less5GB大。 有没有办法将文件添加到容器,而不使用COPY
或ADD
指令? wget
将无法正常工作,因为提到的*.zip
文件位于本地计算机上, curl file://localhost/home/user/program.zip -o /tmp/program.zip
也不起作用。
这不是直截了当的,但可以通过wget
或者使用python
的一点支持来完成。 (所有这三个工具通常应该在*nix
系统上可用。)
没有url
时, wget
将不起作用
curl file://localhost/home/user/program.zip -o /tmp/
将不会在Dockerfile
的RUN
指令中工作。 因此,我们需要一个wget
和curl
可以访问和下载program.zip
的服务器。
为了做到这一点,我们build立了一个小型的python
服务器来服务我们的http
请求。 我们将使用python
的http.server
模块进行此操作。 (你可以使用python
或python 3
,它可以同时使用)。
python -m http.server --bind 192.168.178.20 8000
python
服务器将提供它所在的目录中的所有文件。所以你应该确保你启动你的服务器或者在图像编译期间要下载的文件的目录中,或者创build一个包含你的程序的临时目录。 为了便于说明,我们创build一个文件foo.txt
,稍后我们将通过wget
在Dockerfile
下载这个文件:
echo "foo bar" > foo.txt
启动http服务器时,重要的是我们在局域网上指定本地计算机的IP地址。 此外,我们将打开端口8000.完成这个,我们应该看到以下输出:
python3 -m http.server --bind 192.168.178.20 8000 Serving HTTP on 192.168.178.20 port 8000 ...
现在我们构build一个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
现在我们开始构build
docker build -t test .
在构build期间,您将在我们的python
服务器上看到以下输出:
172.17.0.21 - - [01/Nov/2014 23:32:37] "GET /foo.txt HTTP/1.1" 200 -
我们的图像的构build输出将是:
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
然后,您可以通过从刚刚构build的映像启动并input容器来检查它是否真正起作用:
docker run -i -t --rm test bash
然后可以在/tmp
查找foo.txt
。
我们现在可以添加任何文件到我们的image
而无需创build一个新图层。 假设你想添加一个约5 GB的程序,如问题中提到的,我们可以这样做:
FROM debian:latest RUN apt-get update -qq \ && apt-get install -y wget RUN cd /tmp \ && wget http://conventiont:8000/program.zip \ && unzip program.zip \ && cd program \ && make \ && make install \ && cd /tmp \ && rm -f program.zip \ && rm -rf program
这样我们就不会剩下10克。
你能不能映射一个本地文件夹到启动时的容器,然后复制你需要的文件。
sudo docker run -d -P --name myContainerName -v /localpath/zip_extract:/container/path/ yourContainerID
没有办法做到这一点。 function请求在这里https://github.com/docker/docker/issues/3156 。
我在这里发布了类似的答案: https : //stackoverflow.com/a/37542913/909579
您可以使用docker-squash来挤压新创build的图层。 如果在后续的RUN
指令中删除档案,这将会从最终映像中删除档案。