Helm: Storage and backups
Zulip stores persistent data (uploads, avatars, and configuration) in a volume
mounted at /data inside the container. The Helm chart manages this storage
through a PersistentVolumeClaim.
Configuring storage
By default, the chart creates a 10Gi PVC with ReadWriteOnce access. You can
customize this in your values file:
zulip:
persistence:
enabled: true
accessModes:
- ReadWriteOnce
size: 20Gi
storageClass: "fast-ssd"
Using an existing PVC
If you have a pre-existing PersistentVolumeClaim (for example, restored from a backup), you can tell the chart to use it instead of creating a new one:
zulip:
persistence:
enabled: true
existingClaim: my-existing-zulip-pvc
When existingClaim is set, the chart does not create a PVC; the StatefulSet
references the named claim directly.
Backing up
The PVC mounted at /data is the unit of backup. A
VolumeSnapshot
captures everything Zulip needs to restore a deployment, because
/data/backups/ already holds a recent pg_dump written there by
app:backup on a daily schedule (see AUTO_BACKUP_ENABLED).
Most operators drive snapshot creation through a higher-level
orchestrator that handles retention, off-cluster storage, and
scheduling. Velero is the standard open-source
option, and commercial alternatives also exist. The VolumeSnapshot
CRD is also usable directly when no orchestrator is in play.
For coherence with the freshest possible database dump, refresh
app:backup immediately before snapshotting:
kubectl exec zulip-0 -c zulip -- /sbin/entrypoint.sh app:backup
If you need just the database dump out-of-band:
kubectl cp zulip-0:/data/backups/ ./backups/ -c zulip
To avoid backing up uploads at all, configure Zulip to use S3-compatible storage as a native upload backend, which keeps the PVC small.
See /data volume layout for the cross-deployment backup model.
Off-site database backups
For continuous off-site database backups, independent of the volume-snapshot path, Zulip supports WAL-based archiving via wal-g, which streams write-ahead logs to S3 for point-in-time recovery.
Adding a sidecar container
You can use the sidecars value to run additional containers alongside Zulip
that share its persistent volume. The volume name follows the pattern
<fullname>-persistent-storage; for the helm install zulip command from the
getting-started guide, the full name resolves to zulip, so the volume is
zulip-persistent-storage:
sidecars:
- name: my-sidecar
image: busybox:latest
command: ["sleep", "infinity"]
volumeMounts:
- name: zulip-persistent-storage
mountPath: /data
readOnly: true