Reputation: 203
I'm experimenting with Micro-containers. I created the following Dockerfile. The idea is that this Docker file starts with a very small base image. (5 MB) Installs the build tools, does the build and then removes the build tool.
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
I was expecting it to be really small. But it is 358 MB. It appears that the last command did not actually delete the build components.
I'm pretty new to Docker so I may be completely missing something here.
It's also possible that the file system on the image doesn't get compacted, so even though the build component files are gone the file system is still 358 MB.
Upvotes: 1
Views: 566
Reputation: 74690
Each COMMAND
in a docker file can commit a new image file system layer, if the step makes change to the file system.
Even if you RUN rm -rf /
after all other steps, the image would still have the contents of each previous layer stored in the image.
Do the installs and removes in the one RUN
step to avoid committing the file system changes you don't want to keep:
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
You will notice when using this setup, all steps will have to be run every time so you lose some of Dockers caching niceness.
If you have issues with the build turnaround times, an alternative is to have a specific build image that is seperate from the image you run the application with.
One of the cool things about Go is you can build static binaries with no dependencies and run them FROM scratch
resulting in a truely micro container.
As Mark O'Connor noted, you probably don't need to setup your own image for the build as you can use the official 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;
Extract the binary from the image
docker run go-build tar -cvf /bin/dockerdemo > dockerdemo.tar
Build the app container from it
FROM scratch
ADD dockerdemo.tar /
ENTRYPOINT ["/bin/dockerdemo"]
Upvotes: 1
Reputation: 77971
Why not use the official golang image from Docker hub? It has an alpine option.
https://hub.docker.com/_/golang/
Checkout 1.8-alpine Dockerfile:
Docker is a layered append file system. This means files are not truly deleted. You'll need to to an export/import to compact everything down to a single layer.
Upvotes: 0
Reputation: 12391
Are you sure it's not build-deps
, build-base
, go
, and/or git
that take up the 350 MB?
Upvotes: 0