crane (from Google’s go-containerregistry) is a CLI that talks to container registries directly. It’s great when you want to list tags, inspect manifests, pin digests, or mirror images between registries without running Docker locally.
This post shows how to install crane on Ubuntu 24.04 and a set of practical commands you can copy into scripts or CI.
What you’ll use crane for
- List tags in a repo (e.g.,
registry.k8s.io/kubectl) - Find the latest stable tag and its immutable digest
- Inspect manifest/config (multi-arch, labels, entrypoint, env)
- Copy images between registries (e.g.,
registry.k8s.io→ Harbor) without pulling locally - Export/import images as tar (air-gapped workflows)
- Authenticate to private registries (Harbor robot accounts work great)
- Get the latest
go-containerregistryrelease tag
This sets VERSION to something like v0.20.7.
VERSION=$(
curl -fSL -H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/google/go-containerregistry/releases/latest" \
| jq -r '.tag_name'
)
echo "$VERSION"
Troubleshooting tip: If you see jq: parse error: Invalid numeric literal, it usually means GitHub returned something that isn’t JSON (rate limit / HTML / API error). Print the raw response to verify:
curl -fSL -H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/google/go-containerregistry/releases/latest"
- Download and install
craneon Ubuntu 24.04
This matches your install method.
OS=Linux
ARCH="$(dpkg --print-architecture)"
[ "$ARCH" = "amd64" ] && ARCH="x86_64"
curl -fSL "https://github.com/google/go-containerregistry/releases/download/${VERSION}/go-containerregistry_${OS}_${ARCH}.tar.gz" \
-o /tmp/go-containerregistry.tar.gz
sudo tar -zxvf /tmp/go-containerregistry.tar.gz -C /usr/local/bin crane
crane version
Why the ARCH mapping matters: Ubuntu reports amd64, but the release tarball uses x86_64.
- Verify it works
which crane
crane version
crane --help | head
Use cases
- List tags in a repository
List tags under registry.k8s.io/kubectl:
crane ls registry.k8s.io/kubectl
Sort as versions and show the newest 50 (your example):
crane ls registry.k8s.io/kubectl | sort -V | tail -n 50
Only stable tags (vX.Y.Z) and show the latest 20:
crane ls registry.k8s.io/kubectl \
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
| sort -V \
| tail -n 20
- Find the latest stable tag and pin it by digest
Tags can move. Digests don’t. This prints a fully pinned immutable reference like:
registry.k8s.io/kubectl@sha256:…
REPO="registry.k8s.io/kubectl"
TAG=$(
crane ls "$REPO" \
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
| sort -V \
| tail -n 1
)
DIGEST="$(crane digest "$REPO:$TAG")"
echo "Latest stable tag: $TAG"
echo "Digest: $DIGEST"
echo "Pinned reference: $REPO@$DIGEST"
- Inspect the manifest (multi-arch vs single-arch)
Pretty-print the manifest:
crane manifest registry.k8s.io/kubectl:v1.34.3 | jq .
If it’s a multi-arch index, list platforms:
crane manifest registry.k8s.io/kubectl:v1.34.3 \
| jq -r '.manifests[] | "\(.platform.os)/\(.platform.architecture) \(.digest)"'
- Inspect image config (labels, entrypoint, env)
crane config registry.k8s.io/kubectl:v1.34.3 | jq .
Only show labels:
crane config registry.k8s.io/kubectl:v1.34.3 \
| jq '.config.Labels // {}'
- Copy images between registries (no local pull)
This is where crane is really useful: you can mirror images without docker pull.
Example: mirror kubectl into Harbor:
crane copy registry.k8s.io/kubectl:v1.34.3 harbor.maksonlee.com/mirror/kubectl:v1.34.3
Even better: copy by digest (fully pinned source):
D=$(crane digest registry.k8s.io/kubectl:v1.34.3)
crane copy registry.k8s.io/kubectl@"$D" harbor.maksonlee.com/mirror/kubectl:v1.34.3
Note: If your Harbor project is publicly readable, you can run crane ls/digest/manifest/config without login. But pushing (crane copy to Harbor) usually requires auth.
- Export/import an image tarball (air-gapped workflow)
Export to a tar file:
crane export registry.k8s.io/kubectl:v1.34.3 /tmp/kubectl_v1.34.3.tar
Import into Harbor:
crane import /tmp/kubectl_v1.34.3.tar harbor.maksonlee.com/mirror/kubectl:v1.34.3
- Login for private registries
crane auth login harbor.example.com -u maksonlee -p password
Did this guide save you time?
Support this site