diff --git a/dockerfiles/Dockerfile.hermes-chat-router b/dockerfiles/Dockerfile.hermes-chat-router new file mode 100644 index 000000000..f7fa5a04c --- /dev/null +++ b/dockerfiles/Dockerfile.hermes-chat-router @@ -0,0 +1,23 @@ +# dockerfiles/Dockerfile.hermes-chat-router +FROM --platform=$BUILDPLATFORM golang:1.24-alpine@sha256:8bee1901f1e530bfb4a7850aa7a479d17ae3a18beb6e09064ed54cfd245b7191 AS build + +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /src +COPY services/hermes/router/ ./ + +RUN GO111MODULE=off CGO_ENABLED=0 go test . \ + && GOOS=${TARGETOS} GOARCH=${TARGETARCH} GO111MODULE=off CGO_ENABLED=0 go build \ + -trimpath \ + -ldflags="-s -w" \ + -o /out/chat-router . + +FROM scratch + +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=build --chown=10000:10000 /out/chat-router /chat-router + +USER 10000:10000 +EXPOSE 8080 +ENTRYPOINT ["/chat-router"] diff --git a/services/hermes/agent-deployment.yaml b/services/hermes/agent-deployment.yaml index a5990288e..6d3e26cff 100644 --- a/services/hermes/agent-deployment.yaml +++ b/services/hermes/agent-deployment.yaml @@ -67,6 +67,13 @@ spec: - key: kubernetes.io/hostname operator: NotIn values: [titan-13, titan-15, titan-17, titan-18, titan-19] + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: [arm64] + - key: jetson + operator: In + values: ["true"] preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: @@ -238,6 +245,7 @@ spec: - name: hermes image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f imagePullPolicy: IfNotPresent + command: [/opt/hermes/.venv/bin/hermes] args: [gateway, run] ports: - {name: dashboard, containerPort: 9119, protocol: TCP} diff --git a/services/hermes/chat-router.yaml b/services/hermes/chat-router.yaml index d4ab57e69..046ebea2e 100644 --- a/services/hermes/chat-router.yaml +++ b/services/hermes/chat-router.yaml @@ -20,7 +20,7 @@ spec: app: hermes-chat-router annotations: ai.bstein.dev/role: privacy-preserving-chat-tenant-router - ai.bstein.dev/config-rev: "20260808-webui-telegram" + ai.bstein.dev/config-rev: "20260808-webui-telegram-router-image" vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/agent-pre-populate-only: "true" vault.hashicorp.com/agent-init-first: "true" @@ -60,37 +60,10 @@ spec: - key: hardware operator: In values: [rpi5] - initContainers: - - name: build-router - image: golang:1.24-alpine@sha256:8bee1901f1e530bfb4a7850aa7a479d17ae3a18beb6e09064ed54cfd245b7191 - imagePullPolicy: IfNotPresent - command: - - sh - - -c - - | - set -eu - cd /src - GOCACHE=/tmp/go-cache GO111MODULE=off CGO_ENABLED=0 go test . - GOCACHE=/tmp/go-cache GO111MODULE=off CGO_ENABLED=0 go build -trimpath -o /tools/chat-router . - chmod 0755 /tools/chat-router - securityContext: - allowPrivilegeEscalation: false - runAsUser: 10000 - runAsGroup: 10000 - seccompProfile: - type: RuntimeDefault - volumeMounts: - - {name: source, mountPath: /src, readOnly: true} - - {name: tools, mountPath: /tools} - - {name: tmp, mountPath: /tmp} - resources: - requests: {cpu: 100m, memory: 128Mi} - limits: {cpu: "1", memory: 512Mi} containers: - name: router - image: busybox:1.37 + image: registry.bstein.dev/bstein/hermes-chat-router@sha256:ccb3a7c7ceba317153ff64455777459a5cfd9497bc0e6f51687feedfbfd6f4ed imagePullPolicy: IfNotPresent - command: [/tools/chat-router] ports: - {name: http, containerPort: 8080, protocol: TCP} env: @@ -115,18 +88,12 @@ spec: seccompProfile: type: RuntimeDefault volumeMounts: - - {name: tools, mountPath: /tools, readOnly: true} - {name: state, mountPath: /state} - {name: tmp, mountPath: /tmp} resources: requests: {cpu: 25m, memory: 32Mi} limits: {cpu: 250m, memory: 128Mi} volumes: - - name: source - configMap: - name: hermes-chat-router-source - - name: tools - emptyDir: {} - name: state persistentVolumeClaim: claimName: hermes-chat-router-state diff --git a/services/hermes/chat-statefulset.yaml b/services/hermes/chat-statefulset.yaml index 339a86bfa..32c5c7d35 100644 --- a/services/hermes/chat-statefulset.yaml +++ b/services/hermes/chat-statefulset.yaml @@ -154,6 +154,7 @@ spec: - name: hermes image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f imagePullPolicy: IfNotPresent + command: [/opt/hermes/.venv/bin/hermes] args: [gateway, run] ports: - {name: api, containerPort: 8642, protocol: TCP} diff --git a/services/hermes/deployment.yaml b/services/hermes/deployment.yaml index ea777ab04..e0f71204c 100644 --- a/services/hermes/deployment.yaml +++ b/services/hermes/deployment.yaml @@ -74,6 +74,15 @@ spec: - titan-17 - titan-18 - titan-19 + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - arm64 + - key: jetson + operator: In + values: + - "true" preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: @@ -253,6 +262,7 @@ spec: - name: hermes image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f imagePullPolicy: IfNotPresent + command: [/opt/hermes/.venv/bin/hermes] args: - gateway - run diff --git a/services/hermes/kustomization.yaml b/services/hermes/kustomization.yaml index ea2258a1c..c3a7fef32 100644 --- a/services/hermes/kustomization.yaml +++ b/services/hermes/kustomization.yaml @@ -43,16 +43,6 @@ configMapGenerator: - patch_hermes_auth.py=scripts/patch_hermes_auth.py options: disableNameSuffixHash: true - - name: hermes-chat-router-source - namespace: hermes - files: - - main.go=router/main.go - - main_test.go=router/main_test.go - - telegram.go=router/telegram.go - - telegram_test.go=router/telegram_test.go - - web.go=router/web.go - options: - disableNameSuffixHash: true - name: hermes-triage-skill namespace: hermes files: