DEV Community

Cover image for 20X Faster Golang Docker Builds
JackTT
JackTT

Posted on • Edited on

20X Faster Golang Docker Builds

According to the Go command documentation:

"The go command caches build outputs for reuse in future builds."

This means that the first time you run go build will take the most time, but all subsequent times will use the cache to reduce building time.

Dockerfile without caching

Let's take a look at this Dockerfile



FROM golang:1.21-bullseye as builder
WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
RUN go build -o app

FROM ubuntu:22.04
RUN mkdir /app
WORKDIR /app
COPY --from=builder /app/app .
ENTRYPOINT ["./app"]


Enter fullscreen mode Exit fullscreen mode

This Dockerfile is using 2 states:

  • The first stage is responsible for downloading dependencies and building the binary app.
  • The second state copy this binary app a clean Ubuntu image.

It did help us cache some layers when they are not changed.

But every time we build this image, Docker creates a new environment. This means that the go build command will rebuild without using the cache. The more dependencies included in this project, the longer the build process takes.

In my "Hello world!" example, it took 26s to complete the build process.

Image description

Docker cache mount

Cache mounts let you specify a persistent package cache to be used during builds. The persistent cache helps speed up build steps, especially steps that involve installing packages using a package manager. Having a persistent cache for packages means that even if you rebuild a layer, you only download new or changed packages.

Cache mounts are created using the --mount flag together with the RUN instruction in the Dockerfile. To use a cache mount, the format for the flag is --mount=type=cache,target=<path>, where is the location of the cache directory that you wish to mount into the container.

The Dockerfile after using the mount flag will look like:



FROM golang:1.21-bullseye as builder

WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
ENV GOCACHE=/root/.cache/go-build
RUN --mount=type=cache,target="/root/.cache/go-build" go build -o app

FROM ubuntu:22.04
RUN mkdir /app
WORKDIR /app
COPY --from=builder /app/app .
ENTRYPOINT ["./app"]


Enter fullscreen mode Exit fullscreen mode

After applying mount cache, it took 1.2s to complete the build process.

Image description

References

Top comments (1)

Collapse
 
cherrot profile image
cherrot

from docs.docker.com/build/guide/mounts/

RUN --mount=type=cache,target=/go/pkg/mod/ \
    --mount=type=bind,source=go.sum,target=go.sum \
    --mount=type=bind,source=go.mod,target=go.mod \
    go mod download -x

ENV GOCACHE=/root/.cache/go-build
RUN --mount=type=cache,target=/go/pkg/mod/ \
    --mount=type=cache,target="/root/.cache/go-build" \
    --mount=type=bind,target=. \
    go build -o app

Enter fullscreen mode Exit fullscreen mode