Skip to content

SmallWorlds v1.2.39

Choose a tag to compare

@github-actions github-actions released this 14 Aug 18:06
· 50 commits to main since this release

Backup data now lives on its own volume, separate from the data it protects.

Upgrade note — rebuild, do not bump

Do not adopt this release on an existing cluster by bumping your overlay's pinned tag. Nodes provisioned before it have no /mnt/smallworlds-backup, so garage-backup's volumes never bind, and every tenant's garage-init blocks waiting for an instance that can never start — a total sync stall with nothing obviously pointing at the cause. Rebuild the node from this release instead.

If you have ever configured the offsite leg, members' personal pods are at your offsite provider now. The previous replicator synced the whole Garage instance and the setup guide granted read on every bucket, so pod archives — unencrypted, including the PIN-protected immich-locked/ prefix — were copied offsite in contradiction of ADR 0047. This release stops that, but does not undo it. Delete those objects by hand, prior versions included.

Device enrolment is now mandatory. The nightly Immich export fails while any member holding assets has no enrolled device, and names them. Set REQUIRE_ENROLMENT=false on the export CronJob if your community has accepted the risk.

What changed

  • Two volumes. A second block volume holds every Recovery Point, served by a new garage-backup instance with both its data and its metadata on it. Terraform provisions it; both bootstraps refuse to start if the two paths land on the same device. (ADR 0048)
  • Database backups ran hourly, not daily. CloudNativePG's schedule takes a six-field cron with seconds first, so "0 2 * * *" meant "minute 2 of every hour" — roughly 144 base backups a day across six clusters, all retained seven days. Now "0 0 2 * * *".
  • Garage never used its 120 Gi volume. apps/garage.yaml set persistence.size and persistence.storageClass, which chart 0.7.1 does not define, so Helm ignored them and Garage ran on a 1 Gi local-path claim.
  • Nextcloud's user files had no server-side backup. pv-backup covered only /var/www/html. They are now copied nightly to garage-backup, with deleted and superseded objects retained under versions/<date>/.
  • The offsite leg is scoped. An explicit bucket list, never pod-gateway, plus a refusal to run if the replicator key can even see that bucket. Destination buckets must be pre-created with versioning enabled — buckets rclone creates on first sync are un-versioned, which silently reduces the offsite copy to a mirror.
  • Restoring Immich originals is now documented and tooled (admin-tools/restore-immich-originals.py, §7.4). It reads the pod bucket by default, verifies every object against its manifest digest, and refuses a mismatch rather than writing it. Note it requires a restored database first: only the database maps an archive key to a library path.
  • Pod archive monitoring. The gateway's metrics were never scraped; there is now a ServiceMonitor and alerts for a device that has gone stale, one that has never checked in, and orphaned objects.

Verification

The chain was exercised end to end on a purpose-built cluster: barman, Velero and pod objects landing on the separate device, a CNPG restore from Garage, and Immich originals restored from the pod bucket and served back byte-identical to their export-time digests. The full rebuild-from-nothing sequence (§7.6) has still not been drilled and is documented as a plan.

Release inputs

The k3s installer digest is bumped: upstream replaced the script at https://get.k3s.io, so the previous pin no longer matches. The k3s version it installs is unchanged (v1.36.2+k3s1), as is the Argo CD manifest.