Published on

Build Small Golang Docker Containers


In this tutorial I will show you how to build really small docker containers for golang applications. And I mean the difference between 310MB down to 2MB

But Alpine..

So we thinking lets go with alpine right? Yeah sure lets build a small, app running on go with alpine.

Our application code:

package main

import (

func main() {
  lekkewords := []string{
    "dog", "cat", "fish", "giraffe",
    "moo", "spider", "lion", "apple",
    "tree", "moon", "snake", "mountain lion",
    "trooper", "burger", "nasa", "yes",

  var zelength int = len(lekkewords)
  var indexnum int = rand.Intn(zelength-1)
  word := lekkewords[indexnum]

  fmt.Println("Number of words:", zelength)
  fmt.Println("Selected index number:", indexnum)
  fmt.Println("Selected word is:", word)

Our Dockerfile:

FROM golang:alpine

WORKDIR $GOPATH/src/mylekkepackage/mylekkeapp/
COPY app.go .
RUN go build -o /go/app

CMD ["/go/app"]

Let's package our app to an image:

docker build -t mygolangapp:using-alpine .

Inspect the size of our image, as you can see it being 310MB

docker images "mygolangapp:*"
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
mygolangapp         using-alpine        eea1d7bde218        About a minute ago   310MB

Just make sure it actually works:

docker run mygolangapp:using-alpine

Number of words: 16
Selected index number: 11
Selected word is: mountain lion

But for something just returning random selected text, 310MB is a bit crazy.

Multi Stage Builds

As Go binaries are self-contained, we can make use of docker's multi stage builds, where we can build our application on alpine and use the binary on a scratch image:

Our multi stage Dockerfile:

FROM golang:alpine AS builder

WORKDIR $GOPATH/src/mylekkepackage/mylekkeapp/
COPY app.go .
RUN go build -o /go/app

FROM scratch

COPY --from=builder /go/app /go/app

CMD ["/go/app"]

Build it:

docker build -t mygolangapp:using-multistage -f Dockerfile.multi .

Notice that the image is only 2.01MB, say w000t!

docker images "mygolangapp:*"

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mygolangapp         using-multistage    31474c61ba5b        15 seconds ago      2.01MB
mygolangapp         using-alpine        eea1d7bde218        2 minutes ago       310MB

Run the app:

docker run mygolangapp:using-multistage

Number of words: 16
Selected index number: 5
Selected word is: spider


Source code for this demonstration can be found at

Thank You

Thanks for reading, if you like my content, feel free to check out my website, and subscrube to my newsletter or follow me at @ruanbekker on Twitter.

Buy Me A Coffee