Tooling

Image Building

Building VM and container images — Packer, Buildah, Kaniko, Earthly, Dagger.

VM / AMI / cloud images

  • Packer (HashiCorp) — multi-cloud image builder; AWS / GCP / Azure / Vultr / Hetzner / VMware / Proxmox. The default for "build a custom AMI."
  • EC2 Image Builder — AWS-native AMI pipelines.
  • GCP Cloud Build + image families — GCP-native.
  • Azure VM Image Builder — Azure-native.
  • disk-image-builder / diskimage-builder — OpenStack-flavored.

Container image building

  • Docker Buildx + BuildKit — the default; multi-platform, cache-friendly.
  • Buildah — Red Hat / Podman ecosystem; rootless, no daemon. Great for CI.
  • Kaniko (Google) — build container images inside containers without Docker daemon. Standard in Kubernetes-based CI.
  • img — daemonless, rootless builder.
  • ko — build Go containers without Dockerfiles.
  • jib — same idea for JVM.
  • paketo / Cloud Native Buildpacks — opinionated buildpack-based builders; no Dockerfile needed.
  • chainguard images — distroless, vuln-scanned base images; commercial.
  • distroless (Google) — minimal base images; debug variants for dev.

Pipelines / orchestrators that build images

  • Earthly — Earthfiles (Dockerfile-shaped) with caching + parallelism. Same syntax for build steps and CI.
  • Dagger — pipelines as code in TS / Go / Python; runs locally and in CI; first-class container build steps.
  • GitHub Actions with docker/build-push-action — boring, works.
  • Tekton — k8s-native pipelines; good for image building in cluster.
  • Concourse — older Pivotal pipeline tool.
  • Argo Workflows — k8s-native; can build images.

Layer / cache analysis

  • dive — interactive image-layer browser; spot bloat.
  • docker history — built-in.
  • crane (go-containerregistry) — manipulate images / manifests without Docker.
  • trivy — vulnerability scan (also see Image Supply Chain).

Patterns to adopt

  • Multi-stage Dockerfiles. Build deps in stage 1, copy artifacts to a tiny runtime stage.
  • Pin base image digests (FROM alpine@sha256:...). Avoids "they changed latest and broke us."
  • Distroless or chainguard for prod, alpine / debian-slim for dev.
  • Cache mounts (RUN --mount=type=cache,...) to avoid re-downloading deps.
  • Layer ordering — copy package.json + lockfile first, install, then copy source. Cache hits go up.
  • Tag with both :tag and :sha — humans use the tag, machines use the immutable digest.
  • Reproducible builds with source-date-epoch and Buildx for byte-identical outputs across builds.

Multi-platform builds

  • docker buildx build --platform=linux/amd64,linux/arm64 — single command.
  • QEMU + binfmt_misc for emulation when you don't have native arm64 builders.
  • Native arm64 runners (GitHub now has them, also Fly machines, Buildjet, Depot).

Pick this if…

  • Default container image build: Docker Buildx + multi-stage Dockerfile.
  • Rootless / daemonless / Kubernetes CI: Buildah or Kaniko.
  • Tired of writing pipeline YAML: Earthly or Dagger.
  • AMIs / cloud images: Packer.
  • Go-only: ko (no Dockerfile needed).
  • Reproducible / supply-chain-strict: chainguard images + Buildx + Cosign signing.

On this page