kroskinski.com (~$)
jerry@homelab:~/docs

jerry@homelab:~/docs$ cat multi-host.md

Managing Four Hosts From One Dashboard

The homelab spans four hosts -- two Intel NUCs on the home LAN, and two Oracle Cloud VMs -- and Dockhand gives one dashboard view across all of them, without opening a single new inbound port anywhere.

Outbound Agents, Not Inbound Access

Dockhand itself runs centrally on the main server. Every other host -- both Oracle VMs and the secondary NUC -- connects to it via Hawser, a lightweight agent that opens an outbound WebSocket connection from the remote host to Dockhand, rather than Dockhand reaching in. Same principle the public website's own deploy process uses (an outbound git pull over Tailscale, never an inbound connection) -- nothing new gets exposed just to make monitoring possible.

A port-usage tracker follows the identical "deploy everywhere" pattern -- running on all four hosts, so every one of them has conflict visibility, not just the two that happen to run the most services. Only the main server's instance sits behind a real subdomain; the rest are reached directly over Tailscale, the same way most other internal-only tooling in this project works.

Gotcha: Hawser's WebSocket handshake got auth-gated by accident. Same root cause as the headless-client problem described on the SSO page -- the general two-factor policy on Dockhand's domain intercepted the agent's connection attempt and redirected it to a login page, which surfaced client-side as a generic websocket: bad handshake rather than anything obviously auth-related. Fixed with the same kind of narrowly-scoped bypass rule, ordered above the general policy.

A Known Limitation, Not a Config Mistake

Dockhand's "Adopt existing stack" feature -- which lets it take over managing a compose file it didn't create -- doesn't work for Hawser-connected remote hosts. Its file browser always shows the local server's own filesystem, never the remote node's, because Hawser currently only proxies Docker API calls, not filesystem access. The practical effect: every remote host's containers are fully visible and manageable through the dashboard -- logs, resource metrics, start/stop -- but their compose stacks can't be formally adopted the way local ones can.

Workarounds exist (a git-based stack pointed at a repo containing the compose file, or mounting the remote filesystem into the Dockhand container itself) but were deliberately not pursued -- the remote hosts' stacks are simple and rarely change, so visibility without formal adoption was judged good enough for now. Worth revisiting if that changes.

jerry@homelab:~/docs$

cd ..