1
Admin – Back Up and Restore
Dmitrii Iurco edited this page 2026-06-11 15:39:28 -04:00

Status: Active | Owner: @roof | Applies to: main (2026-06) | Updated: 2026-06-11

Admin – Back Up and Restore


What is included in a backup

A make backup archive contains:

  • config/ — all service configuration, including cell_config.json
  • data/ — secrets and state (WireGuard keys, internal CA, vault keys, admin credentials, DDNS token, peer data, cell links, connectivity configs), excluding logs and internal config-backup snapshots
  • docker-compose.yml and Makefile

The archive is written with permissions 0600. It contains key material. Store it somewhere safe — anyone with the archive and enough time can recover your credentials.

The API-driven backup captures everything above, and additionally:

  • .env
  • Caddyfile and Corefile (runtime-generated)
  • DNS zone files
  • Vault directory (CA, certificates, trust store)
  • Per-peer service credentials
  • Caddy ACME certificates and ACME state
  • Live service data volumes (email mailboxes, calendar collections, file trees, streamed via docker exec tar)

Running a backup

Via make (quick archive)

# Run on: the cell server host, from /opt/pic
make backup

Creates backups/cell-backup-<timestamp>.tar.gz. Does not include live service data volumes.

Via API (full backup with service data)

POST /api/config/backup

To encrypt the archive with a passphrase:

POST /api/config/backup
Content-Type: application/json

{"passphrase": "<your-passphrase>"}

The encrypted file is named <backup_id>.tar.gz.age. The plaintext staging directory is removed immediately after encryption. The archive uses Fernet encryption with an scrypt-derived key.

Both the unencrypted and encrypted archive files are written with permissions 0600.


Restoring from a backup

From a make backup archive

# Run on: the cell server host, from /opt/pic
tar -xzf backups/cell-backup-YYYYMMDD-HHMMSS.tar.gz
make restart

After restart, the API regenerates the Caddyfile and Corefile from the restored config and re-applies routing rules.

From an API backup

POST /api/config/restore/<backup_id>

For an encrypted archive:

POST /api/config/restore/<backup_id>
Content-Type: application/json

{"passphrase": "<your-passphrase>"}

The restore process:

  1. Restores the vault first (the vault key must be present before any encrypted secrets can be read)
  2. Restores identity, .env, WireGuard keys, cell links
  3. Restores Caddy ACME certs, Caddyfile, Corefile, DNS zones
  4. Restores connectivity configs, auth users, DDNS token
  5. Restores service account credential files
  6. Reloads cell_config.json into memory
  7. Restores live service data volumes (if service containers are running)
  8. Regenerates Caddyfile and Corefile from restored config and re-applies routing rules

After an API restore, run make restart to ensure all containers pick up the restored configuration.


Backup schedule

PIC does not run automated backups on a schedule. Set up a cron job or systemd timer to call make backup (or the API endpoint) regularly.

Example cron (runs nightly at 2 AM from the PIC directory):

0 2 * * * cd /opt/pic && make backup

Security reminder

A backup contains everything needed to fully reconstruct your cell — including your WireGuard private key, internal CA, and admin credentials. Treat backup files with the same care as a password manager export.

If you use passphrase encryption, store the passphrase separately from the backup file. If you lose the passphrase, the backup is unrecoverable.

Internals: see Dev – Architecture