|
| 1 | +# Mesh homeserver runbook |
| 2 | + |
| 3 | +This stack runs the managed Mesh Matrix service on the Mac mini: |
| 4 | + |
| 5 | +- Synapse for accounts, rooms, messages, encryption metadata, and federation; |
| 6 | +- PostgreSQL for durable state; |
| 7 | +- Caddy for public HTTPS and Matrix discovery after DNS/router activation. |
| 8 | + |
| 9 | +The permanent Matrix server name is `mesh.dhawal.org`. User IDs will look like |
| 10 | +`@name:mesh.dhawal.org`. |
| 11 | + |
| 12 | +## Local setup |
| 13 | + |
| 14 | +```sh |
| 15 | +cd mesh/infra/homeserver |
| 16 | +./setup.sh |
| 17 | +./start.sh |
| 18 | +./status.sh |
| 19 | +./backup.sh |
| 20 | +``` |
| 21 | + |
| 22 | +The local Synapse control port binds only to `127.0.0.1:8008`. Registration is |
| 23 | +closed by default. Create alpha accounts with `register_new_matrix_user` after |
| 24 | +the service is healthy. |
| 25 | + |
| 26 | +The initial operator account is `@dhawal:mesh.dhawal.org`. Its generated |
| 27 | +password is stored in macOS Keychain and can be retrieved locally with: |
| 28 | + |
| 29 | +```sh |
| 30 | +security find-generic-password \ |
| 31 | + -a '@dhawal:mesh.dhawal.org' \ |
| 32 | + -s 'Mesh Homeserver Admin' \ |
| 33 | + -w |
| 34 | +``` |
| 35 | + |
| 36 | +The installed `org.mesh.homeserver` user LaunchAgent opens Docker after login. |
| 37 | +Docker's `unless-stopped` policy then restarts the Mesh services. The |
| 38 | +`org.mesh.homeserver.backup` LaunchAgent makes a local backup daily at 3:15 AM |
| 39 | +under `~/Library/Application Support/Mesh/backups`. Copy those backups to a |
| 40 | +separate disk before treating the service as durable. The scheduled local |
| 41 | +copies are retained for 14 days. |
| 42 | + |
| 43 | +The `org.mesh.homeserver.ddns` LaunchAgent checks the public IPv4 address every |
| 44 | +five minutes and updates only the `mesh.dhawal.org` Cloudflare A record when it |
| 45 | +changes. Its restricted API token is stored in macOS Keychain under |
| 46 | +`Mesh Cloudflare DDNS API Token`. |
| 47 | + |
| 48 | +## Public activation |
| 49 | + |
| 50 | +Do not start the public profile until all of these are true: |
| 51 | + |
| 52 | +1. In Cloudflare DNS, add a DNS-only `A` record named `mesh` pointing to the |
| 53 | + home connection's public IPv4 address. |
| 54 | +2. Add a DNS-only `CNAME` named `matrix.mesh` targeting `mesh.dhawal.org`. |
| 55 | +3. Reserve the Mac's Ethernet address in the router, then forward TCP 80, |
| 56 | + TCP 443, and UDP 443 to it. |
| 57 | +4. Enable the macOS firewall and allow Docker's incoming listener. |
| 58 | +5. If the public IP is not static, configure a Cloudflare dynamic-DNS updater. |
| 59 | +6. Confirm that the local stack and a backup restore have passed validation. |
| 60 | + |
| 61 | +Then start the proxy: |
| 62 | + |
| 63 | +```sh |
| 64 | +sed -i '' 's/MESH_PUBLIC_ENABLED=0/MESH_PUBLIC_ENABLED=1/' .env |
| 65 | +./start.sh |
| 66 | +``` |
| 67 | + |
| 68 | +Verify from a device that is not on the home Wi-Fi: |
| 69 | + |
| 70 | +```sh |
| 71 | +curl https://mesh.dhawal.org/.well-known/matrix/client |
| 72 | +curl https://matrix.mesh.dhawal.org/_matrix/client/versions |
| 73 | +``` |
| 74 | + |
| 75 | +The MatrixRTC stack under `../matrixrtc` is activated separately after the |
| 76 | +homeserver is publicly healthy. |
| 77 | + |
| 78 | +## Critical data |
| 79 | + |
| 80 | +Never lose: |
| 81 | + |
| 82 | +- the PostgreSQL database; |
| 83 | +- `runtime/synapse/mesh.dhawal.org.signing.key`; |
| 84 | +- the local media store; |
| 85 | +- the untracked `.env` operator secrets. |
| 86 | + |
| 87 | +The server name and signing key identify the homeserver in federation. Backups |
| 88 | +must eventually be copied off this Mac and restore-tested. |
| 89 | + |
| 90 | +If operator secrets are exposed, rotate the PostgreSQL password and Synapse |
| 91 | +runtime secrets without changing the server name or signing key: |
| 92 | + |
| 93 | +```sh |
| 94 | +./rotate-runtime-secrets.sh |
| 95 | +``` |
0 commit comments