Archive · Docker

Multi-Stage Builds and BuildKit

Keep compilers out of the final image and build faster with BuildKit.

1 min read

  • Docker Engine 19.03.13
  • BuildKit
  • golang:1.15
  • alpine:3.12

A multi-stage build compiles in one stage and copies only the result into a small final image.

FROM golang:1.15 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /out/app .

FROM alpine:3.12
RUN adduser -D app
COPY --from=build /out/app /usr/local/bin/app
USER app
ENTRYPOINT ["app"]

The Go toolchain (hundreds of MB) stays in the build stage; the final image is a few MB with a smaller attack surface.

BuildKit, the newer builder shipped with Docker 18.09 and later, builds independent stages in parallel and caches better. Enable it per build:

DOCKER_BUILDKIT=1 docker build -t app:1.0 .
docker images app

On 19.03 BuildKit is opt-in with that variable (or "features": {"buildkit": true} in /etc/docker/daemon.json). Also supported in 19.03: RUN --mount=type=cache for package caches, under the # syntax=docker/dockerfile:1.1-experimental header.