Feb 14, 2020 // by Nicholas Anastasi in technical pentesting
Docker containers can be a burden when the image gets too large.
By default, the Golang Docker container at its smallest is 123 MB. While seemingly small, this can result in annoying latency and slowness when deploying new tooling at scale.
Traditional Dockerfile Creation
Typically, we would create a Dockerfile that looks like the following for our desired Golang tool.
# This is our base container FROM golang:1-alpine # Installing git and waybackurls within the container RUN apk update && \ apk add git && \ go get github.com/tomnomnom/waybackurls # Setting our entrypoint so we can easily use the new tool ENTRYPOINT ["waybackurls"]
While this works perfectly, our resulting Docker image is 130 MB. We need to explore other features of Docker to create a smaller container.
Dockerfile as builder
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.
In Docker version 17.05 and later, we now use the
as builder feature in our Dockerfile to keep the image small. This feature is often referred to as multi-stage builds. It allows us to use an intermediary container to build an up to date version of our Golang tool and then move it into a much smaller container.
An example of a multi-stage Dockerfile:
# Using the golang alpine container as an build enviornment FROM golang:1.13-alpine3.10 as builder # Adding git and installing our tool from source RUN apk --no-cache add git RUN go get github.com/tomnomnom/waybackurls; exit 0 WORKDIR /go/src/github.com/tomnomnom/waybackurls RUN go install ./... #Spinning up a new container that is much smaller FROM alpine:latest RUN apk --no-cache add ca-certificates # Moving our previously built tool into the new container COPY --from=builder /go/bin/waybackurls /bin/waybackurls
The resulting container is now only 13.5 MB in size. That is big improvement!
You'll find that this is extremely useful when creating containers used for every day penetration testing work. Small containers help us scale our operations and continuously engage with new tooling.
This feature of Docker has quite a lot more to it that wasn't mentioned here.
Learn more: Docker multi-stage builds
Become a ninja: Advanced multi-stage builds