ConfigsApr 16, 2026·3 min read

ko — Build and Deploy Go Container Images Without Dockerfiles

ko builds Go applications into container images without a Dockerfile or Docker daemon, producing minimal images and deploying them directly to Kubernetes with a single command.

Introduction

ko is a lightweight container image builder designed specifically for Go applications. It compiles your Go binary, layers it onto a minimal base image (distroless by default), and pushes the result to a container registry — all without a Dockerfile or Docker daemon. ko also integrates with Kubernetes manifests, replacing image references on the fly so you can build and deploy in a single step.

What ko Does

  • Compiles Go applications and packages them into minimal OCI container images
  • Pushes images directly to any container registry without requiring a local Docker daemon
  • Resolves ko:// image references in Kubernetes YAML and replaces them with built image digests
  • Uses distroless base images by default for minimal size and attack surface
  • Supports multi-platform builds for linux/amd64, linux/arm64, and more

Architecture Overview

ko works by invoking the Go compiler to produce a static binary for the target platform. It then constructs an OCI image by layering that binary onto a configurable base image (defaulting to gcr.io/distroless/static). The image layers are pushed directly to the registry via the OCI distribution API, bypassing Docker entirely. For Kubernetes workflows, ko parses YAML manifests, finds image fields matching ko:// prefixes, builds those images, and rewrites the references with fully qualified digests.

Self-Hosting & Configuration

  • Install via go install or download a pre-built binary from the GitHub releases page
  • Set KO_DOCKER_REPO to your target registry (e.g., ghcr.io/myorg or gcr.io/myproject)
  • Create a .ko.yaml config file to customize base images, build flags, or platform targets
  • Use ko build ./cmd/app to build a single service or ko build ./... for all commands
  • Integrate with kubectl by piping: ko resolve -f deploy/ | kubectl apply -f -

Key Features

  • Zero-Docker workflow: no Dockerfile, no docker build, no daemon process required
  • Blazing fast builds that leverage Go's compilation speed and registry-direct pushing
  • Automatic SBOM generation for supply chain security and vulnerability scanning
  • Multi-platform support for building images targeting amd64, arm64, s390x simultaneously
  • Kubernetes-native integration that resolves and applies manifests in one step

Comparison with Similar Tools

  • Dockerfile + docker build — requires writing and maintaining Dockerfiles plus a running daemon
  • Jib — same daemonless philosophy but designed for Java/Maven/Gradle, not Go
  • Kaniko — builds Dockerfiles in containers for CI but still needs a Dockerfile and is slower
  • GoReleaser — excellent for releasing Go binaries and archives but container support is secondary
  • Buildpacks (Paketo) — auto-detect and build but slower, larger images, and less Go-specific optimization

FAQ

Q: Does ko work with CGO-enabled applications? A: By default ko builds with CGO_ENABLED=0 for static binaries. If your app needs CGO, you can set build flags in .ko.yaml and use a base image with glibc.

Q: Can I use a custom base image instead of distroless? A: Yes. Set defaultBaseImage in .ko.yaml or use the --base-image flag to specify any OCI image as the base.

Q: How does ko handle private registries? A: ko uses the standard Docker credential helpers and config.json for authentication. It works with GCR, ECR, ACR, GHCR, and any registry supporting token-based auth.

Q: Is ko suitable for production deployments? A: Yes. ko is used in production by the Knative project, Tekton, and many other Kubernetes-native Go projects. Image digests ensure immutable deployments.

Sources

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets