Features05 Backups

A backup only counts if it comes back.

Back up a volume by hand or on a schedule, at a fixed time and on the machine it belongs to. Every backup is compressed, read back after writing, and checked again before it restores. Encrypt it with your own password, send it to an SFTP server, an S3 bucket or WebDAV, and let Postgres, MySQL/MariaDB or MongoDB make their own dump.

Screenshot: The automatic backup of shop_pgdata: a dump of the database in shop-db-1, every day at 03:00, to a Backblaze B2 bucket, encrypted, keeping fourteen.

Fig. — A nightly dump of a Postgres database to Backblaze B2, encrypted.

Would your backup come back?Read the comic: crates packed tight and checked, a padlock of your own, and a van that leaves the building →

What you can do

Checked after writing

A volume becomes a .tar.zst with a small .json beside it: the volume, the machine, the size and a sha256. The app reads the whole file back before it counts; a half-written one goes away.

At a fixed time

Every day or every week, at 03:00 or whenever you pick, so it does not drift. A new schedule makes its first backup straight away, and Back up now makes one in between.

On its own machine

A schedule runs on the machine where you made it, also while the app shows another one. The same volume on two machines gets two schedules, and their backups never clear each other out.

Keep the newest

Keep 1 to 100 per schedule; the oldest go, with their .json. And the checkup lists every volume in use without a schedule as “Never backed up”.

When the volume is busy

Skip and try again every hour, or pause its containers for a few seconds. Three skips in a row and you get a notification, so backups never stop quietly.

Encrypted with your password

With age and one password for the whole app, at least twelve characters, kept in the encrypted store of your system. Without it a backup cannot come back, so the app says to keep it somewhere else too.

Off this computer

An SFTP server, an S3 bucket (AWS, Backblaze B2, Wasabi, MinIO) or WebDAV (Nextcloud, a NAS). Written and checked here first, then uploaded; the copy here goes away.

A server you confirmed

SFTP shows the fingerprint of the server and only logs in once you trust it. If the server has another key later, the app stops before logging in, and nothing goes out.

A dump of the database

For Postgres, MySQL/MariaDB and MongoDB: consistent without pausing, with the user and password the container already has. The app never sees them.

Commands before and after

The labels of offen/docker-volume-backup work: archive-pre before the pause, archive-post once the containers run again. If archive-pre fails, there is no backup.

Checked before it restores

The whole file, its sha256, the password and what is in it, before anything stops or changes. A typo in the password costs nothing.

Three ways back

Merge into the volume, empty it first so it holds exactly the backup, or restore into a new volume to look first. Before overwriting, a backup of what is there now.

Databases

The database makes its own backup.

Copying the files of a database while it writes can give a backup it cannot read itself. For Postgres, MySQL/MariaDB and MongoDB a schedule can ask the database for a dump instead, with pg_dumpall, mysqldump or mariadb-dump, or mongodump. That is consistent without pausing, and it runs with the user and password the container already has, so the app never sees them. The dump goes into the same archive as any backup: checked after writing, encrypted with your password if you like, and uploaded like the rest. Restoring goes back through the running database, after a dump of what is there now; Postgres closes the other connections first, and errors the database reports while it carries on end up in the notification.

Screenshot: Restoring shop_pgdata: four nightly dumps, encrypted, that go back through the database in shop-db-1, after a dump of what is in it now.
Fig. — A dump goes back through the running database, after a dump of what is there now.

Off this computer

A backup on the same disk goes when the disk goes.

So a schedule can send its backups elsewhere: an SFTP server, an S3 bucket or WebDAV, with the password or key in the encrypted store of your system. Each backup is written and checked here first, then uploaded so that a half upload never looks like a backup, and the containers are already running again by then. The app remembers what it uploaded, with its sha256: a file on the server it did not put there is marked “not from the app” and never picked for you, and one that was replaced does not restore. Plain http only goes to your own network, and then only encrypted.

Screenshot: Settings, Servers: an SFTP server, a Backblaze B2 bucket and Nextcloud as backup destinations, the backup password, and two automatic backups that go to them.
Fig. — Three destinations, one password, and two schedules that leave the computer.

Encryption

Your password, and nobody else’s.

An encrypted backup is a .tar.zst.age: tar, compressed with zstd, encrypted with age. Open formats all the way down. The app keeps one password, never shows it again, and refuses to fall back to an unencrypted backup when it cannot read it. A wrong password shows at the first bytes of the file, before anything reaches the volume. Change the password and older backups keep the old one: restoring one asks for it once, and forgets it when the dialog closes.

Screenshot: Restoring shop_uploads after the password changed: the app asks for the password the backup was made with, before anything stops.
Fig. — An older backup asks for its own password; nothing has stopped yet.

Restore

Checked first, then put back.

Restore reads the whole backup before it touches anything: to the very end, against the sha256 in its .json, with your password, and only files under data/. A backup without its .json, from a USB stick say, still has to end the way a tar ends. Only then does the app make a backup of what is there now (the newest three per volume, encrypted if you have a password), stop the containers that use the volume, and start them again afterwards. Merge, clean, or into a new volume next to the old one: that volume gets a label of its own, so if anything fails, only the volume the app made goes away.

Screenshot: Restoring shop_uploads: four nightly backups, merge, clean or a new volume, a backup of what is there first, and shop-web-1 stopped while it works.
Fig. — Merge, clean, or a new volume next to the old one, with a backup of what is there first.

All features

Try it on your own daemon.
Free and open source. Windows installer, Linux AppImage, or npx on any platform.
Download for Windows
$ npx docker-client-mx