TZX MESH
Sign in

Backups and upgrades

The control plane is two Postgres databases and one directory of config. Back those up and you can rebuild the server anywhere.

What matters

ItemWhereContains
Config and secrets/opt/tzxmesh/app.env, owner.hash, compose file, Caddy and control-plane config
Control-plane databasePostgres tzxmeshdevices, keys, groups, policies, routes, activity
Identity databasePostgres tzxmesh_idplocal users, password hashes, signing keys, sessions
Data volumeserver_datageolocation databases; regenerated if lost
The encryption key in .env protects secrets inside the database. A database backup without the .env that goes with it cannot be decrypted.

Back up

cd /opt/tzxmesh/app
docker exec tzxmesh-postgres pg_dump -U tzxmesh -d tzxmesh -Fc > tzxmesh.dump
docker exec tzxmesh-postgres pg_dump -U tzxmesh -d tzxmesh_idp -Fc > tzxmesh_idp.dump
tar czf tzxmesh-config.tgz .env owner.hash docker-compose.yml Caddyfile config.yaml

Encrypt the three files before they leave the server, and copy them somewhere the server cannot reach. Run it nightly from cron.

Restore

  1. Run the installer on the new server with the same domain, then stop the stack: docker compose down.
  2. Unpack the config archive over /opt/tzxmesh/app.
  3. Start only Postgres, restore both dumps with pg_restore --no-owner into their databases, then docker compose up -d.
  4. Point DNS at the new server. Devices reconnect on their own; nothing needs re-enrolling.

Practise it once on a scratch machine. A restore you have never run is not a backup.

Upgrade

cd /opt/tzxmesh/app
docker compose pull
docker compose up -d

Database migrations run automatically on start. To pin a version, edit the image tags in .env before pulling. Rolling back is the same with the previous tag.