post-thumb

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

How to implement Singed Cookies in Unity with CloudFront?

How to reverse engineer C# and Unity3D Games?