Copyright © KC Green

From Harbor to Zot on ARM64

 infrastructure 

Why the lab dropped Harbor for a lighter OCI registry after moving Talos nodes to aarch64.

Harbor is a full registry product: scanning, replication, projects, and several backing services. On aarch64 it is also heavy, and it was a poor fit for four RK1 boards (ARM support is still catching up). After moving Talos from x86-64 to ARM64, Harbor stayed disabled in Git; Zot serves oci.this-is-fine.io instead.

Harbor shines when you want built-in scanning UI, replication policies, and a large operations surface. The lab mainly needed push, pull, sign, and admit — a smaller registry that speaks OCI and runs comfortably on ARM boards was the better fit.

Harbor vs Zot

Harbor (planned) Zot (running)
Footprint Many pods (core, jobs, DB, Redis, …) One registry process + PVC
ARM64 Not deployed here Fits the lab boards
API Harbor-specific OCIcrane, skopeo, cosign
GitOps Large Helm stack Slim release + zot.json
Hostname hub.this-is-fine.io (unused) oci.this-is-fine.io

Harbor manifests remain in the repo for reference; the apps overlay does not enable them.

What Zot provides

  • OCI-native push and pull (CI uses skopeo, not docker push — see Cosign + Kyverno).
  • Cosign signature storage and trust configuration.
  • Optional Trivy search for CVE metadata.
  • OpenID through Pocket ID for humans; htpasswd and robot users for automation.
forge CI -> skopeo push oci.this-is-fine.io/zeroclaw/...
  -> cosign sign
  -> Kyverno verifyImages on pull

Ingress is an HTTPRoute on shared-gateway-external. Large layer uploads use a long-timeout Envoy BackendTrafficPolicy.

CI robots authenticate with htpasswd while humans use OIDC (Pocket ID). That separation matters when Kyverno enforces signatures on pull: machines and people use different paths, but the same registry hostname.

What carried over

Harbor projects and replication rules do not migrate literally, but OCI tags and cosign signatures do. The lab cared about:

  1. Images built for the same architecture as the nodes (arm64 in .build.yml).
  2. Kyverno enforcing signatures on oci.this-is-fine.io/*.
  3. Lower RAM on a cluster that also runs Ceph, Mastodon, and monitoring.

Docs: Zot configuration, why Zot.