backup · restore · migrate · clustered

Back it up. Restore it. Move it to another node.

ProxDock is a clustered Docker orchestrator built on ZFS. Each application gets its own dataset and its own address, and is backed up as a send stream that restores image, configuration and data as one unit. Migration between nodes runs that same code, so the path you need in an emergency is the one that runs on an ordinary Tuesday.

  • ▪ backups are zfs send streams, checksummed and verified
  • ▪ migration reuses restore, so the recovery path never goes stale
  • ▪ one static binary; any node serves the whole cluster
you@proxdock1 · install
$ wget -qO- https://proxdock.whydoesnothing.work/install.sh | sudo sh
==> host prepared
    zfs-2.3.9-0+deb13u1 · Docker version 29.8.0 · Compose v5.5.1
==> installing proxdock 0.71.2 (release)

 proxdock installed and running.
   Web UI:            https://10.42.0.11:8443
   Initial password:  GdYW-EQHX-VX6k-Hx8H

# everything after this happens in the browser:
#   the setup wizard, then pick a template and deploy.

Backups that restore

Stop, snapshot, start, then zfs send from the snapshot, so ownership, xattrs, ACLs, sparseness and recordsize all survive, because none of them are being re-derived on the way out. Every stream is read back as it is written and checked record by record, every ZFS checksum, so a backup that would not restore fails on the night it was taken, not the day you need it.

Migration is the recovery path

Moving an application to another node is the same code as backup and restore. Bulk data pre-seeds while it is still running; the cutover is a stop, an incremental send and a start. The address moves with it, and because the MAC is derived from the address, the rest of the network learns nothing new. The old dataset is kept for rollback.

The cluster has no special node

Every node serves the whole UI and API. Reads come from the local replica, writes go through the Raft leader, and node-local work is proxied one hop over mTLS with the original user asserted for audit. Lose a majority and the cluster goes read-only and says so, rather than failing one write at a time.

The interface

Built for the day something breaks

Replica state, backup verification and node health are facts on the screen, not things you go digging for. The screens you need during an incident are the ones you already use on an ordinary day.

https://proxdock1.homelab.internal:8443/backups?tab=backups

Backups

6 scheduled jobs · 148 retained backups · 2.4 TB on tank/backups

Backups Jobs
Last night
6 / 6
all verified · 218 GB sent
Retention
148
7 daily · 4 weekly · 6 monthly
Target
2.4 TB
tank/backups · 61% used
Recent backups Back up now
applicationtakenkindsizestaterestore
immich 2026-09-05 03:00 full 184.2 GB verified Restore
paperless 2026-09-05 03:12 incremental 12.8 GB verified Restore
gitea 2026-09-05 03:18 incremental 4.1 GB verified Restore
jellyfin 2026-09-04 03:00 full 96.4 GB verified Restore
vaultwarden 2026-09-04 03:04 incremental 318 MB verified Restore
grafana 2026-09-03 03:00 full 1.9 GB stale Restore

Stop · snapshot · start · zfs send from the snapshot. Ownership, xattrs, ACLs, sparseness and recordsize survive; every stream is checksummed and carries a self-describing manifest.

Recovery

Every backup verified, nothing restored to do it

Each backup is read back and checked end to end as a ZFS stream, so verifying a 200 GB backup costs one read, not 200 GB of scratch space. Migration runs the restore path every time an application moves, and single files come out of a snapshot without a restore at all.

How it compares

The gap is the data, not the containers

Every tool here manages containers well. The difference is what happens to the data those containers spent a year generating: whether backing it up, proving the backup works and moving it to another host are things the tool does, or things left to you.

CapabilityProxDock Portainer CEDockge Komodo
Containers and Compose stacks from a browser✓ ✓ ✓ ✓
Several hosts from one interface✓ every node serves the whole API✓ agent per host✓ agent per host✓ agent per host
Application data backed up on a schedule✓ zfs send streams– open request since 2018– compose files only– its own database only
Backups proven by restoring them✓ on a schedule, into a throwaway clone– – –
Encrypted copies shipped offsite✓ s3, nas or another node– your own tooling– your own tooling– your own tooling
Move an application and its data to another host✓ one action, seconds of downtime– – • redeploys the stack; the data is yours to move
Control plane survives losing a node✓ replicated store, any node– one server– one server– one core
The detailed comparison every capability, in both directions
CapabilityProxDockPortainerCEDockgeKomodo
Backup and restore
Application data backed up on a schedule✓ – open request since 2018– compose files only– its own database only
Ownership, xattrs, ACLs and sparseness survive✓ a send stream, not a tarball– – –
Restore into a fresh dataset, keeping the previous one✓ a bad restore is a rollback– – –
Restore beside the original, under a new name✓ – – –
Encrypted on the way out✓ local copy stays readable– – –
Offsite to S3, a NAS or another node✓ – your own tooling– your own tooling– your own tooling
Backups proven by restoring them on a timer✓ into throwaway clones– – –
Pull one file out of a snapshot✓ no spare dataset needed– – –
Retention covers datasets left by deletes and migrations✓ – – –
Moving between hosts
Move an application and its data to another host✓ one action– – • redeploys the stack; the data is yours to move
Bulk data copies while the application still serves✓ the stop is an incremental send– – –
The address and MAC move with it✓ arp caches survive– – –
The source copy is kept for rollback✓ – – –
The cluster
Several hosts from one interface✓ ✓ ✓ ✓
Every node serves the whole API✓ no admin node– server and agents– server and agents– core and peripheries
Control plane survives losing a node✓ replicated store– – –
Lost quorum is stated, not inferred✓ read-only, and it says so– – –
Hosts reachable over the internet, behind NAT– a LAN cluster✓ edge agents– –
Deploying
Compose is the source of truth✓ ✓ ✓ ✓
Every transformation shown before anything is written✓ path, before, after, reason– – –
Template library✓ embedded, so always version-matched✓ app templates– –
Roll back to the snapshot taken before an update✓ – – –
Per-application automatic updates✓ on a schedule– – ✓ on a new digest
Build images from a Dockerfile– build: is refused✓ ✓ ✓
Deploy from a git repository– ✓ webhook or schedule– ✓
Whole configuration declared in version control– • per stack– ✓ toml resource syncs
Paste a docker run command, get compose back– – ✓ –
Addressing and certificates
Each application holds a real address on the LAN✓ macvlan zones– – –
Per-node HTTPS issued automatically✓ acme dns-01, nothing exposed– – –
Per-application certificates✓ own key each– – –
Per-application storage limit✓ refquota, rides a send– – –
Where it will run
Any filesystem– zfs, and that is the trade✓ ✓ ✓
Runs as a container on any Linux host– a package on the host✓ ✓ ✓
arm64– amd64 packages, arm64 planned✓ ✓ ✓
Kubernetes– ✓ – –
Docker Swarm– ✓ – –
Operating it
Container console and live logs in the browser✓ ✓ ✓ ✓
Users, teams and per-resource permissions✓ ✓ – ✓
Sign in with an external identity provider– local accounts only✓ by edition– ✓ oidc
Notifications when something fails– recorded, not sent– – ✓ telegram, ntfy, gotify, apprise
Scheduled multi-step automation– – – ✓ procedures and actions

Upstream open-source editions as of September 2026, checked against each project's own documentation and issue tracker. These are all very mature projects with rich feature sets. ProxDock is still in relatively early development.

Running now

It runs a real cluster, every day

The full lifecycle runs on a live three-node cluster: deploy, update, roll back, snapshot, back up, ship offsite, restore, migrate between nodes. One command puts it on a host.