this repo has no description

Add Zot container registry at zot.sans-self.org

JuiceFS-backed storage, htpasswd auth with anonymous pull,
Trivy CVE scanning, and web UI enabled.

+237
+2
CHANGELOG.md
··· 12 12 - Add tarpit for vulnerability scanners hitting known exploit paths (#18) 13 13 14 14 ### Added 15 + - Add Zot container registry with S3 storage and CVE scanning (#56) 15 16 - Update PDS to use S3 for blob storage instead of filesystem (#52) 16 17 - Add S3 remote backend for OpenTofu state (#50) 17 18 - Migrate to 3-node HA cluster with JuiceFS and S3-backed storage (#38) ··· 22 23 - Add Tangled knot with Spindle CI/CD to k3s cluster (#1) 23 24 24 25 ### Fixed 26 + - Fix knot post-receive hooks not being executable (#54) 25 27 - Remove deleted pds-test subdomain from TLS certificate (#48) 26 28 - Restore PDS and knot data from S3 backups (#34) 27 29 - Fix backup script to prevent empty source from wiping S3 data (#33)
+1
k8s/kustomization.yaml
··· 6 6 - juicefs 7 7 - pds 8 8 - knot 9 + - registry 9 10 10 11 generatorOptions: 11 12 disableNameSuffixHash: true
+12
k8s/registry/cert.yaml
··· 1 + apiVersion: cert-manager.io/v1 2 + kind: Certificate 3 + metadata: 4 + name: zot-sans-self-org 5 + namespace: registry 6 + spec: 7 + secretName: zot-sans-self-org-tls 8 + issuerRef: 9 + name: letsencrypt-prod 10 + kind: ClusterIssuer 11 + dnsNames: 12 + - zot.sans-self.org
+42
k8s/registry/configmap.yaml
··· 1 + apiVersion: v1 2 + kind: ConfigMap 3 + metadata: 4 + name: zot-config 5 + namespace: registry 6 + data: 7 + config.json: | 8 + { 9 + "distSpecVersion": "1.1.0", 10 + "storage": { 11 + "rootDirectory": "/data", 12 + "dedupe": true 13 + }, 14 + "http": { 15 + "address": "0.0.0.0", 16 + "port": "5000", 17 + "auth": { 18 + "htpasswd": { 19 + "path": "/etc/zot/htpasswd" 20 + } 21 + }, 22 + "accessControl": { 23 + "repositories": { 24 + "**": { 25 + "anonymousPolicy": ["read"], 26 + "defaultPolicy": ["read", "create", "update", "delete"] 27 + } 28 + } 29 + } 30 + }, 31 + "extensions": { 32 + "search": { 33 + "enable": true, 34 + "cve": { 35 + "updateInterval": "2h" 36 + } 37 + }, 38 + "ui": { 39 + "enable": true 40 + } 41 + } 42 + }
+81
k8s/registry/deployment.yaml
··· 1 + apiVersion: apps/v1 2 + kind: Deployment 3 + metadata: 4 + name: zot 5 + namespace: registry 6 + spec: 7 + replicas: 1 8 + strategy: 9 + type: Recreate 10 + selector: 11 + matchLabels: 12 + app: zot 13 + template: 14 + metadata: 15 + labels: 16 + app: zot 17 + spec: 18 + terminationGracePeriodSeconds: 30 19 + securityContext: 20 + fsGroup: 1000 21 + runAsUser: 1000 22 + runAsGroup: 1000 23 + runAsNonRoot: true 24 + containers: 25 + - name: zot 26 + image: ghcr.io/project-zot/zot:v2.1.14 27 + ports: 28 + - containerPort: 5000 29 + volumeMounts: 30 + - name: data 31 + mountPath: /data 32 + - name: config 33 + mountPath: /etc/zot/config.json 34 + subPath: config.json 35 + readOnly: true 36 + - name: htpasswd 37 + mountPath: /etc/zot/htpasswd 38 + subPath: htpasswd 39 + readOnly: true 40 + startupProbe: 41 + httpGet: 42 + path: /v2/ 43 + port: 5000 44 + failureThreshold: 30 45 + periodSeconds: 2 46 + livenessProbe: 47 + httpGet: 48 + path: /v2/ 49 + port: 5000 50 + periodSeconds: 30 51 + timeoutSeconds: 5 52 + failureThreshold: 3 53 + readinessProbe: 54 + httpGet: 55 + path: /v2/ 56 + port: 5000 57 + periodSeconds: 10 58 + timeoutSeconds: 5 59 + failureThreshold: 2 60 + securityContext: 61 + allowPrivilegeEscalation: false 62 + capabilities: 63 + drop: 64 + - ALL 65 + resources: 66 + requests: 67 + cpu: 100m 68 + memory: 256Mi 69 + limits: 70 + cpu: 500m 71 + memory: 1Gi 72 + volumes: 73 + - name: data 74 + persistentVolumeClaim: 75 + claimName: zot-data 76 + - name: config 77 + configMap: 78 + name: zot-config 79 + - name: htpasswd 80 + secret: 81 + secretName: zot-htpasswd
k8s/registry/htpasswd.secret

This is a binary file and will not be displayed.

+28
k8s/registry/ingress.yaml
··· 1 + apiVersion: traefik.io/v1alpha1 2 + kind: Middleware 3 + metadata: 4 + name: strip-server-headers 5 + namespace: registry 6 + spec: 7 + headers: 8 + customResponseHeaders: 9 + X-Powered-By: "" 10 + --- 11 + apiVersion: traefik.io/v1alpha1 12 + kind: IngressRoute 13 + metadata: 14 + name: zot 15 + namespace: registry 16 + spec: 17 + entryPoints: 18 + - websecure 19 + tls: 20 + secretName: zot-sans-self-org-tls 21 + routes: 22 + - match: Host(`zot.sans-self.org`) 23 + kind: Rule 24 + middlewares: 25 + - name: strip-server-headers 26 + services: 27 + - name: zot 28 + port: 5000
+22
k8s/registry/kustomization.yaml
··· 1 + apiVersion: kustomize.config.k8s.io/v1beta1 2 + kind: Kustomization 3 + 4 + resources: 5 + - namespace.yaml 6 + - configmap.yaml 7 + - pvc.yaml 8 + - deployment.yaml 9 + - service.yaml 10 + - ingress.yaml 11 + - cert.yaml 12 + - network-policy.yaml 13 + 14 + generatorOptions: 15 + disableNameSuffixHash: true 16 + 17 + secretGenerator: 18 + - name: zot-htpasswd 19 + namespace: registry 20 + type: Opaque 21 + files: 22 + - htpasswd=htpasswd.secret
+4
k8s/registry/namespace.yaml
··· 1 + apiVersion: v1 2 + kind: Namespace 3 + metadata: 4 + name: registry
+22
k8s/registry/network-policy.yaml
··· 1 + apiVersion: networking.k8s.io/v1 2 + kind: NetworkPolicy 3 + metadata: 4 + name: zot-ingress 5 + namespace: registry 6 + spec: 7 + podSelector: 8 + matchLabels: 9 + app: zot 10 + policyTypes: 11 + - Ingress 12 + ingress: 13 + - from: 14 + - namespaceSelector: 15 + matchLabels: 16 + kubernetes.io/metadata.name: traefik 17 + ports: 18 + - port: 5000 19 + - from: 20 + - podSelector: {} 21 + ports: 22 + - port: 5000
+12
k8s/registry/pvc.yaml
··· 1 + apiVersion: v1 2 + kind: PersistentVolumeClaim 3 + metadata: 4 + name: zot-data 5 + namespace: registry 6 + spec: 7 + accessModes: 8 + - ReadWriteOnce 9 + storageClassName: juicefs-sc 10 + resources: 11 + requests: 12 + storage: 50Gi
+11
k8s/registry/service.yaml
··· 1 + apiVersion: v1 2 + kind: Service 3 + metadata: 4 + name: zot 5 + namespace: registry 6 + spec: 7 + selector: 8 + app: zot 9 + ports: 10 + - port: 5000 11 + targetPort: 5000