# translate.watersmedia.org — local DNS and reverse proxy Puts the Church Translate congregation page on a church hostname inside the Apollo Beach and North Attleboro networks. LAN only, plain HTTP, no WAN access. The app's own requirements are in [PUBLIC-ACCESS.md](../../PUBLIC-ACCESS.md). This was done on 2026-10-15 against app 3.23.2 build 121. | What | Value | | --- | --- | | App host | Translate Mac, North Attleboro LAN `10.1.7.39` | | App port | TCP 3100, plain HTTP + WebSocket on `/ws` (the only port to expose) | | Reverse proxy | Boba-Fett (Synology DSM 7.0.1), `10.1.1.4`, `ssh boba-fett` (port 202, user Michael) | | Hostname | `translate.watersmedia.org` | | Local DNS | A record on the AB and NA UDM Pro consoles → `10.1.1.4`, TTL 300 | | HTTPS | no certificate; `https://translate.watersmedia.org` answers 301 to `http://` | `curl -s http://10.1.7.39:3100/healthz` should return `{"ok":true,"live":true,...}` before anything below is tested. ## 1. Local DNS on UniFi (AB and NA) — done 2026-10-15 Each console has its own Network API key saved as `~/.config/unifi/-network-api-key` (created in Settings → Control Plane → Integrations → Create API Key; all five sites are saved on Michael's Mac). The record was created with: ```bash python3 docs/examples/waters-church-na/unifi-dns-record.py translate.watersmedia.org 10.1.1.4 --sites apollo-beach,north-attleboro ``` Resulting policy ids: AB `379f868d-a956-4ec1-acef-13557153ff3f`, NA `16bf7109-ec68-41f9-9c16-fa6a62471430`. Both gateways answer `10.1.1.4`. `--list` shows every DNS policy per console; `--dry-run` previews. Why Boba-Fett and not the Mac: the proxy owns the hostname so the port never appears in the URL, and AB clients reach `10.1.1.4` over the site-to-site link exactly as they already do for `chronicles-na.waterschurch.org`. ## 2. Reverse proxy on Boba-Fett — done 2026-10-15 [boba-fett-translate-proxy.sh](boba-fett-translate-proxy.sh) does the whole job and is idempotent. It was run on 2026-10-15; afterwards `/healthz`, `/api/languages`, the `/ws` upgrade (101) and the HTTPS 301 all checked out from both the AB and NA LANs, and `/operator` returned 404 as designed. A copy lives at `~/translate-proxy.sh` on Boba-Fett (Michael's home). DSM's reverse-proxy API and nginx reload both need root, and sudo there asks for Michael's password, so run it interactively: ```bash ssh -t boba-fett sudo bash translate-proxy.sh ``` What it creates: | Piece | Where | Content | | --- | --- | --- | | DSM reverse proxy rule | Control Panel → Login Portal → Advanced → Reverse Proxy, "translate.watersmedia.org" | HTTP `translate.watersmedia.org:80` → HTTP `10.1.7.39:3100`; custom headers `Upgrade: $http_upgrade`, `Connection: $connection_upgrade` (WebSocket), `X-Forwarded-Host: $http_host`; read timeout 3600 s; HTTP/1.1 | | HTTPS redirect | `/usr/local/etc/nginx/sites-enabled/translate-redirect.conf` | `server { listen 443 ssl; server_name translate.watersmedia.org; return 301 http://translate.watersmedia.org$request_uri; }` | DSM already sends `Host`, `X-Real-IP`, `X-Forwarded-For` and `X-Forwarded-Proto` on every rule. The whole host lands on `/`, which the app requires. `/operator` returning 404 through the proxy is intended; staff use `http://10.1.7.39:3100/operator` on the LAN. To undo: delete the rule in the DSM Reverse Proxy list, remove the redirect file, and `sudo synosystemctl reload nginx`. Known limits: - The HTTPS redirect only runs after a TLS handshake with Boba-Fett's default certificate, so a browser shows a certificate warning first. A trusted certificate for this name would need DNS-01 validation against the watersmedia.org zone (cPanel), which is not set up. - DSM's reverse proxy cannot turn `proxy_buffering` off. HLS segments under `/live/` are small discrete files and the WebSocket is a tunnel after upgrade, so the effect is minor; if audio lag is reported, that is the first thing to revisit with a hand-written nginx include. ## 3. After the proxy answers 1. On the NA LAN open `http://10.1.7.39:3100/operator`, enter the operator PIN, and set **Public address** to `http://translate.watersmedia.org` (no trailing slash). Otherwise the QR code and poster keep advertising `10.1.7.39:3100`. 2. Verify from a machine at AB and one at NA: ```bash curl -s http://translate.watersmedia.org/healthz ``` It must return the same JSON as the direct `10.1.7.39:3100` check. 3. Open the page on a phone on guest wifi and confirm captions appear (WebSocket) and spoken audio plays (`/live/`). If phones cannot connect at all, look at client isolation on the guest network and the guest → `10.1.1.4` firewall rule before anything else.