feat(backend): provision macsync runtime in cloud-init (rebuild-safe)

The backend droplet rebuild wiped the manually-deployed macsync server because
backend.yaml only installed pgbouncer. Install the macsync RUNTIME at boot
(unzip, redis, bun -> /root/.bun, caddy) + open ufw 80/443, so a rebuilt droplet
is ready for a one-command `macsync/deploy/deploy-server.sh`. RUNTIME ONLY — no
secrets, no app code (secrets are metadata-readable in user-data, so they are
pushed over SSH by the deploy script; the gpu.sh credential finding applied).

Note: backend.yaml is shared with the gpu droplet template (droplet.tf), so a
gpu rebuild also gets these idle packages — harmless. The DO cloud firewall
(network.tf) must also allow 80/443 for the edge to be reachable post-rebuild.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Natalie 2026-06-30 13:03:15 -04:00
parent 9a743ee11e
commit 3c4ffcc5e8

View file

@ -15,6 +15,8 @@ packages:
- git
- curl
- ufw
- unzip # bun installer needs it to unpack
- redis-server # macsync job/cache queue (REDIS_URL=redis://127.0.0.1:6379)
write_files:
# WireGuard wg1 - joins the existing mesh. Hub pubkey + the [Peer] block are
@ -41,15 +43,29 @@ runcmd:
- umask 077; wg genkey | tee /etc/wireguard/wg1.key | wg pubkey > /root/wg1.pub
- sed "s#__PRIVATE_KEY__#$(cat /etc/wireguard/wg1.key)#" /etc/wireguard/wg1.conf.tmpl > /etc/wireguard/wg1.conf
- chmod 600 /etc/wireguard/wg1.conf
# Host firewall mirrors the DO cloud firewall: WG + SSH only, deny the rest.
# Host firewall: WG + SSH for management, plus the public HTTPS edge (Caddy).
- ufw --force reset
- ufw default deny incoming
- ufw default allow outgoing
- ufw allow 22/tcp
- ufw allow ${wg_listen_port}/udp
- ufw allow 80/tcp # Caddy ACME http-01 + redirect
- ufw allow 443/tcp # macsync public TLS edge
- ufw --force enable
# wg1 is enabled but stays down until the hub [Peer] block is added.
- systemctl enable wg-quick@wg1 || true
- echo "WG public key for hub peer list:" && cat /root/wg1.pub
# --- macsync runtime (RUNTIME ONLY — no secrets, no app code). Secrets
# (DB pw, SERVICE_TOKEN, Spaces keys) are metadata-readable in user-data,
# so they are pushed separately over SSH by macsync/deploy/deploy-server.sh.
# This only makes a rebuilt droplet ready for a one-command deploy. ---
- mkdir -p /opt/mac-sync-server/data/blobs /etc/mac-sync-server
- systemctl enable --now redis-server || true
# bun runtime -> /root/.bun (matches ExecStart=/root/.bun/bin/bun in the unit).
- test -x /root/.bun/bin/bun || (export BUN_INSTALL=/root/.bun; curl -fsSL https://bun.sh/install | bash)
# caddy from the cloudsmith stable repo (not in default apt repos).
- curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
- curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
- apt-get update -qq && apt-get install -y caddy
final_message: "backend bootstrap done. Add /root/wg1.pub to vps-0 hub, append the [Peer] block to /etc/wireguard/wg1.conf, then: systemctl start wg-quick@wg1"