backup
Where config backups are written — local paths, an external disk, and remote destinations through rclone — and whether each one is reachable.
List backup destinations
Every place a config backup is written, with its last successful backup and whether it is stale. Credentials are never returned — `hasSecrets` is the only trace of them.
Add a backup destination
A remote destination (`smb`, `s3`, `sftp`, `webdav`, `rclone`) is written through rclone and is always encrypted. It is refused with 400 `backup_passphrase_required` while no backup passphrase is set, and with 424 `rclone_missing` — whose `message` carries the install command — when rclone is not installed. Credentials in `secrets` are sealed under the machine key before they reach the database. Local destinations work without rclone.
Change a backup destination's enabled flag or retention
Changes `enabled` and `retention` in place; a field left out is left as it is. Its type, path, options and credentials cannot be changed — remove the destination and add it again. Disabling never removes an archive or the credentials, and the next backup run uses the new values without a restart. Retention is bounded as in `createBackupDestination` (each count 0 to 1000, at least one archive kept) and, as always, applies only to archives this installation wrote. Switching a disabled destination back on restarts its staleness clock, so it is not reported stale until two days after that. 404 `backup_destination_not_found` for an unknown id; 400 `backup_destination_invalid` for a retention out of bounds.
Remove a backup destination
Removes the destination's configuration. Archives already written to it are left where they are.
Test a backup destination
Writes a small file to the destination, reads it back and deletes it. A destination that cannot be reached is a `200` with `success` false and the reason; a missing rclone is a `424` `rclone_missing`.
Last restore drill
The result of the most recent restore drill: whether the newest config archive on each enabled backup destination could be fetched, opened the way a restore opens it, and verified, and when. `lastRun` is absent until a drill has run. 501 `not_configured` when this daemon has no backup service. When the next drill is due is in `getSchedules`, under the `restore_drill` job.
Run a restore drill now
Queues a `restore_drill` job (service class), the job the monthly schedule queues. It fetches the newest config archive this installation wrote to each enabled destination, opens it the way a restore would (an encrypted one through its identity sidecar and the backup passphrase alone), checks its checksums and that `state.db` opens and passes `PRAGMA integrity_check`, and discards everything it fetched. It never writes to a destination and never reads the live database. A destination that cannot be read, or holds no archive written by this installation, fails the drill. The result replaces the one `getRestoreDrill` returns, and a failed drill publishes a `restore_drill_failed` notification. A drill behind another one queues rather than failing.
Appdata backup policy
Every container with a bind-mounted directory inside the appdata location (the cache disk's `appdata` directory), each with whether the backup stops it while its directory is copied and whether it is in the backup at all. A container the operator has not configured is stopped and included. A known database image that is not stopped carries `warning`: copying a database's files while it runs can produce an archive that does not restore. 501 `not_configured` when this daemon has no Docker Engine client, and 503 when the Engine is not reachable.
Start an appdata backup
Queues an `appdata_backup` job (service class): every container that is running and set to be stopped is stopped, each included container's appdata directories are archived, one archive per container, on the same device as the appdata location, the stopped containers are started again in reverse order, and only then are the archives verified and written to the enabled backup destinations (never the boot device's default destination, which is too small for appdata). `containers` limits the run to the named containers; omit it for every included one. Refused with 409 `array_stopped` while the array is stopped or its storage is not ready — with the cache disk unmounted the appdata directories are empty — and 404 `container_not_found` for a name that is not in scope. A run that fails publishes an `appdata_backup_failed` notification.
Set a container's appdata backup policy
Replaces the container's policy. Opting a known database image out of being stopped is allowed, and the response carries `warning` saying why that is a bad idea. 404 `container_not_found` for a name with no appdata directory in scope.
List appdata archives
The appdata archives this installation wrote to each enabled backup destination, newest first, optionally for one container. It lists the destinations when asked — a remote destination is reached through rclone — and a destination that could not be listed is reported in `unavailable` instead of being read as having no archives.
Restore one container's appdata
Queues an `appdata_restore` job (service class). The archive is fetched, decrypted and verified before anything is changed. Then the container is stopped if it is running, a snapshot of its current appdata is written to the enabled backup destinations, and only when that snapshot is written is the appdata replaced by the archive's content; if the snapshot cannot be written the live appdata is not touched. The container is started again afterwards. Requires `confirm: true`: the restore overwrites the container's appdata (400 `confirmation_required` otherwise). 404 `archive_not_found` for an archive the named destination does not hold, and 409 `array_stopped` while the array is stopped or its storage is not ready.
Preview restoring one container's appdata
Queues an `appdata_restore_preview` job (service class, scoped to the container) that reports what `restoreAppdata` would overwrite for the same archive on the same destination, before anything is changed. Read the result with `getAppdataRestorePreview` once the job has succeeded. The job fetches, decrypts and verifies the archive exactly as the restore does and fails with the restore's own error when the archive is corrupt, is another container's, names a directory outside the appdata location, or holds entries a restore could not unpack. It then compares each archived directory with the live one, walking the live appdata only for this job: files present in both are `replaced`, files only in the archive are `added`, and files only in the live appdata are `removed`, because the restore replaces each directory as a whole. It stops no container, writes nothing under the appdata location and leaves no fetched archive on disk, on success or failure. It queues behind a backup or restore of the same container and runs beside those of others. Cancelling it stops the fetch, the reading of the archive and the walk of the live directories; the decryption and the verification read that follow the fetch run to their end first. 404 `archive_not_found` for an archive the named destination does not hold, 404 `backup_destination_not_found`, 400 `appdata_archive_invalid` for a request that names no archive of this installation and container, and 409 `array_stopped` while the array is stopped or its storage is not ready.
Get a restore preview
The result of the `appdata_restore_preview` job `previewAppdataRestore` queued. The daemon holds the sixteen most recent results in memory, so a result is gone after a restart and after sixteen newer previews: preview again. 404 `job_not_found` for an id that is not a restore preview job, 409 `appdata_preview_not_ready` while the job is queued or running, 409 `appdata_preview_failed` when it failed, was cancelled or was interrupted (the message says why; `getJob` and `getJobLog` have the rest), and 404 `appdata_preview_gone` when the job succeeded but its result is no longer held.