github twitter linkedin email rss
Way to reduce Docker image size with 'tarball'
Jan 24, 2017
2 minutes read

Problem

One day, I tried to build a new docker image for an application written by Go. However, the image is too big to send to Google Container Registory. Docker images should be as small as possible because it’s easier to build and deploy on Kubernetes. Also, I should save the cost of GCR since it charge us based on the container size.

Solution

To make Docker images smaller, you should create two images to build it. One just is to build a Go application which includes all sources, Go compiler, tools, etc. The point is it’s just to build a binary on it. Another one is an image to run the binary file so the base image can be smaller than the previous image. In my case, it reduced the image size to 5MB from 300MB.

Example

Docker image to build

On this image, you need to have everything to build. So, the image has to be golang and need to download some dependencies. Lastly, you need to pass archived folder into standard output to give it to the runtime image.

FROM golang:1.7.1
MAINTAINER Kohei Mikami

ENV APPDIR /go/src/bitbucket.org/mikamikuh/stories-server
ENV BUILD_DIR /tmp/build

WORKDIR ${APPDIR}
RUN curl https://glide.sh/get | sh

...
RUN glide install
...

RUN go build -o ${BUILD_DIR}/srv
RUN cp build/Dockerfile ${BUILD_DIR}

WORKDIR ${BUILD_DIR}

ENTRYPOINT ["tar", "cf", "-", "."]

Docker runtime image

On this file, you can choose a small base image because Go binary doesn’t have any dependency. What you need to do on this image is running the binary on it.

FROM flynn/busybox
COPY srv /bin/srv
EXPOSE 5900
CMD ["/bin/srv"]

How to build

In theory, you need to build the first image sample-to-build before building the actual image. You need to pass files through pipe like below.

docker build -t mikamikuh/sample-to-build -f build/Dockerfile.base .
docker run --rm=false mikamikuh/sample-to-build | docker build -t mikamikuh/sample-to-run -

Back to posts


comments powered by Disqus