# The server pod runs teamclaw-server with the secret broker as a sidecar # sharing a private emptyDir for the unix socket — the §15 topology: no # network hop carries credentials, and nothing else can reach the socket. apiVersion: apps/v1 kind: Deployment metadata: name: teamclaw-server labels: {{- include "teamclaw.labels" . | nindent 4 }} spec: replicas: {{ .Values.server.replicas }} selector: matchLabels: {{- include "teamclaw.serverSelector" . | nindent 6 }} template: metadata: labels: {{- include "teamclaw.serverSelector" . | nindent 8 }} app.kubernetes.io/instance: {{ .Release.Name }} spec: securityContext: runAsNonRoot: true runAsUser: 10001 seccompProfile: { type: RuntimeDefault } containers: - name: server image: "{{ .Values.image.registry }}/server:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - { containerPort: 8080, name: http } env: - name: TEAMCLAW_CONFIG value: /etc/teamclaw/teamclaw.toml - name: TEAMCLAW_DATABASE__URL valueFrom: secretKeyRef: name: {{ .Values.database.urlSecretName }} key: url {{- if eq .Values.llm.provider "anthropic" }} - name: ANTHROPIC_API_KEY valueFrom: secretKeyRef: name: {{ .Values.llm.apiKeySecretName }} key: api-key {{- end }} {{- if eq .Values.storage.backend "s3" }} - name: TEAMCLAW_STORAGE__S3_ACCESS_KEY valueFrom: secretKeyRef: name: {{ .Values.storage.s3.credentialsSecretName }} key: access-key - name: TEAMCLAW_STORAGE__S3_SECRET_KEY valueFrom: secretKeyRef: name: {{ .Values.storage.s3.credentialsSecretName }} key: secret-key {{- end }} volumeMounts: - { name: config, mountPath: /etc/teamclaw, readOnly: true } - { name: broker-socket, mountPath: /run/teamclaw } {{- if eq .Values.storage.backend "local" }} - { name: data, mountPath: {{ .Values.storage.dataDir }} } {{- end }} readinessProbe: httpGet: { path: /healthz, port: http } initialDelaySeconds: 3 resources: {{- toYaml .Values.server.resources | nindent 12 }} securityContext: allowPrivilegeEscalation: false capabilities: { drop: ["ALL"] } readOnlyRootFilesystem: true - name: broker image: "{{ .Values.image.registry }}/broker:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: - name: TEAMCLAW_BROKER_SOCKET value: /run/teamclaw/broker.sock - name: TEAMCLAW_BROKER_KEY_FILE value: /etc/teamclaw-broker/broker.key - name: TEAMCLAW_DATABASE__URL valueFrom: secretKeyRef: name: {{ .Values.database.urlSecretName }} key: url volumeMounts: - { name: broker-socket, mountPath: /run/teamclaw } - { name: broker-key, mountPath: /etc/teamclaw-broker, readOnly: true } resources: {{- toYaml .Values.broker.resources | nindent 12 }} securityContext: allowPrivilegeEscalation: false capabilities: { drop: ["ALL"] } readOnlyRootFilesystem: true volumes: - name: config configMap: { name: teamclaw-config } - name: broker-socket emptyDir: {} - name: broker-key secret: { secretName: {{ .Values.broker.keySecretName }} } {{- if eq .Values.storage.backend "local" }} - name: data persistentVolumeClaim: { claimName: teamclaw-data } {{- end }} --- apiVersion: v1 kind: Service metadata: name: teamclaw-server labels: {{- include "teamclaw.labels" . | nindent 4 }} spec: selector: {{- include "teamclaw.serverSelector" . | nindent 4 }} ports: - { name: http, port: 8080, targetPort: http } {{- if eq .Values.storage.backend "local" }} --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: teamclaw-data labels: {{- include "teamclaw.labels" . | nindent 4 }} spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: {{ .Values.storage.pvcSize }} {{- end }}