freeCodeCamp/guide/english/docker/separate-build-image/index.md

2.2 KiB

title
Separate Build Image

Overview

Making lightweight docker images is key to having a fast development/deployment pipeline. For compiled code, building the binary inside a docker container has the benefit of being a repeatable and standardised build process. However, this can create a very large images which can become an issue down the line.

Our code

In this example, we will use a simple webserver writen in Go. The following code is just a simple hello world webserver listening on port 8080.

package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world!")
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Dockerfile

The Dockerfile for this code might look something like this

FROM golang:1.11

ADD . /app

WORKDIR /app

RUN go build -o /myserver .

EXPOSE 8080

CMD [ "/myserver" ]

Building this image results in an image with a size of 783MB!! With an image that size for a simple application, it's easy to see how this can slow things down when deploying.

A better solution

A better solution would be to use a separate build image to build the binary and then copy it to the final image. As Go generates a standalone binary, we can use the scratch docker image as a base which is about as small as it gets!

Dockerfile

The following Dockerfile will first build the binary inside the golang image and then build a new image from scratch, copying the binary from the first image into the second.

FROM golang:1.11 as build

ADD . /app

WORKDIR /app

RUN go build -o /myserver .


FROM scratch

COPY --from=build /myserver /myserver

EXPOSE 8080

CMD [ "myserver" ]

Building from this dockerfile results in a final image size of only 6.55MB! That's over 100 times smaller than our first attempt, making it 100 times faster to pull the image down from a registry!

Bonus benefit

Not only do we now have a tiny docker image for our application, we also only have to worry about the security of our application as there is no other software running inside the container.