Skip to content
Latchkey

crane append: Add a Layer Without a Dockerfile

crane append lays a tarball on top of a base image as a new layer and pushes the resulting image, with no Dockerfile and no daemon.

For images that are just "a base plus a few files" (a static binary, some config) crane append builds them without a Dockerfile or a builder, which is fast and reproducible in CI.

What it does

crane append takes a base image (-b) and one or more layer tarballs (-f), creates a new image with those layers on top, and either pushes it to a tag (-t) or writes it to a tarball (-o). It is a minimal, deterministic way to produce an image from files.

Common usage

Terminal
# pack a binary into a tar, then append it onto a base
tar -cf app-layer.tar -C ./dist app
crane append \
  -b gcr.io/distroless/static:nonroot \
  -f app-layer.tar \
  -t ghcr.io/acme/app:1.4.0

# write the result to a local tarball instead of pushing
crane append -b alpine:3.20 -f app-layer.tar -o image.tar

Options

FlagWhat it does
-b, --base <ref>Base image to append onto
-f, --new_layer <tar>Tarball to add as a new layer (repeatable)
-t, --new_tag <ref>Push the result to this reference
-o, --output <file>Write the result to a tarball instead of pushing
--insecureAllow HTTP / skip TLS verification

In CI

crane append is ideal for a static Go/Rust binary on a distroless base: build the binary, tar it, append it, and push, all without a Docker daemon or BuildKit. Because the inputs are fixed the output digest is stable across runs.

Common errors in CI

"UNAUTHORIZED: authentication required" pushing to -t means log in first. A layer that lands in the wrong place usually means the tar was created without the right -C base directory (paths inside the tar become paths inside the image). "MANIFEST_UNKNOWN" on -b means the base reference is wrong.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →