diff --git a/gitea/registry-ingress.yaml b/gitea/registry-ingress.yaml deleted file mode 100644 index 9814c6a..0000000 --- a/gitea/registry-ingress.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# Dedicated DNS-only hostname for the Gitea container registry. -# -# WHY: Docker registry pushes can't go through the Cloudflare proxy, which caps -# request bodies at 100 MB (413 Payload Too Large). `registry.rogi.casa` is a -# DNS-only (grey-cloud) record in Cloudflare pointing straight at the cluster, -# so Traefik serves it directly with a Let's Encrypt cert (HTTP-01). Git traffic -# on `git.rogi.casa` stays behind the Cloudflare proxy untouched. -# -# Cloudflare setup: -# A registry.rogi.casa DNS-only (grey cloud) -# -# Push with: -# docker login registry.rogi.casa -u -# docker tag git.rogi.casa/roger/hermes-agent:v1.35-1 registry.rogi.casa/roger/hermes-agent:v1.35-1 -# docker push registry.rogi.casa/roger/hermes-agent:v1.35-1 -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: gitea-registry - namespace: gitea - annotations: - cert-manager.io/cluster-issuer: letsencrypt-prod - # Allow large docker layer uploads (no upstream body-size cap from Traefik). - traefik.ingress.kubernetes.io/buffering: | - maxRequestBodyBytes: 0 -spec: - ingressClassName: traefik - tls: - - hosts: - - registry.rogi.casa - secretName: gitea-registry-tls - rules: - - host: registry.rogi.casa - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: gitea - port: - number: 80 diff --git a/platform-engineer/deployment.yaml b/platform-engineer/deployment.yaml index 546aa80..1d7ed41 100644 --- a/platform-engineer/deployment.yaml +++ b/platform-engineer/deployment.yaml @@ -18,8 +18,7 @@ spec: app: hermes spec: serviceAccountName: platform-engineer - imagePullSecrets: - - name: gitea-registry + # No imagePullSecrets — using the public stock Hermes image from Docker Hub. # Pin to the powerful amd64 node (image is linux/amd64; the NUC has 24 GiB). nodeSelector: @@ -43,6 +42,28 @@ spec: topologyKey: kubernetes.io/hostname initContainers: + # Download kubectl + helm into a shared emptyDir so the stock Hermes image + # (which doesn't ship kubectl) can still drive the cluster. Avoids building + # and pushing a custom image through a slow / size-capped registry. + - name: install-tools + image: curlimages/curl:8.12.1 + command: ["sh", "-c"] + args: + - | + set -e + echo "Downloading kubectl v1.35.0..." + curl -fsSL -o /tools/kubectl \ + https://dl.k8s.io/release/v1.35.0/bin/linux/amd64/kubectl + chmod +x /tools/kubectl + echo "Downloading helm v3.16.3..." + curl -fsSL https://get.helm.sh/helm-v3.16.3-linux-amd64.tar.gz \ + | tar -xz -C /tools --strip-components=1 linux-amd64/helm + chmod +x /tools/helm + echo "Tools installed:"; ls -la /tools + volumeMounts: + - name: tools + mountPath: /tools + # Seed /opt/data with config.yaml + SOUL.md on first boot only. # ArgoCD owns the manifests; the PVC is runtime state and is NOT reconciled. - name: seed-data @@ -68,8 +89,8 @@ spec: containers: - name: hermes - image: registry.rogi.casa/roger/hermes-agent:v1.35-1 - imagePullPolicy: IfNotPresent # falls back to local image if present + image: nousresearch/hermes-agent:latest + imagePullPolicy: Always command: ["gateway", "run"] ports: - name: gateway @@ -80,14 +101,21 @@ spec: - secretRef: name: hermes-env env: - # k3s injects these automatically; kubectl inside the pod uses the SA token. + # k3s injects KUBERNETES_SERVICE_HOST/PORT + the SA token automatically; + # kubectl inside the pod authenticates as the platform-engineer SA. - name: HERMES_HOME value: /opt/data + # Put the initContainer-installed kubectl/helm on PATH for the hermes user. + - name: PATH + value: /opt/hermes/bin:/opt/hermes/.venv/bin:/tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin volumeMounts: - name: data mountPath: /opt/data - name: workspace mountPath: /workspace + - name: tools + mountPath: /tools + readOnly: true resources: requests: memory: "512Mi" @@ -104,7 +132,6 @@ spec: failureThreshold: 3 securityContext: allowPrivilegeEscalation: false - runAsNonRoot: false # official image runs as root for s6 init then drops to hermes volumes: - name: data @@ -112,6 +139,8 @@ spec: claimName: hermes-data - name: workspace emptyDir: {} + - name: tools + emptyDir: {} - name: seed configMap: name: hermes-seed