我正在尝试使用微型容器。我创建了以下Dockerfile。这个想法是这个Docker文件以一个非常小的基本图像开始。 (5 MB)安装构建工具,进行构建,然后删除构建工具。
FROM alpine
ENTRYPOINT ["/bin/dockerdemo"]
RUN apk update
RUN apk add -t build-deps build-base go git
COPY . /go/src/dockerdemo
RUN cd /go/src/dockerdemo \
&& export GOPATH=/go \
&& go get \
&& go build -o /bin/dockerdemo \
&& rm -rf /go
RUN apk del --purge build-base go git
我原以为它真的很小。但它是358 MB。似乎最后一个命令实际上没有删除构建组件。
我对Docker很陌生,所以我可能在这里完全遗漏了一些东西。
图像上的文件系统也可能不会被压缩,因此即使构建组件文件已经消失,文件系统仍然是358 MB。
答案 0 :(得分:1)
如果步骤更改了文件系统,则docker文件中的每个COMMAND
都可以提交新的image file system layer。
即使你RUN rm -rf /
完成所有其他步骤,图像仍然会将每个前一层的内容存储在图像中。
在RUN
步骤中执行安装和删除,以避免提交您不想保留的文件系统更改:
FROM alpine
ENTRYPOINT ["/bin/dockerdemo"]
COPY . /go/src/dockerdemo
RUN set -uex; \
apk update; \
apk add -t build-deps build-base go git; \
cd /go/src/dockerdemo; \
export GOPATH=/go; \
go get; \
go build -o /bin/dockerdemo; \
rm -rf /go; \
apk del --purge build-base go git
使用此设置时,您将注意到,每次都必须运行所有步骤,这样您就会失去一些Dockers缓存的好处。
如果您在构建周转时间方面遇到问题,另一种方法是让特定的构建映像与运行应用程序的映像分开。
关于Go的一个很酷的事情是你可以build static binaries没有依赖关系并运行它们FROM scratch
导致一个真正的微容器。
正如Mark O&Connor所说,您可能不需要为构建设置自己的图像,因为您可以使用官方golang image。
FROM golang
COPY . /go/src/dockerdemo
RUN set -uex; \
cd /go/src/dockerdemo; \
export GOPATH=/go; \
go get; \
CGO_ENABLED=0 GOOS=linux go build -ldflags "-s" -a -installsuffix cgo -o /bin/dockerdemo;
从图像中提取二进制文件
docker run go-build tar -cvf /bin/dockerdemo > dockerdemo.tar
从中构建app容器
FROM scratch
ADD dockerdemo.tar /
ENTRYPOINT ["/bin/dockerdemo"]
答案 1 :(得分:0)
您确定它不是build-deps
,build-base
,go
和/或git
占用350 MB吗?
答案 2 :(得分:0)
为什么不使用Docker hub的官方golang图像?它有一个高山选择。
https://hub.docker.com/_/golang/
结帐 1.8-alpine Dockerfile:
Docker是一个分层附加文件系统。这意味着文件不会被真正删除。您需要进行导出/导入以将所有内容压缩到单个图层。