New chart helm/zddc-server-cache/ deploys zddc-server in client mode against an upstream master. Mirrors the prod chart's source-build-via- init-container pattern but with: - ZDDC_UPSTREAM, ZDDC_MODE, ZDDC_BEARER_FILE, ZDDC_NO_AUTH, ZDDC_SKIP_TLS_VERIFY, ZDDC_MIRROR_SUBTREE, ZDDC_MIRROR_MIN_INTERVAL wired from values.yaml. Mirror-only env vars conditionally rendered (only when mode=mirror) to keep the rendered manifest minimal. - Bearer token mounted from a separately-created Kubernetes Secret (defaultMode 0400) at /etc/zddc/bearer/token. values.yaml.example documents the secret-creation flow but contains no token. Secret reference can be set to "" to disable bearer auth (only valid for upstreams running --no-auth). - Recreate strategy + replicaCount: 1 (multiple replicas would race the cache directory and double the upstream walker traffic). - TCP-socket probes instead of HTTP — HTTP probes against / would fail when both upstream is unreachable AND the cache is empty (the cache layer returns 503 + offline header in that state), causing crashloops. TCP verifies process liveness without depending on upstream reachability or cache contents. - Mounts a separate cache PVC (operator-provided, like the master's data PVC). Sized to the working set you expect to mirror; can be much smaller than the master's data volume. Existing prod and dev charts gain optional ZDDC_NO_AUTH wired from zddc.env.noAuth (default false → no change to existing rendered manifests). Useful for trusted-LAN or genuinely-public master deployments. Updated docs: helm/README.md gains the cache row in the chart table, the cache-install quickstart with the secret-creation flow, and the cache-specific structural notes (Recreate / TCP probes / single- instance). CLAUDE.md and ARCHITECTURE.md updated to reflect three charts instead of two. Verified with helm template rendering: ZDDC_NO_AUTH only renders when noAuth: true; ZDDC_MIRROR_SUBTREE / ZDDC_MIRROR_MIN_INTERVAL only render when mode: mirror; bearer volume + ZDDC_BEARER_FILE only render when bearer.secretName is non-empty. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
162 lines
5.9 KiB
YAML
162 lines
5.9 KiB
YAML
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: {{ include "zddc-server.fullname" . }}
|
|
labels:
|
|
{{- include "zddc-server.labels" . | nindent 4 }}
|
|
spec:
|
|
replicas: {{ .Values.replicaCount }}
|
|
# Cache writes serialize through the local filesystem; running two
|
|
# replicas would race the cache directory + double the upstream
|
|
# walker traffic. Recreate strategy ensures only one pod holds the
|
|
# cache PVC at a time.
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
{{- include "zddc-server.selectorLabels" . | nindent 6 }}
|
|
template:
|
|
metadata:
|
|
labels:
|
|
{{- include "zddc-server.selectorLabels" . | nindent 8 }}
|
|
spec:
|
|
{{- with .Values.imagePullSecrets }}
|
|
imagePullSecrets:
|
|
{{- toYaml . | nindent 8 }}
|
|
{{- end }}
|
|
volumes:
|
|
- name: zddc-bin
|
|
emptyDir: {}
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: {{ .Values.data.pvcName }}
|
|
{{- if .Values.bearer.secretName }}
|
|
- name: bearer
|
|
secret:
|
|
secretName: {{ .Values.bearer.secretName | quote }}
|
|
defaultMode: 0400
|
|
items:
|
|
- key: {{ .Values.bearer.secretKey | quote }}
|
|
path: token
|
|
{{- end }}
|
|
initContainers:
|
|
# Build zddc-server from the pinned git ref. Same flow as the
|
|
# master charts — the binary is the same; client mode is
|
|
# selected at runtime via ZDDC_UPSTREAM.
|
|
- name: build-zddc-server
|
|
image: {{ printf "%s:%s" .Values.buildImage.repository .Values.buildImage.tag | quote }}
|
|
imagePullPolicy: IfNotPresent
|
|
command: ["/bin/sh", "-c"]
|
|
args:
|
|
- |
|
|
set -eu
|
|
apk add --no-cache git
|
|
git clone --depth 1 --branch "$GIT_REF" "$GIT_REPO" /workspace
|
|
cd /workspace/zddc
|
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
|
|
go build -trimpath \
|
|
-ldflags="-s -w -X main.version=$GIT_REF" \
|
|
-o /out/zddc-server \
|
|
./cmd/zddc-server
|
|
echo "built /out/zddc-server from $GIT_REF"
|
|
env:
|
|
- name: GIT_REPO
|
|
value: {{ .Values.zddc.gitRepo | quote }}
|
|
- name: GIT_REF
|
|
value: {{ .Values.zddc.gitRef | quote }}
|
|
volumeMounts:
|
|
- name: zddc-bin
|
|
mountPath: /out
|
|
resources:
|
|
requests:
|
|
cpu: 200m
|
|
memory: 256Mi
|
|
limits:
|
|
cpu: 1000m
|
|
memory: 512Mi
|
|
containers:
|
|
- name: zddc-server
|
|
image: {{ printf "%s:%s" .Values.runtimeImage.repository .Values.runtimeImage.tag | quote }}
|
|
imagePullPolicy: IfNotPresent
|
|
command: ["/zddc/zddc-server"]
|
|
ports:
|
|
- name: http
|
|
containerPort: 8080
|
|
protocol: TCP
|
|
env:
|
|
- name: ZDDC_ROOT
|
|
value: {{ .Values.zddc.env.rootPath | quote }}
|
|
- name: ZDDC_ADDR
|
|
value: {{ .Values.zddc.env.addr | quote }}
|
|
- name: ZDDC_TLS_CERT
|
|
value: "none"
|
|
- name: ZDDC_INSECURE_DIRECT
|
|
value: "1"
|
|
- name: ZDDC_EMAIL_HEADER
|
|
value: {{ .Values.zddc.env.emailHeader | quote }}
|
|
- name: ZDDC_CORS_ORIGIN
|
|
value: {{ .Values.zddc.env.corsOrigin | quote }}
|
|
- name: ZDDC_LOG_LEVEL
|
|
value: {{ .Values.zddc.env.logLevel | quote }}
|
|
- name: ZDDC_INDEX_PATH
|
|
value: {{ .Values.zddc.env.indexPath | quote }}
|
|
{{- if .Values.zddc.env.noAuth }}
|
|
- name: ZDDC_NO_AUTH
|
|
value: "1"
|
|
{{- end }}
|
|
# Client-mode flags. ZDDC_UPSTREAM activates client mode
|
|
# in cmd/zddc-server/main.go's runClient short-circuit.
|
|
- name: ZDDC_UPSTREAM
|
|
value: {{ .Values.zddc.upstream.url | quote }}
|
|
- name: ZDDC_MODE
|
|
value: {{ .Values.zddc.upstream.mode | quote }}
|
|
{{- if .Values.zddc.upstream.skipTLSVerify }}
|
|
- name: ZDDC_SKIP_TLS_VERIFY
|
|
value: "1"
|
|
{{- end }}
|
|
{{- if .Values.bearer.secretName }}
|
|
- name: ZDDC_BEARER_FILE
|
|
value: "/etc/zddc/bearer/token"
|
|
{{- end }}
|
|
{{- if eq .Values.zddc.upstream.mode "mirror" }}
|
|
{{- with .Values.zddc.upstream.mirrorSubtree }}
|
|
- name: ZDDC_MIRROR_SUBTREE
|
|
value: {{ . | quote }}
|
|
{{- end }}
|
|
{{- with .Values.zddc.upstream.mirrorMinInterval }}
|
|
- name: ZDDC_MIRROR_MIN_INTERVAL
|
|
value: {{ . | quote }}
|
|
{{- end }}
|
|
{{- end }}
|
|
volumeMounts:
|
|
- name: zddc-bin
|
|
mountPath: /zddc
|
|
- name: data
|
|
mountPath: {{ .Values.zddc.env.rootPath }}
|
|
{{- with .Values.data.subPath }}
|
|
subPath: {{ . | quote }}
|
|
{{- end }}
|
|
{{- if .Values.bearer.secretName }}
|
|
- name: bearer
|
|
mountPath: /etc/zddc/bearer
|
|
readOnly: true
|
|
{{- end }}
|
|
resources:
|
|
{{- toYaml .Values.resources | nindent 12 }}
|
|
# TCP-socket probes only — HTTP probes against `/` would
|
|
# fail when both upstream is unreachable AND the cache is
|
|
# empty (the cache layer returns 503 in that state). TCP
|
|
# probes verify the server process is alive without
|
|
# depending on upstream reachability or cache contents.
|
|
livenessProbe:
|
|
tcpSocket:
|
|
port: http
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
readinessProbe:
|
|
tcpSocket:
|
|
port: http
|
|
initialDelaySeconds: 2
|
|
periodSeconds: 10
|
|
timeoutSeconds: 3
|