A simple, fast container image builder for Golang applications

Golang Docker

ko is a simple, fast container image builder for Go applications.

It’s ideal for use cases where your image contains a single Go application without any/many dependencies on the OS base image (e.g., no cgo, no OS package dependencies).

ko builds images by effectively executing go build on your local machine and as such, doesn’t require docker to be installed. This can make it a good fit for lightweight CI/CD use cases.

ko also includes support for simple YAML templating, which makes it a powerful tool for Kubernetes applications (See below).

Setup the Golang Project

Install

Install from Releases

$ VERSION=TODO # choose the latest version
$ OS=Linux     # or Darwin
$ ARCH=x86_64  # or arm64, i386, s390x

We generate SLSA3 provenance using the OpenSSF’s slsa-framework/slsa-github-generator. To verify our release, install the verification tool from slsa-framework/slsa-verifier#installation and verify as follows:

$ curl -sL "https://github.com/google/ko/releases/download/v${VERSION}/ko_${VERSION}_${OS}_${ARCH}.tar.gz" > ko.tar.gz
$ curl -sL https://github.com/google/ko/releases/download/v${VERSION}/attestation.intoto.jsonl > provenance.intoto.jsonl
$ slsa-verifier -artifact-path ko.tar.gz -provenance provenance.intoto.jsonl -source github.com/google/ko -tag "v${VERSION}"
  PASSED: Verified SLSA provenance
$ tar xzf ko.tar.gz ko
$ chmod +x ./ko

Install using Homebrew

brew install ko

Install on Alpine Linux

Installation on Alpine requires using the testing repository

echo https://dl-cdn.alpinelinux.org/alpine/edge/testing/ >> /etc/apk/repositories
apk update
apk add ko

Build and Install from Golang Source

With Go 1.18+, build and install the latest released version:

go install github.com/google/ko@latest

Setup on GitHub Actions

You can use the setup-ko action to install ko and setup auth to GitHub Container Registry in a GitHub Action workflow:

steps:
- uses: imjasonh/[email protected]

Authenticate

ko depends on the authentication configured in your Docker config (typically ~/.docker/config.json). If you can push an image with docker push, you are already authenticated for ko.

Since ko doesn’t require dockerko login also provides a surface for logging in to a container image registry with a username and password, similar to docker login.

Additionally, if auth is not configured in the Docker config, ko includes built-in support for authenticating to the following container registries using credentials configured in the environment:

Choose Destination

ko depends on an environment variable, KO_DOCKER_REPO, to identify where it should push images that it builds. Typically this will be a remote registry, e.g.:

  • KO_DOCKER_REPO=gcr.io/my-project, or
  • KO_DOCKER_REPO=my-dockerhub-user

Build a Docker Image with the Golang Project

ko build ./cmd/app builds and pushes a container image, and prints the resulting image digest to stdout.

In this example, ./cmd/app must be a package main that defines func main().

ko build ./cmd/app
...
gcr.io/my-project/app-099ba5bcefdead87f92606265fb99ac0@sha256:6e398316742b7aa4a93161dce4a23bc5c545700b862b43347b941000b112ec3e

NB: Prior to v0.10, the command was called ko publish — this is equivalent to ko build, and both commands will work and do the same thing.

The executable binary that was built from ./cmd/app is available in the image at /ko-app/app — the binary name matches the base import path name — and that binary is the image’s entrypoint.

Because the output of ko build is an image reference, you can easily pass it to other tools that expect to take an image reference.

To run the container locally:

docker run -p 8080:8080 $(ko build ./cmd/app)

Or to deploy it to other services like Cloud Run:

gcloud run deploy --image=$(ko build ./cmd/app)

Or fly.io:

flyctl launch --image=$(ko build ./cmd/app)
  • Note: The image must be publicly available.

Or AWS Lambda:

aws lambda update-function-code \
  --function-name=my-function-name \
  --image-uri=$(ko build ./cmd/app)
  • Note: The image must be pushed to ECR, based on the AWS-provided base image, and use the aws-lambda-go framework. See official docs for more information.

Or Azure Container Apps:

az containerapp update \
  --name my-container-app
  --resource-group my-resource-group
  --image $(ko build ./cmd/app)
  • Note: The image must be pushed to ACR or another registry service. See official docs for more information.

Configuration

Aside from KO_DOCKER_REPO, you can configure ko‘s behavior using a .ko.yaml file. The location of this file can be overridden with KO_CONFIG_PATH.

Overriding Base Images

By default, ko bases images on gcr.io/distroless/static:nonroot. This small image provides the bare necessities to run your Go binary.

You can override this base image in two ways: