如何拼合Docker镜像?

我做了一个相当大的Docker容器。 当我提交容器来创build一个图像时,图像大约是7.8GB。 但是,当我export容器(不save图像!) export到压缩包并重新导入时,图像只有3 GB大。 当然,历史是失败的,但这对我来说是行得通的,因为形象在我看来已经“完成”了,并且已经准备好部署了。

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

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


在版本1.13之前:

据我所知,你不能使用Docker api。 docker exportdocker import是为这种情况devise的,就像你自己已经提到的那样。

如果您不想保存到磁盘,则可能将导出的输出stream导入导入的inputstream。 我没有testing过,但是试试

 docker export red_panda | docker import - exampleimagelocal:new 

现在Docker已经在17.05发布了多阶段版本,你可以重新格式化你的版本,如下所示:

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

结果将是您的构build环境图层被caching在构build服务器上,但只有平铺的副本将存在于您标记和推送的结果图像中。


请注意,您通常会重新制定这个复杂的构build环境,只复制几个目录。 下面是一个Go的例子,从源代码和单个构build命令中创build一个二进制映像,而不在主机上安装Go并在Docker之外进行编译:

 $ 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"] 

go文件是一个简单的hello世界:

 $ cat hello.go package main import "fmt" func main() { fmt.Printf("Hello, world.\n") } 

构build会创build环境,构build环境和临时构build环境,然后为其划分标签:

 $ 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 

查看这些图像,只有一个二进制文件在被发送的图像中,而构build环境超过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. 

使用--squash标志构build图像:

https://docs.docker.com/engine/reference/commandline/build/#squash-an-images-layers-squash-experimental-only

还要考虑扫除不需要的文件,如aptcaching:

RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*