Build Minimized Docker Images in Golang

Build Minimized Docker Images in Golang

For most of the production ready application the size of the Docker file matters . A minified docker image will run smoothly and securely .

One of the most challenging things about building images is keeping the image size down. Each instruction in the Dockerfile adds a layer to the image, and you need to remember to clean up any artifacts you don’t need before moving on to the next layer. To write a really efficient Dockerfile, you have traditionally needed to employ shell tricks and other logic to keep the layers as small as possible and to ensure that each layer has the artifacts it needs from the previous layer and nothing else.

It was actually very common to have one Dockerfile to use for development (which contained everything needed to build your application), and a slimmed-down one to use for production, which only contained your application and exactly what was needed to run it. This has been referred to as the “builder pattern”. Maintaining two Dockerfiles is not ideal.

Now simply understand this

Build Stage

  1. first we will make an golang image from docker hub official Golang image and give an alias name builder .

  2. Than make a directory and use it as your Root Directory inside the image using this command WORKDIR /app and copy your source code using this command COPY . . , which will copy your code form your pc to the image /app directory .

  3. Now build your go code inside the image using golang build command , RUN go build -o main main.go

Run Stage

  1. in this second stage , pull the shortest docker image (alpine)

  2. Create and move to a working directory - WORKDIR /app

  3. Copy your binary code from previous image to the working diretory COPY --from=builder /app/main .

  4. copy your in environment variable to the working directory COPY .env . (this should not be done in production )

  5. lets expose port 8080 for accessing from outside of container - EXPOSE 8080

  6. Finally run main binary - CMD ["/app/main"]

the whole Dockerfile

// Build stage
FROM golang:1.18.2-alpine3.16 AS builder 
WORKDIR /app 
COPY . . 
RUN go build -o main main.go

//Run stage
FROM alpine:3.16
WORKDIR /app 
COPY --from=builder /app/main .
//this `COPY app.env .` should not be run in production
COPY .env .
EXPOSE 8080 
CMD ["/app/main"]

For more information read the official Docker documentation

Use multi-stage builds | Docker Documentation

In my demo application is was able to get around 20mb container form 150mb docker container . which was massive 🚀✨