Skip to content

Container Registry

Zot Registry

This guide focuses on deploying Zot as a container registry.

Make sure kubeconf-demo is obtained for that specific cluster and active in current shell via KUBECONFIG environment variable or specified via --kubeconfig flag for helm and kubectl command line tools.

Add the Zot Helm Repository

# Add the Zot Helm repository
helm repo add project-zot https://project-zot.github.io/helm-charts

# Update your Helm repositories
helm repo update

# Verify the chart is available
helm search repo project-zot/zot

# create namespace
kubectl create namespace zot-registry

Create the Zot Configuration

Before installing the Helm chart, create a ConfigMap with your custom Zot configuration. This will override the default configuration.

# zot-config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: zot-config
  namespace: zot-registry
data:
  config.json: |
    {
      "distSpecVersion": "1.1.0",
      "storage": {
        "rootDirectory": "/var/lib/registry",
        "dedupe": true,
        "gc": true,
        "gcDelay": "1h",
        "gcInterval": "24h"
      },
      "http": {
        "address": "0.0.0.0",
        "port": "5000",
        "realm": "zot",
        "auth": {
          "htpasswd": {
            "path": "/secret/htpasswd"
          }
        }
      },
      "log": {
        "level": "info",
        "output": "/dev/stdout"
      },
      "extensions": {
        "metrics": {
          "enable": true,
          "prometheus": {
            "path": "/metrics"
          }
        },
        "search": {
          "enable": true,
          "cve": {
            "updateInterval": "24h"
          }
        },
        "ui": {
          "enable": true
        }
      }
    }

Apply the ConfigMap:

kubectl apply -f zot-config-map.yaml

Create Authentication Secret (Optional)

If you're using htpasswd authentication as shown in the config above, create the authentication secret:

# Generate htpasswd credentials
htpasswd -Bbn admin "SecurePassword123" > htpasswd

# Create the secret
kubectl create secret generic zot-htpasswd \
  --from-file=htpasswd=htpasswd \
  --namespace zot-registry

# Clean up local file
rm htpasswd

Example Create Helm Values File

Create a values file named zot-values.yaml:

# zot-values.yaml
replicaCount: 1

serviceAccount:
  create: true
  annotations: {}
  name: ""

service:
  type: ClusterIP
  port: 5000

persistence:
  enabled: true
  storageClass: "large"
  size: 100Gi

resources:
  limits:
    cpu: 1000m
    memory: 1Gi
  requests:
    cpu: 100m
    memory: 256Mi

# Mount custom zot configuration to override default
extraVolumes:
  - name: zot-config
    configMap:
      name: zot-config

extraVolumeMounts:
  - name: zot-config
    mountPath: /etc/zot-config
    readOnly: true

# If using htpasswd authentication
secretMounts:
  - name: zot-htpasswd
    mountPath: /secret
    secretName: zot-htpasswd
    readOnly: true

Install Zot with Helm

Install Zot using the Helm chart with your custom values:

helm install zot project-zot/zot \
  --namespace zot-registry \
  --values zot-values.yaml

Accessing Zot Registry

Public Access

Ensure appropriate traffic management is configured when exposing cluster services. Examples below illustrate local port forwarding access.

Port Forward (For Testing)

kubectl port-forward -n zot-registry svc/zot 5000:5000

Then access:

  • API: http://localhost:5000/v2/
  • UI: http://localhost:5000/
  • Metrics: http://localhost:5000/metrics

Testing the Registry

# Test the API endpoint
curl http://localhost:5000/v2/

# With authentication
curl -u admin:SecurePassword123 http://localhost:5000/v2/_catalog

# Login with Docker
podman login localhost:5000 -u admin

# Tag and push an image
podman tag nginx:latest localhost:5000/nginx:test
podman push localhost:5000/nginx:test

# Verify the image was pushed
curl -u admin:SecurePassword123 http://localhost:5000/v2/_catalog