Storage and Backups
Kanera holds two things you cannot regenerate: the PostgreSQL database and uploaded files. Decide where each lives before you invite people in.
Upload storage
By default, uploaded files are stored in the kanera_uploads Docker volume.
For S3-compatible storage, set:
S3_REGION=auto
S3_BUCKET=kanera
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...
S3_ENDPOINT=https://s3.example.com
S3_PUBLIC_URL_PREFIX=https://cdn.example.com/kanera
When the required S3 values are set, S3 takes precedence over local upload storage.
Self-hosted Kanera has no storage quota, so attachment capacity is whatever the volume or bucket provides. File volume and retention usually drive disk requirements more than Kanera itself, so alert on disk growth.
Backups
Back up both:
| Data | Location |
|---|---|
| PostgreSQL data | kanera_pgdata Docker volume. |
| Uploaded files | kanera_uploads Docker volume, unless S3 storage is configured. |
Manual PostgreSQL backup:
docker compose exec -T postgres pg_dump -U kanera kanera | gzip > kanera-$(date +%F).sql.gz
Kanera can also run encrypted full PostgreSQL backups to S3-compatible storage:
DB_BACKUPS_ENABLED=true
DB_BACKUP_ENCRYPTION_PASSPHRASE=<openssl rand -hex 32>
DB_BACKUP_TIMES_UTC=00:15,12:15,16:45
DB_BACKUP_RETENTION_DAYS=14
DB_BACKUP_S3_PREFIX=backups/postgres
The backup service compresses the dump, encrypts it with GPG symmetric AES-256, uploads it to S3, and prunes old backups after successful uploads. Store DB_BACKUP_ENCRYPTION_PASSPHRASE somewhere durable outside the deployment too; it is required to restore backups.
Keep database and uploaded-file backups off the server's primary disk. A backup on the same volume as the data does not survive the failure it exists for.
Secrets worth keeping
Losing these costs you data rather than uptime:
| Value | If it changes or is lost |
|---|---|
DB_BACKUP_ENCRYPTION_PASSPHRASE | Existing encrypted backups cannot be restored. |
SECRETS_ENCRYPTION_KEY | Stored integration credentials, such as chat destination and personal webhook secrets, can no longer be decrypted. |
MFA_ENCRYPTION_KEY | Enrolled authenticators and outstanding MFA challenges become invalid. |
MEDIA_SIGNING_SECRET | Existing signed media URLs stop resolving. |
JWT_SECRET | Everyone is signed out. |