backup: the panel's full backup works, without the queue

Found by the e2e restore scenario of the next commit: the Full backup
button answered 200 with ten bytes. The archive includes the Postfix
queue, Postfix keeps every queue file and directory readable by its own
user alone (not configurable), and the panel runs as its own user - the
walk stopped at /data/postfix/queue/active with "permission denied"
after the headers were out. So since the queue moved under /data in
1.3.0. Confirmed on the test server: selfpost-backup as root makes the
whole archive, the same command as user panel fails the same way.

Owner, 2026-10-11: the panel's archive comes without the queue.

- backup.Params.Unprivileged: the queue is left out, and so is a file
  under certs/ that cannot be opened (the private key on the test
  server is root and Postfix's group only), named through OnWarn. The
  selfpost-backup command leaves it unset and takes both, as before.
- backup.Check reads through everything Create would archive, writing
  nothing. The panel runs it before the first byte: a failure is a
  message on the page, not a download cut short.
- The box, Help (design commit before this one) and the guide say what
  the panel's archive leaves out; the guide's comparison table has rows
  for the queue and the private key, and tells to put the key back
  before starting a restored instance.

  go vet ./internal/backup/ ./internal/web/handlers/: ok
  go test ./internal/backup/ ./cmd/... ./internal/web/...: ok
  make e2e on the test server, with the restore scenario: ok

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-11 19:55:18 +03:00
co-authored by Claude Opus 5.5
parent 646ec1e149
commit 8c9a71e6a0
6 changed files with 184 additions and 20 deletions
+15 -2
View File
@@ -556,12 +556,23 @@ instance keeps running, what goes into the archive, and what happens on restore.
**1. Panel — while the container is running (no downtime).** *Server › Backup*
→ *Full backup*. *Encrypt with a password* is ticked; untick it for a plain
archive. Same archive as the CLI below.
archive. The archive of the CLI below, less two things the panel may not read:
it runs as its own user, not as root. **The Postfix queue** is left out —
Postfix keeps it readable by its own user alone — so mail that was waiting for
delivery at that moment is not in the archive; the restored instance starts
with an empty queue. **A file in `certs/` the panel cannot open** is left out
too, which is usually the private key (the panel's log names it); put the key
back into `certs/` before starting a restored instance. If anything else
cannot be read, the panel says so and downloads nothing.
**2. `selfpost-backup` CLI — while the container is running (no downtime).**
The panel button and this command call the same code path: a consistent SQLite
snapshot via `VACUUM INTO`, then a gzip tar of `data/` (minus diagnostics) plus
deploy files.
deploy files. `docker exec` runs the command as root, so this archive is the
complete one: it has the Postfix queue and everything in `certs/`. The queue is
copied while Postfix works on it, so a message on its way through may be in the
archive twice or not at all; stop the service first (method 3) if the queue
matters.
```sh
docker exec <container> selfpost-backup > selfpost-backup.tar.gz
@@ -616,6 +627,8 @@ methods avoid it by stopping first.
| Self-contained archive | Yes | Yes | No — deploy files separate |
| SQLite consistency | `VACUUM INTO` snapshot | Safe when stopped | Safe when stopped |
| `data/log/` | Excluded | Included (optional exclude) | Included (optional exclude) |
| Postfix queue | CLI: yes, copied live. Panel: no | Yes | Yes |
| `certs/` private key | CLI: yes. Panel: only if the panel may read it | Yes | No — deploy files separate |
| `data/manifest.json` | Written (version stamp) | Absent | Absent |
| Restore version check | Yes — must match image tag | No | No |
| Post-restore *Resync* | Yes, on first boot | No | No |