Skip to main content

Zot

Purpose

Zot is Lumie's private container registry. It is the required image source for cluster workloads, and it also mirrors selected upstream registries on demand so the rest of the platform can stay inside the zot.lumie-infra.com/* image policy enforced elsewhere in the stack.

This page is a reference document for developers changing registry auth, upstream mirror coverage, MinIO storage, or build and deploy image paths.

Source Paths

PathRole
lumie-infra/bootstrap/zot/argocd.yamlArgo CD application for Zot
lumie-infra/bootstrap/zot/common-values.yamlVault-backed htpasswd, OIDC, and MinIO credential projection
lumie-infra/bootstrap/zot/helm-values.yamlZot deployment, ingress, rendered config, mirror policy, and auth settings
lumie-infra/bootstrap/minio/**Object storage Zot uses for its S3 backend
lumie-infra/applications/tekton/ci-cd/manifests/secrets/zot-registry-credentials.yamlTekton's push credential for zot.lumie-infra.com

Public Surface

SurfaceContract
External URLhttps://zot.lumie-infra.com
In-cluster ServicePort 5000 exposed by the zot service
Storage backendS3-compatible MinIO bucket zot at http://minio.minio.svc.cluster.local:9000
Auth methodshtpasswd and Keycloak OIDC
MetricsPrometheus endpoint at /metrics

Repository access is intentionally asymmetric:

  • anonymous users get read access;
  • admins group members and the admin user get create, update, and delete rights.

Runtime Flow

Configuration Highlights

The active config contract is rendered from a ConfigMap template plus a Vault-projected OIDC client secret:

"auth": {
"htpasswd": {
"path": "/etc/zot/htpasswd"
},
"openid": {
"providers": {
"oidc": {
"clientid": "zot",
"clientsecret": "__OIDC_CLIENT_SECRET__"
}
}
}
}

Important behavior from bootstrap/zot/helm-values.yaml:

  • the init container renders /etc/zot/config.json by substituting the live OIDC client secret into the template;
  • storage is S3-backed rather than PVC-backed;
  • ingress is public on zot.lumie-infra.com with a cert-manager-issued TLS secret;
  • retention keeps only the most recently pushed tag while deleting referrers.

Upstream Mirror Policy

On-demand sync is enabled for specific registries and prefixes:

RegistryExample prefixes
Docker Hublibrary/**, bitnami/**, gitea/**, rabbitmqoperator/**, minio/**, timberio/**
GHCRcloudnative-pg/**, kyverno/**, tektoncd/**, openclaw/**, kedacore/**
Quayprometheus/**, thanos/**, prometheus-operator/**, keycloak/**
Public ECRgravitational/**
registry.k8s.iokube-state-metrics/**, autoscaling/**
gcr.iokaniko-project/**

If an upstream namespace is not listed, Zot will not mirror it on demand and downstream image pulls should be expected to fail policy checks elsewhere in the stack.

Secret And Dependency Flow

SecretSource pathConsumer
zot-htpasswdbootstrap/zot/common-values.yamlLocal htpasswd auth
zot-oidc-secretbootstrap/zot/common-values.yamlInit-container render step
minio-s3-credentialsbootstrap/zot/common-values.yamlMain Zot container S3 client

All three are materialized by VaultStaticSecret resources through the shared vault/vault-auth identity.

Failure Modes

Failure pointBehavior
Missing zot-oidc-secretInit container cannot render config.json, so the pod never starts cleanly
MinIO outageRegistry reads and writes fail even if the Zot pod is healthy
Missing allowlisted prefixOn-demand pull fails because Zot refuses to mirror that upstream image path
TLS or ingress issueExternal pulls from zot.lumie-infra.com fail even if the in-cluster service is healthy

Verification

cd lumie-infra
rg -n "zot.lumie-infra.com|regionendpoint|onDemand|tektoncd/|clientsecret" \
bootstrap/zot applications/tekton/ci-cd
kubectl get application zot -n argocd -o yaml
kubectl get deploy,svc,ingress -n zot
kubectl get secret zot-htpasswd zot-oidc-secret minio-s3-credentials -n zot