Removing unused intermediate docker images automatically

Alvin Rizki
3 min readNov 3, 2019

--

Cover

Docker and Go is a great combination for developers. With Go, developer can create a “so fast” application due to its static typing and compiled language. Its performance is almost as fast as C, but depends how you write your code and algorithm. With docker, you can virtualize your apps like when you are using virtual machine, but less resource. It do virtualization on process level, not in OS level such as virtualbox or VMware.

When you are working with those two technologies, many developers will compile their Go app and ship its binary to a docker image. A common approach is by using multistage build. Let’s see a sampe Go code below and its Dockerfile for the example.

  1. main.go
package mainimport (
"encoding/json"
"net/http"
)
func okFunc(w http.ResponseWriter, r *http.Request) {
data := struct {
Status string `json:"status"`
}{
Status: "OK",
}

w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(data)
}
func main() {
handler := http.NewServeMux()
handler.HandleFunc("/", okFunc)
http.ListenAndServe(":8080", handler)
}

2. Dockerfile

# build stage
FROM golang:1.13.2-alpine3.10 as builder
LABEL stage=gobuilder
WORKDIR /go/src/multistageapp
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /go/bin/multistageapp# final stage
FROM scratch
COPY --from=builder /go/bin/multistageapp /go/bin/multistageappEXPOSE 8080
ENTRYPOINT ["/go/bin/multistageapp"]

When you build your Go app docker image by using docker build -t multistageapp:latest . , first it will build my Go app inside golang:1.13.2-alpine3.10 docker image. Then on the final stage, my binary Go app will be copied from builder image to docker scratch image. (Why I use scratch image? To build image as minimal as possible). My docker images can be seen by using docker images.

docker images
docker images

But as you can see in the picture, this multistage process comes with one unwanted thing. It creates an intermediate docker images as a result of compiling Go app. The more you build your app, the more intermediate docker images lies on your machine and took your space slowly.

So how can we get rid of this? Can it be deleted after we build image? Yes. You can use docker image prune -f after building images.

docker image prune

This command will remove any untagged docker images from your machine. What if we want to remove only selected untagged images? Use filter for this command docker image prune command. In the example, my builder stage is labeled as stage=gobuilder . So I will filter prune based on this label by using docker image prune --filter label=stage=gobuilder -f .

docker image prune with filter

You can combine docker build and docker prune together so that you don’t need to type twice to to this : docker build -t multistageapp:latest . && docker image prune -f .

Hope it useful for you guys.

--

--