Skip to content

Backup & Restore

dockmesh backs up stack volumes, bind-mounted paths, and optional database dumps to reusable backup targets. Every backup is encrypted with age, versioned, and subject to a retention policy.

Targets are reusable connection configs that backup jobs reference. Create them once under Backups → Targets:

TypeFieldsNotes
LocalDirectory pathOn the dockmesh server filesystem
SMB / NASHost + share + username + passwordSpecify the share path explicitly — no auto-discovery
SFTPHost + port + user + key or passwordUses OpenSSH-compatible key formats
WebDAVURL + user + passwordTested against Nextcloud, OwnCloud, Synology
S3Endpoint + bucket + region + access/secretWorks with AWS, MinIO, Backblaze B2, Wasabi

Every dialog has a Test connection button that establishes a live session and reports failures with the actual protocol error.

A job ties a target to a schedule. Open Backups → New job:

  1. Select stacks — pick one or more named stacks (or a volume / host-files source)
  2. Pick a target
  3. Schedule — visual cron builder (every 6h, daily at 02:00, weekly Sunday, etc.) or raw cron
  4. Pre/post hooks — pick a preset (PostgreSQL dump, MySQL dump, Redis BGSAVE) or write a custom shell command
  5. Retention — combine two independent caps: retention_count (keep last N runs) and retention_days (keep runs younger than N days). The actual deletion fires the latter of the two — set whichever is appropriate, or both for belt-and-braces
  6. Encryption — checkbox. When on, every archive is encrypted with the server-wide age key from DOCKMESH_SECRETS_KEY_PATH (the same key that protects stack .env files). There is no per-job passphrase — losing or rotating that one key affects every encrypted backup and every encrypted .env on the server, so back the key up alongside your DB. Export it from Settings → Encryption key.

For each selected stack:

  • compose.yaml and .env
  • All named volumes (streamed as tar)
  • Bind mounts (tar of the referenced host path)
  • Optional hook output — e.g. a pg_dump file placed next to the volume

Everything is combined into a single <stack>-<timestamp>.tar.age file, encrypted with the job’s passphrase.

Backups → Runs lists every successful run grouped by job. Click Restore on a run and dockmesh:

  1. Reads the archive from the backup target
  2. Decrypts it with the server’s age key (if the run was encrypted)
  3. Stops the target stack (if running)
  4. Extracts compose.yaml, .env, and named-volume contents in place — the old volume contents are overwritten without a safety copy, so pair high-risk restores with a fresh backup of the current state first
  5. Restarts the stack

You can restore into a different stack name (target_stack parameter on POST /backups/runs/{id}/restore-stack) to spin up a clone. Restoring to a different host is not supported in a single click — restore locally first, then migrate the resulting stack.

Retention runs after every successful job. Two independent caps drive deletion:

  • retention_count — keep the most recent N runs; older ones are pruned
  • retention_days — keep runs younger than N days; older are pruned

Set either, both, or neither (neither = keep forever). The pruner deletes the archive from the target and writes an entry to the audit log. Grandfather-father-son rotation is not implemented today — the count/days combo covers most real-world retention policies on its own.