Migrating from Dockerfile

If your Dockerfile looks like either of the examples in the official tutorial for writing a Dockerfile to containerize a Go application, you can easily migrate to use ko instead.

Let’s review the best practice multi-stage Dockerfile in that tutorial first:

  1. # syntax=docker/dockerfile:1
  2. ##
  3. ## Build
  4. ##
  5. FROM golang:1.16-buster AS build
  6. WORKDIR /app
  7. COPY go.mod ./
  8. COPY go.sum ./
  9. RUN go mod download
  10. COPY *.go ./
  11. RUN go build -o /docker-gs-ping
  12. ##
  13. ## Deploy
  14. ##
  15. FROM gcr.io/distroless/base-debian10
  16. WORKDIR /
  17. COPY --from=build /docker-gs-ping /docker-gs-ping
  18. EXPOSE 8080
  19. USER nonroot:nonroot
  20. ENTRYPOINT ["/docker-gs-ping"]

This Dockerfile:

  1. pulls the golang:1.16 image
  2. COPYs your local source into the container environment (COPYing go.mod and go.sum first and running go mod download, to cache dependencies in the container environment)
  3. RUNs go build on your source, inside the container, to produce an executable
  4. COPYs the executable built in the previous step into a new image, on top of a minimal distroless base image.

The result is a Go application built on a minimal base image, with an optimally cached build sequence.

After running docker build on this Dockerfile, don’t forget to push that image to the registry so you can deploy it.


Migrating to ko

If your Go source is laid out as described in the tutorial, and you’ve installed and set up your environment, you can simply run ko build ./ to build and push the container image to your registry.

You’re done. You can delete your Dockerfile and uninstall docker.

ko takes advantage of your local Go build cache without needing to be told to, and it sets the ENTRYPOINT and uses a nonroot distroless base image by default.

To build a multi-arch image, simply add --platform=all. Compare this to the equivalent Docker instructions.