2014-03-28 35 views
17

我做了一个相当大的Docker容器。当我提交容器来创建图像时,图像大约为7.8 GB。但是当我将容器(不是save的图像!)export重新导入tarball并重新导入时,图像只有3 GB大。当然,历史已经消失了,但对我而言这确实很好,因为我认为这个图像已经“完成”了,并且已经准备好部署。如何拼合Docker镜像?

如何展平图像/容器而不将其导出到磁盘并再次导入它?而且:这样做是明智的主意还是我错过了一些重要的观点?

+1

你建立与'''--rm'''选项?这将删除中间图像。还是我误解了这个问题? – shabbychef

+1

还有一些其他技巧可以使图像变小:在一个'''RUN'''中调用一堆安装命令,删除不需要的ubuntu软件包,_etc._请参阅https://github.com/dckc/ipython-docker/blob/master/Dockerfile就是一个很好的例子。 – shabbychef

回答

15

从Docker 1.13开始,您可以使用--squash标志。


1.13版本之前:

据我所知,你不能使用泊坞API。 docker exportdocker import是针对这种情况设计的,就像你自己已经提到的那样。

如果你不想保存到磁盘,你可能会将输出输出流管道输入到输入流中。我没有测试过这一点,但尝试

docker export red_panda | docker import - exampleimagelocal:new 
+0

我刚刚在“Docker version 1.1.1,build bd609d2”上做了这个,所产生的图像并不小。它实际上有点大。但是新的形象没有了历史。 – VolkerK

+0

适用于Docker 17.03.0-ce。从33GB图像大小减少到19GB –

8

现在Docker已经在17.05发布了多阶段版本,你可以重新格式化哟乌尔构建看起来像这样:

FROM buildimage as build 
# your existing build steps here 
FROM scratch 
COPY --from=build// 
CMD ["/your/start/script"] 

其结果将是构建环境层在构建服务器缓存,但只有一个扁平的副本将您标记和推动所产生的图像中存在。


请注意,您通常会重新制定这个复杂的构建环境,只复制几个目录。下面是用了一个范例,使从源代码和一个构建命令单个二进制图像,而不在主机上安装围棋和编译泊坞窗之外:

$ cat Dockerfile 
ARG GOLANG_VER=1.8 
FROM golang:${GOLANG_VER} as builder 
WORKDIR /go/src/app 
COPY . . 
RUN go-wrapper download 
RUN go-wrapper install 

FROM scratch 
COPY --from=builder /go/bin/app /app 
CMD ["/app"] 

转到文件是一个简单的Hello World:

$ cat hello.go 
package main 

import "fmt" 

func main() { 
     fmt.Printf("Hello, world.\n") 
} 

构建既创造环境,构建环境和迷惑不解,然后标签划痕一个:

$ docker build -t test-multi-hello .                                
Sending build context to Docker daemon 4.096kB 
Step 1/9 : ARG GOLANG_VER=1.8 
---> 
Step 2/9 : FROM golang:${GOLANG_VER} as builder 
---> a0c61f0b0796 
Step 3/9 : WORKDIR /go/src/app 
---> Using cache 
---> af5177aae437 
Step 4/9 : COPY . . 
---> Using cache 
---> 976490d44468 
Step 5/9 : RUN go-wrapper download 
---> Using cache 
---> e31ac3ce83c3 
Step 6/9 : RUN go-wrapper install 
---> Using cache 
---> 2630f482fe78 
Step 7/9 : FROM scratch 
---> 
Step 8/9 : COPY --from=builder /go/bin/app /app 
---> Using cache 
---> 5645db256412 
Step 9/9 : CMD /app 
---> Using cache 
---> 8d428d6f7113 
Successfully built 8d428d6f7113 
Successfully tagged test-multi-hello:latest 

望着图像,只有一个双进制在图像中被运,而构建环境是超过700MB:

$ docker images | grep 2630f482fe78 
<none>    <none>    2630f482fe78  6 days ago   700MB 

$ docker images | grep 8d428d6f7113 
test-multi-hello  latest    8d428d6f7113  6 days ago   1.56MB 

是的,它运行:

$ docker run --rm test-multi-hello 
Hello, world. 
+0

这应该是这个时候接受的答案..它非常有效和灵活! –