Client reference

lazer.sh has no bespoke CLI. It implements the OCI Distribution Specification, so the tool you already have is the tool you use. This page covers the commands that matter and the errors worth recognising.

Authenticating

bash
sudo docker login lazer.sh
echo "$LAZER_KEY" | sudo docker login lazer.sh -u ci --password-stdin
podman login lazer.sh
crane auth login lazer.sh -u ci -p "$LAZER_KEY"

Credentials land in your Docker config and are reused by most tools. On a shared or ephemeral machine, log out when you are done:

bash
sudo docker logout lazer.sh

Pushing and pulling

bash
sudo docker tag api:2.4.1 lazer.sh/acme/api:2.4.1
sudo docker push lazer.sh/acme/api:2.4.1
sudo docker pull lazer.sh/acme/api:2.4.1

Multi-architecture images work as normal through buildx:

bash
sudo docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --tag lazer.sh/acme/api:2.4.1 \
  --push .

Inspecting without pulling

crane and skopeo read metadata without downloading layers, which is much faster in CI when you only need a digest:

bash
crane digest lazer.sh/acme/api:2.4.1
crane ls lazer.sh/acme/api
crane manifest lazer.sh/acme/api:2.4.1 | jq .
skopeo inspect docker://lazer.sh/acme/api:2.4.1

Copying between registries

Migrating off another registry, or mirroring into lazer.sh, is a copy:

bash
crane copy 123456789.dkr.ecr.eu-west-1.amazonaws.com/api:2.4.1 lazer.sh/acme/api:2.4.1
skopeo copy --all docker://ghcr.io/acme/api:2.4.1 docker://lazer.sh/acme/api:2.4.1

--all on skopeo copies every architecture in an index rather than just the one matching your machine. It is almost always what you want.

Deleting

bash
crane delete lazer.sh/acme/api:2.4.1

Deleting a tag unlinks the manifest. The bytes are reclaimed by garbage collection once the grace period passes, and are shared with any other image that still references them.

Errors you will hit

Message What it means
denied: insufficient scope The credential is valid but not scoped for this action on this repository. Check the key's scopes in the panel
unauthorized: authentication required No credential, or it expired. Log in again
denied: quota exceeded The project has no allocation left. Delete images, raise the allocation, or upgrade the plan
denied: project suspended Billing lapsed past the grace period. Pulls keep working; pushes resume when payment succeeds
manifest unknown The tag or digest does not exist in that repository
blob upload unknown An upload session expired mid-push. Retry the push

Compatibility

See OCI compatibility for what we implement and what we deliberately do not.