github amayer1983/docksentry v1.22.0
v1.22.0 — Atomic writes + backup/restore + data-loss alert

latest release: v1.22.1
3 hours ago

Major release driven by @famewolf's #2 reports. Three of his Docksentry hosts simultaneously rebooted (likely unattended-upgrades) and came back with completely empty config — container groups gone, web setup wizard re-appearing. We found and fixed the root cause, plus added two layers of defense-in-depth.

Fixed

Persistent state survives mid-write kills

Root cause: both container_store._save_dict and config.save_persistent used open(path, "w") which truncates the file to 0 bytes immediately, before the new content is written. A kill between truncate and close (host reboot, Docker daemon restart, OOM, power loss) left a 0-byte or partial-JSON file. Next boot: parse failed → empty defaults → wizard.

Bug existed since v1.7.0.

Fix: both write paths now write to <path>.tmp, flush() + os.fsync() to push bytes through the kernel page cache to disk, then os.replace() which is POSIX-atomic — either the new file is fully visible or the old one is still there, never a partial state. Applies to settings.json, groups.json, notes.json, links.json, update_windows.json, pending_major.json.

Added

"No persisted settings" Telegram alert on boot

When BOT_TOKEN is configured via env vars but /data/settings.json is missing on startup, surface a Telegram message warning of possible data loss. Users no longer discover the wizard accidentally hours later via the Web UI — the bot tells them immediately.

Backup & Restore via Web UI

New Backup & Restore card on the Settings page:

  • ⬇ Export backup — downloads a single JSON file containing every persisted state (settings, pinned, autoupdate, ask-major flags, container groups, notes, links, update windows) with a schema_version sentinel for forward compatibility
  • ⬆ Restore backup… — reads a previously-exported file and writes each section through the now-atomic save paths

Defense-in-depth against the kind of data loss that hit @famewolf. Also useful for host migrations or routine snapshots. Backup files contain webhook URLs and bot tokens — treat them like passwords.

Container Groups ordering in update notifications, plus 👑 HEAD badge

When a container is the first (head) member of a Container Group with ≥ 2 members, it now gets a 👑 badge in the "🔄 Updates Available" Telegram message. The same message also sorts updates by group position (head first, then dependents in order, orphans at the end). Mirrors the sort handle_autoupdates already did during execution but extends it to the pre-update notification. Reported by @famewolf: with a Gluetun+dependents stack, gluetun was showing up LAST in the notification, making cascade-debugging harder.

API

  • /api/backup_export (GET) — returns a docksentry-backup-YYYYMMDD-HHMMSS.json attachment with the full state bundle. Read-only.
  • /api/backup_import (POST, multipart/form-data with file field) — accepts a backup bundle, restores each known section, returns {ok, restored: [...], errors: [...], schema_version, from_version}. Unknown / missing sections are silently skipped (forward-compatible).

Cleanup

  • _groups_html removed (dead code since v1.21.1 when the legacy Settings → Groups card became a redirect banner).

Upgrade

docker pull amayer1983/docksentry:latest
docker compose up -d

Hard-reload the Web UI (Ctrl+Shift+R) once after pulling so the new Backup/Restore card's JS lands.

Strongly recommended: after pulling, open Web UI → Settings → Backup & Restore → Export backup and save the file somewhere safe. If anything goes sideways, you can restore in one click.

Don't miss a new docksentry release

NewReleases is sending notifications on new releases.