Documentation
Getting started.
Zacsync is a FastAPI backend with a React interface, packaged as a single container. It needs a data volume and, if your routers connect over tunnels, a WireGuard host.
Install
Docker
Run these commands from the repository root. The build uses the root as its context, and the /data bind mount is created next to it.
docker compose -f docker/docker-compose.yml up -d --build
docker compose -f docker/docker-compose.yml exec zacsync \
python -m zacsync.cli create-admin --username admin --password 'choose-one'
curl http://localhost:8080/api/health
From source
python -m venv .venv && .venv/bin/python -m pip install -e ".[dev]"
export ZACSYNC_DATA_DIR=/tmp/zacsync-dev
.venv/bin/python -m zacsync.cli create-admin --username admin --password admin
.venv/bin/python -m uvicorn zacsync.main:app --reload --port 8080
/ and the OpenAPI reference at /docs.
Secrets are generated into the data volume unless you supply your own.
First fleet
Enrolling a router
Configure the hub. Set the WireGuard hub's public key, address and endpoint, and the enrolment CA. Scripts can't be downloaded until all of these are set, and the error names whatever is missing.
Generate a site token and download that site's provisioning script.
Get the script to the router by email, a messaging app or any other way that reaches the site, then paste it into the terminal. It creates the tunnel interface, a management user and a firewall rule, then contacts the manager.
Approve it. The device appears as pending, showing the details it reported. Approving adds it to the WireGuard peer list; a service on the host applies the change and the tunnel comes up. Rejecting deletes the request.
Before your first change
How Change Guard works
Any job with a command that isn't a known read-only command sets up Change Guard on every targeted device: a backup, then a revert timer on the device, then your commands. If Zacsync can't open a new connection afterwards to confirm the router still responds, the router restores its backup and reboots.
This is what protects you from lockouts. It also means that if you deliberately take a device offline during a guarded job, it will be reverted. You can disarm guards you no longer need from the guards view.
Reference
Further documentation
Full documentation comes with the software. The README covers every part of
the system, and design documents, including the hosted beta terms, are in the
docs/ folder of the repository. Configuration uses environment variables
starting with ZACSYNC_; each default and the reason for it are documented in
config.py.
Operational notes are kept with the scripts they apply to. The hotspot guide covers common problems: set up a management port outside the hotspot bridge before you start; newer RouterOS device-mode can leave a hotspot inactive until someone presses the reset button on site; and a CDN wildcard in the walled garden gives everyone free internet access.