Files
honeyDueAPI/deploy-k3s/manifests/api/deployment.yaml
T
Trey t 1cd6cafa9d
Backend CI / Test (push) Has been cancelled
Backend CI / Contract Tests (push) Has been cancelled
Backend CI / Build (push) Has been cancelled
Backend CI / Lint (push) Has been cancelled
Backend CI / Secret Scanning (push) Has been cancelled
deploy-k3s: wire B2_KEY_ID/B2_APP_KEY into api Deployment
The B2 credentials existed in honeydue-secrets (created by
02-setup-secrets.sh) but were never referenced from the api
Deployment, so StorageConfig.IsS3() returned false at runtime →
StorageService fell back to local filesystem. With
readOnlyRootFilesystem=true on the api container, that local
fallback would silently fail on every upload — meaning every
photo, document, and task-completion upload was broken in prod
since the k3s migration on 2026-04-24.

Adding both as secretKeyRef on the api container only (the worker
doesn't perform uploads). Verified end-to-end with a registered
test user: source PDF (sha256=3af3a645...) → POST /api/uploads/document/
→ POST /api/documents/ → GET /api/media/document/:id → byte-identical
download. Storage init log now reports "Storage service initialized (S3)".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 00:53:25 -05:00

139 lines
4.2 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: honeydue
labels:
app.kubernetes.io/name: api
app.kubernetes.io/part-of: honeydue
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: api
template:
metadata:
labels:
app.kubernetes.io/name: api
app.kubernetes.io/part-of: honeydue
spec:
serviceAccountName: api
imagePullSecrets:
- name: ghcr-credentials
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: IMAGE_PLACEHOLDER # Replaced by 03-deploy.sh
ports:
- containerPort: 8000
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
envFrom:
- configMapRef:
name: honeydue-config
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: honeydue-secrets
key: POSTGRES_PASSWORD
- name: SECRET_KEY
valueFrom:
secretKeyRef:
name: honeydue-secrets
key: SECRET_KEY
- name: EMAIL_HOST_PASSWORD
valueFrom:
secretKeyRef:
name: honeydue-secrets
key: EMAIL_HOST_PASSWORD
- name: FCM_SERVER_KEY
valueFrom:
secretKeyRef:
name: honeydue-secrets
key: FCM_SERVER_KEY
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: honeydue-secrets
key: REDIS_PASSWORD
optional: true
# B2 (Backblaze) credentials. With both set, StorageConfig.IsS3()
# returns true and uploads stream to B2 via minio-go. With either
# missing, code falls back to local filesystem — and since
# readOnlyRootFilesystem is true on this container, that fallback
# silently fails. So both must be wired or uploads break.
- name: B2_KEY_ID
valueFrom:
secretKeyRef:
name: honeydue-secrets
key: B2_KEY_ID
- name: B2_APP_KEY
valueFrom:
secretKeyRef:
name: honeydue-secrets
key: B2_APP_KEY
volumeMounts:
- name: apns-key
mountPath: /secrets/apns
readOnly: true
- name: tmp
mountPath: /tmp
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: "1"
memory: 512Mi
startupProbe:
httpGet:
path: /api/health/
port: 8000
# MigrateWithLock in cmd/api/main.go runs pg_advisory_lock on
# every startup. On a cold boot with 3 replicas, the first does
# AutoMigrate (~90s) and the others wait on the lock, so real
# startup runs 90240s. 48 × 5s = 240s grace absorbs it without
# healthcheck killing a still-starting replica.
failureThreshold: 48
periodSeconds: 5
readinessProbe:
httpGet:
path: /api/health/
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
livenessProbe:
httpGet:
path: /api/health/
port: 8000
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 10
volumes:
- name: apns-key
secret:
secretName: honeydue-apns-key
items:
- key: apns_auth_key.p8
path: apns_auth_key.p8
- name: tmp
emptyDir:
sizeLimit: 64Mi