How to build a lightweight go application in DockerFile for EKS?
Docker is widely used in micro-services platforms. To get started is easy but to optimize it is hard. Because it’s difficult to find a full example of docker for building a lightweight application in Golang on Kubernetes platform like EKS on AWS.
Especially, EKS requires you to fully control docker images. If you don’t set up it properly, your application might crash when sending an HTTP Request due to missing SSL certificates.
In this post, we will show a complete example in DockerFile using multi-stage docker builds that you can build a lightweight go application and deploy to EKS or any Kubernetes platforms.
What Are Multi-Stage Docker Builds?
Docker builds are a method of organizing a DockerFile to minimize the size of the final container, improve run time performance. If you don’t use this approach, you will have a heavy docker image containing too many unnecessary libs.
There are two steps for creating multiple-stage docker builds to optimize docker.
Build DockerFile
STEP 1 Build Executable Binary
The first step is to build the base image file for building your application. You need to install the necessary libs for your needs in single RUN command to improve the performance.
Your libs will be cached in .build-deps
RUN apk add --no-cache --virtual .build-deps git musl-dev go && \
apk --update add ca-certificates && \
apk add --no-cache tzdata
After building the binary, you should delete those cache files and packages to reduce the size of the image.
Remember /go/pkg/mod should be deleted.
If not, your base image size will become heavy as having more modules
RUN \
rm -rf /go/pkg/mod && \
rm -rf /usr/local && \
rm -rf /root/.cache && \
apk del .build-deps</code></pre>
You can log in to your base image and check whether you have a large size of folders and files or not.
Then delete it in DockerFile.
// Log in to your base image
docker run -it [Your Image ID] sh
// Find the big size of folders
du -a ./ | sort -n -r | head -n 50</code></pre>
STEP2: Build a Small Image
You only copy the binary files and necessary files to the docker.
This is the reason why you can build the lightweight Go application.
DokcerFile
Below show a full example of DockerFile you can use to build a lightweight application in Golang on any Kubernetes platform.
// DockerFile
############################
## STEP 1 Build Executable Binary
############################
FROM golang:1.13.11-alpine AS builder
RUN apk add --no-cache --virtual .build-deps git musl-dev go && \
apk --update add ca-certificates && \
apk add --no-cache tzdata
RUN mkdir /my-app
WORKDIR /my-app
COPY ./configs /my-app
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
# Build the binary.
RUN CGO_ENABLE=1 go build -a -ldflags "-linkmode external -extldflags '-static' -s -w" -o /go/bin/my-app-main
RUN echo $(ls -1 /my-app/app)
RUN \
rm -rf /go/pkg/mod && \
rm -rf /usr/local && \
rm -rf /root/.cache && \
apk del .build-deps
############################
# STEP 2 Build a Small Image
############################
FROM scratch
WORKDIR /
COPY --from=builder /go/bin/my-app-main .
COPY --from=builder /my-app/configs ./configs
COPY --from=builder /etc/ssl/certs./etc/ssl/certs
EXPOSE 8081
Conclusion
In this post, you learned how to build a small size of the image in multiple-stage docker builds to shorten your deployment time.
What you need to do is to build and copy the go binary file and required files to the docker image.
Don’t forget to check your base image; find and delete those unused cache folders and libraries.
This can definitely save your time to build a small size of the base image as well.
You might be interested in