backup-restore · git:20260928.2939037 · 2026-09-28 · sha256 79c6cb5128ffc01f
backup-restore git:20260928.2939037A
Immutable. This exact content never changes and is served at /api/v1/blob/79c6cb5128ffc01f.
--- name: backup-restore description: >- Manage kopiur Kopia-based backups and restores for Kubernetes PVs in this cluster. user: "check backup status for app X" → describe the SnapshotPolicy/SnapshotSchedule user: "restore from backup" → follow the restore workflow below user: "trigger manual backup" → `kubectl kopiur snapshot now --policy <app> -n <ns> --wait` user: "backup failing" → delegate to debug-cluster for mover pod logs Use when the user mentions backups, restores, snapshots, SnapshotPolicy, SnapshotSchedule, Restore, ClusterRepository, PVC recovery, or disaster recovery. This cluster uses kopiur (home-operations, kopia-native) — not VolSync, not restic. Migrated 2026-07-12. compatibility: Requires `kubectl` access to the cluster and the `kopiur` kubectl plugin; kopiur CRDs and the shared ClusterRepository secret must exist. --- # Backup and restore (kopiur + Kopia) ## Quick reference | Operation | Command | |-----------|---------| | List policies | `kubectl get snapshotpolicy -A` | | List schedules | `kubectl get snapshotschedule -A` | | List snapshots for an app | `kubectl kopiur snapshots list --policy <app> -n <ns>` | | Trigger manual snapshot | `kubectl kopiur snapshot now --policy <app> -n <ns> --wait` | | Check a restore | `kubectl get restore <app>-restore -n <ns>` | | Status | `kubectl describe snapshotpolicy <app> -n <ns>` | ## Check status A healthy policy shows `Ready: True` and a recent `status.lastSuccessfulSnapshot`. The `SnapshotSchedule` object's `status.observedGeneration` sticking behind `.metadata.generation` is a known cosmetic quirk (fleet-wide, harmless) — it makes the owning Flux Kustomization's `wait: true` health check flap (`HealthCheckFailed ... status: 'InProgress'`, self-clears on retry). Don't chase it; trust the policy's own `Ready` condition and a fresh manual snapshot instead. ## Restore from backup The procedure is [docs/kopiur-restore.md](../../../docs/kopiur-restore.md): suspend both Kustomization and HelmRelease, pause KEDA, scale down every deployment sharing the PVC, delete the PVC, resume, verify. That file is the single copy, and also covers point-in-time restore (`offset`/`asOf`/`snapshotRef`/`identity`), the kopiur#233 orphaned-`prime-*`-PVC trap and its sweep commands, and the live-uid check. Not in that file: when the live uid does not match the manifest's `runAsUser`, `KOPIUR_PUID`/`KOPIUR_PGID` (and, only for genuine root, `KOPIUR_MOVER_CAPS_ADD: "[DAC_READ_SEARCH]"`) go in the app's own `ks.yaml` `postBuild.substitute` block — see [references/restore-pvc.md](references/restore-pvc.md). ## Enable backups for a new app Reference patterns in `kubernetes/components/kopiur/`. See [references/restore-pvc.md](references/restore-pvc.md) for the full substitute-variable list. ## Troubleshooting (inline) - Repository secret: `kubectl get secret -n kopiur-system kopia-nas-password` (shared across all apps via credential projection — apps don't carry their own copy) - `ClusterRepository` health: `kubectl get clusterrepository kopia-nas` Symptom-keyed failures (PVC never claimed, restore stalling, wrong `dataSourceRef`, mover stuck with no output) → [docs/kopiur-restore.md](../../../docs/kopiur-restore.md) Troubleshooting. For mover logs and deep failures → [debug-cluster](../debug-cluster/SKILL.md).