Backup Architecture & Matrix
Backup Engine: Kopia (
kopia/kopia:latest)
Destination: Cloudflare R2 Object Storage (cortex-backups)
Encryption: Client-side AES-256-GCM (AES256-GCM-HMAC-SHA256)
Egress Fees: $0 (Cloudflare R2)
Architecture & How It Works
Kopia runs as a standalone container on host latitude. It snapshots read-only (:ro) host bind mounts and named Docker volumes directly to an encrypted S3-compatible Cloudflare R2 bucket.
flowchart TD
subgraph Host ["Host Server (latitude)"]
subgraph DockerStacks ["Docker Stacks"]
DB_Dumpers["Automated DB Dumpers<br/>Paperless, Immich, AdventureLog"]
Configs["Application Configs and Secrets<br/>Home Assistant, Authelia, Caddy"]
Media["Media and User Documents<br/>Immich Library, Paperless"]
end
KopiaContainer["Kopia Container (Read-Only)"]
end
subgraph Cloudflare ["Cloudflare R2 Offsite"]
R2Bucket["cortex-backups bucket<br/>AES-256 Encrypted"]
end
DB_Dumpers -->|"DB Dumps (.sql.gz)"| KopiaContainer
Configs -->|"Read-Only Bind Mounts"| KopiaContainer
Media -->|"Read-Only Bind Mounts"| KopiaContainer
KopiaContainer -->|"Encrypted S3 Sync"| R2Bucket
Core Mechanics
- Zero-Knowledge Encryption: Data is chunked, compressed, and encrypted locally using
AES256-GCMbefore transmission over TLS. - Content Deduplication: Kopia content-addressable storage (Buzhash + BLAKE2B-256) ensures duplicate or unchanged files consume zero extra storage.
- Automated Database Consistency: Live databases (PostgreSQL/PostGIS) use
postgres-backup-localcompanion containers that generate clean daily.sql.gzdumps. Kopia backs up these consistent dumps rather than raw live database files, preventing DB corruption during snapshot windows.
Backup Matrix
| Service | Source Path / Volume | Kopia Target Path | Content Included |
|---|---|---|---|
| Immich (Database) | immich_db-dumps (Volume) |
/data/immich_db_dumps |
Daily automated PostgreSQL dumps |
| Immich (Library) | /home/tforkan/docker/immich/library/library |
/data/immich-library |
Original photos/videos (previews excluded) |
| Paperless-ngx | paperless-ngx_datapaperless-ngx_mediapaperless-ngx_db-dumps |
/data/paperless_data/data/paperless_media/data/paperless_db_dumps |
Index, uploaded documents, DB dumps |
| AdventureLog | adventurelog_db-dumpsadventurelog_adventurelog_media |
/data/adventurelog_db_dumps/data/adventurelog_media |
Automated PostGIS DB dumps, trip media |
| Home Assistant | /home/tforkan/docker/homeassistant/config |
/data/homeassistant_config |
YAML configs, automations, DB, integration tokens |
| Authelia | /home/tforkan/docker/authelia/config/home/tforkan/docker/authelia/secrets |
/data/authelia_config/data/authelia_secrets |
Configuration, access control rules, secrets |
| Jellyfin | /home/tforkan/docker/jellyfin/config |
/data/jellyfin_config |
Watch state, user metadata, configs (media excluded) |
| Beszel | /home/tforkan/docker/beszel/beszel_databeszel_agent_data |
/data/beszel_data/data/beszel_agent_data |
Server monitoring history & agent tokens |
| Homebox | homebox_homebox-data (Volume) |
/data/homebox_data |
Inventory database & file attachments |
| Uptime Kuma | uptime-kuma_uptime-kuma (Volume) |
/data/uptime_kuma_data |
Uptime history, status pages, monitors |
| Pi-hole | /home/tforkan/docker/pihole/etc-piholeetc-dnsmasq.d |
/data/pihole_etc_pihole/data/pihole_etc_dnsmasq |
Local DNS records, blocklists, custom DHCP |
| Seerr | /home/tforkan/docker/seerr/config |
/data/seerr_config |
Media request history & API connections |
| Yamtrack | /home/tforkan/docker/yamtrack/db |
/data/yamtrack_db |
Game tracking SQLite database |
| Glance | /home/tforkan/docker/glance/config |
/data/glance_config |
Dashboard configuration YAMLs |
| ntfy | /etc/ntfy |
/data/ntfy_config |
Push notification server configuration |
| Socials Immich Bot | /home/tforkan/docker/socials-immich-bot |
/data/socials_immich_bot |
Bot code, .env, platform authentication cookies |
| Caddy | /etc/caddy |
/data/caddy |
Reverse proxy Caddyfile & certificates |
Policies & Exclusions
- Excluded Media:
- Immich Transcoded Videos: Transcoded/encoded preview videos are excluded to save bandwidth and cloud storage. Original full-quality media in
library/libraryis 100% preserved. - Jellyfin Media: Raw movie and TV show files are excluded from cloud snapshots due to size; only metadata and watch state in
/configare backed up. - Secrets Storage:
- Local
.envfiles are gitignored. The master Kopia repository password and Cloudflare R2 credentials must be securely stored in your password manager (Bitwarden / 1Password). Without the Kopia passphrase, R2 snapshots cannot be decrypted.
Verification & CLI Commands
All commands run inside the running Kopia container:
- List all active snapshots:
- Check Cloudflare R2 connection & storage size:
- Trigger an immediate manual snapshot run across all targets:
- Run maintenance (index compaction & garbage collection):
📖 Need to restore? See
docs/recovery.mdfor step-by-step disaster recovery runbooks.