# Sando deploy units systemd units and scripts that run on the Sando host (fw13) and on deploy targets. Host-specific secrets, certs, and tailnet IPs are **not** here — they live in the Syncthing private layer (`_private/infra/`, `_private/deploy`). ## Files | File | Where it runs | Purpose | |------|---------------|---------| | `sandod.service` | Sando host | The Sando daemon (`sandod`). | | `bootstrap-sandod-host.sh` | Sando host | One-time host setup for the daemon. | | `bootstrap-node.sh` | a deploy target | One-time node setup (release dirs, deploy user, service). | | `sando-daemon.toml.example` | Sando host | Template for the daemon config (`sando.toml`). | | `post-receive` | git remote | Push-to-deploy hook. | | `sandod-backup-fetch.{service,timer}` | Sando host | Daily pull of the prod backup to `/srv/sando/backups/latest.sql.gz` (04:00 UTC). | | `mnw-testnot-refresh.{sh,service,timer}` | Sando host | Daily refresh of the testnot.work staging mirror (05:00 UTC). | ## testnot.work staging mirror testnot is a read-only mirror of production, gated app-side to Fan+/creator accounts (`ACCESS_GATE=fan_plus_or_creator`). It exists so creators and Fan+ members can preview upcoming features, and to back the pre-cutover migration dry-run. **Daily refresh** (`mnw-testnot-refresh.timer` → `.service` → `.sh`): reloads testnot's database from the backup `sandod-backup-fetch` already pulls, so the mirror tracks live. The script stops the app, resets the schema (recreating `public` owned by the app role — PG15+ otherwise blocks the app role's boot migrations), restores the dump as the postgres superuser over Tailscale SSH, and restarts the app, which applies any newer migrations on boot. Writes between refreshes are non-durable by design. Install on the Sando host: ```sh sudo install -m 0755 mnw-testnot-refresh.sh /usr/local/bin/mnw-testnot-refresh.sh sudo install -m 0644 mnw-testnot-refresh.service /etc/systemd/system/ sudo install -m 0644 mnw-testnot-refresh.timer /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now mnw-testnot-refresh.timer ``` Run a refresh manually: `sudo /usr/local/bin/mnw-testnot-refresh.sh` **Redeploy the binary** (no Sando integration yet — manual): build the release on the Sando host, then over Tailscale SSH as root on the target, copy the current release dir to a new one, stream the new `makenotwork` binary in, stream a tar of `static/` + `docs/` (`docs/` = `server/site-docs/{public,examples}` + `server/docs/business/assumptions.toml`, mirroring `server/deploy/deploy.sh`), flip the `current` symlink, and `systemctl restart makenotwork.service` (which boot-migrates). Old release dirs are kept for rollback. Cert, the makenotwork Postgres password, the Caddyfile, and the operator runbook for the root-level node setup are in `_private/infra/testnot/`.