I’ve started using a new standard Dockerfile for all my projects which works really well for my usecase.

Features

  • secure, minimal courtsey of using distroless base image
  • fast using buildkit caching functionality to preserve cache accross builds. docker build cache
# we can have dependabot automatically updating this go version
FROM golang:1.21.6-alpine AS deps

WORKDIR /app

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

FROM golang:1.21.6-alpine AS build

ARG TARGETOS TARGETARCH
# We set a default value here but it can be customized with 
# --build-arg PROJECT=./cmd/myotherapp
ARG PROJECT=./cmd/myapp

WORKDIR /app

ENV CGO_ENABLED=0

# Mount a directory for go-build cache and the go mod cache.
# This is shareable accross builds
RUN --mount=target=. \
    --mount=type=cache,target=/root/.cache/go-build \
    --mount=type=cache,target=/go/pkg \
    # the /out directory is important, you cant write to the current directory
    # because --mount=target=. is a read only mount
    GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /out/server ${PROJECT}

# This is the final image which will produce an artifact containing our single go binary.
FROM gcr.io/distroless/static-debian12:nonroot AS runner

COPY --from=build /out/server /server
USER 65534

CMD ["/server"]

If you want the same thing as above without all the comments you can find it in a public gist

You can also combine this image e.g. if you want to use insside a docker compose file:

version: "3.8"

services:
  myapp:
    build:
      target: runner
      context: ./
      args:
        PROJECT: ./cmd/myapp
    volumes:
      - go-modules:/go/pkg/mod

volumes:
  go-modules:

Automatic go upgrades with dependabot

If you create a file .github/dependabot.yml dependabot will automatically update your go version inside your Dockerfile. We can also get dependabot to upgrade our go.mod dependencies aswell!

---
version: 2
updates:
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"
  - package-ecosystem: "gomod"
    directory: "/"
    schedule:
      interval: "weekly"      

You can read more about depenadbot in the docs in the docs

References