Repository navigation
feat(backups): restore, download, any schedule and copies to an rclone connection from the web app - #263
Merged
Conversation
… machine agent Lens checks GitHub for a new release once a day, backs the database up and installs a release from the API: install.sh sets up a small agent on the machine (systemd path unit on Linux, launchd on a Mac) that watches .lens-control/inbox, reruns install.sh for the requested release and writes how it went back for the web app. Backups can be listed, taken, downloaded and deleted. __version__ now follows releases. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XturGhybJzfgZvbFxfNB2o
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XturGhybJzfgZvbFxfNB2o
… web app Builds on the backups list from the updates work: restoring a backup replaces the database (server: remove and import; embedded: folder swap), with a before-restore backup put back if it fails, then the schema, upgrades and settings reload. Downloads go through a two-minute signed link (embedded folders as .tar.gz). backups.schedule/timezone/keep take scheduled backups from the routine scheduler. Settings > Backups lists them with Back up now, Download, Restore and Delete. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qkVq3xnW9YJboxRYV4qSv
- Settings > Backups: any cron schedule (presets or custom), timezone, how many to keep - Backups go to an rclone storage connection, sealed with secret.key before they leave - Bring a backup back from the connection, then restore it - Embedded restore: queries meanwhile wait for the pool instead of reopening the files Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qkVq3xnW9YJboxRYV4qSv
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qkVq3xnW9YJboxRYV4qSv
Merged
19 of 20 tasks
adeelahmad
pushed a commit
that referenced
this pull request
Oct 10, 2026
updates.restore_on_start now checks the backup with backups.usable and restores it with backups.restore (which takes a before-restore backup, re-applies the schema and reloads settings); migrations.restore and _import are gone. The Updates page links to Settings → Backups instead of listing backups itself. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FZXPL8F3sAdGJKYYgrVHxb
Merged
5 of 8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Adeel · project thread
Description
Before: backups could be listed, taken, downloaded (exports only) and deleted through
/admin/backups. Putting one back meantsurreal importor swapping folders by hand, nothing took backups on a schedule, and every copy stayed on the same machine.After: Settings › Backups lists every backup with Back up now, Download, Restore and Delete. The schedule is fully configurable: off, presets (nightly, every 6 hours, hourly, weekly) or any cron, with a timezone and how many to keep. Backups can also go to a storage connection (any rclone remote from Settings › Sources), sealed with AES-256-GCM under a key derived from
secret.keybefore they leave the machine. Scheduled and manual backups are copied there, and a copy that only exists on the connection can be brought back and restored. Restoring replaces the whole database: what was there is backed up first (before-restore-*) and put back if the restore fails, and a backup from an older Lens is brought up to date afterwards. Downloads use a two-minute signed link; an embedded database's folder downloads as a.tar.gz.How:
app/domain/backups.pygainsrestore(server:REMOVE DATABASE/DEFINE DATABASEthen/import; embedded: folder swap underdb.closed()),run_due(routine scheduler, processes take turns viabackup_schedule:next), andseal/unseal/send/fetchusing the rclone helpers inblobs.py.db.closed()now keeps the pool places taken, so a query that arrives during an embedded restore waits instead of opening the files again, and it waits until the engine has let go of them. New routes arePOST /admin/backups/{name}/restore|link|send|fetch,GET /admin/backups/{name}/file,GET /admin/backups/remoteandDELETE /admin/backups/{name}/remote. Restore and links need an admin signed in with a passkey. New settings arebackups.schedule,timezone,keep(7),connectionandfolder.Motivation and Context
Adeel asked for backup and restore end to end from the web app, then for configurable scheduled backups and remote backups through an rclone remote. The one-click upgrade can call
backups.restorefor its rollback.Types of changes
!in the title)Checklist:
make hookschecks it on commit).tests/api/test_backups.pycovers embedded and a SurrealDB 3.2.4 server; the rclone tests run where rclone is installed.docs/accordingly (docs/database.md#backups).## UnreleasedinCHANGELOG.md.🤖 Generated with Claude Code
https://claude.ai/code/session_012qkVq3xnW9YJboxRYV4qSv