{{- /* ONE claim, mounted at /app/data, holding all FOUR of Bulwark's directories as subdirectories of it: admin config.json, policy.json, admin.json (the password hash), plugin-config/, plugins/, themes/, branding uploads admin-state admin-state.json (login timestamps), audit.log, the bootstrap setup token settings the encrypted per-account user settings telemetry consent and instance id ONE VOLUME AND NOT FOUR, because a snapshot is atomic per volume and never across volumes - the durability lesson garage (#81) was built on. Split up, a backup can capture an audit log that records logins the configuration does not know about yet, or settings encrypted against a secret the configuration has since been repointed from. There is no argument on the other side here: this is a few hundred kilobytes of JSON plus an append-only log, not an object store. Bulwark creates all four subdirectories itself on start (ensureConfigDir and ensureStateDir, both mkdir -p). It has to: the image's own `mkdir -p /app/data/...` ran in a layer that this mount covers. fsGroup is what makes the freshly provisioned volume writable for uid 1001. DELIBERATELY NOT null-SAFE: an erased size yields an invalid PVC that is rejected at apply time, which is loud. A chart-side fallback would silently size somebody's volume - and on an existing release it could not help anyway, because a PVC cannot shrink. Same reasoning as garage's storage block and satisfactory's documented exception (Gitea #39). NEVER RENAMED. A renamed PVC makes Kubernetes provision a new, empty volume and orphans the data - here that means admin.json, the only copy of the admin password hash, and audit.log, which by its nature cannot be reconstructed. */ -}} apiVersion: v1 kind: PersistentVolumeClaim metadata: name: {{ .Release.Name }}-{{ .Chart.Name }}-pvc labels: app: {{ .Release.Name }}-{{ .Chart.Name }}-sfs spec: accessModes: # ReadWriteOnce, and the single replica follows from it rather than the other # way round - see the bulwark.replicas helper. - ReadWriteOnce resources: requests: storage: {{ .Values.storage.amount }} {{- if .Values.storage.storageClass }} storageClassName: {{ .Values.storage.storageClass }} {{- end }}