diff --git a/services/control-plane/docker-compose.yml b/services/control-plane/docker-compose.yml index 446507d..0cde0ea 100644 --- a/services/control-plane/docker-compose.yml +++ b/services/control-plane/docker-compose.yml @@ -5,7 +5,18 @@ services: user: "1000:1000" command: python src/operator_ui.py ports: - - "18180:8080" + # Loopback: node-agent on the VPS runs with network_mode: host and probes + # localhost:18180/summary directly (_check_control_plane_health in + # node_agent.py). Tailscale IP: runtime-materializer@PIHA and other mesh + # consumers reach this as http://100.95.58.48:18180. No 0.0.0.0 — this + # host previously had NO 0.0.0.0 exemption and /action/mutate has no auth, + # so a public bind lets anyone on the internet approve remediation + # actions. Same dual-bind pattern as services/ollama/docker-compose.yml. + # Requires .env (from env.example) next to this file at deploy — see + # services/fleet-prometheus/README.md for the "missing .env silently + # binds 0.0.0.0" gotcha that also applies here. + - "127.0.0.1:18180:8080" + - "${TAILSCALE_BIND_IP}:18180:8080" volumes: - /opt/homelab:/opt/homelab restart: unless-stopped diff --git a/services/control-plane/env.example b/services/control-plane/env.example new file mode 100644 index 0000000..53fe9c3 --- /dev/null +++ b/services/control-plane/env.example @@ -0,0 +1,13 @@ +# Copy to .env next to docker-compose.yml (gitignored); docker compose picks +# it up automatically. Same convention as services/fleet-prometheus, +# services/llm-gateway, services/gokapi, services/ollama. + +# Tailscale IP of the VPS node. The operator-ui port (18180) is published as +# ${TAILSCALE_BIND_IP}:18180:8080 so the mesh-facing bind is never 0.0.0.0. +# Verify when rebuilding the host: tailscale ip -4. +# +# WARNING (same footgun as fleet-prometheus, see its README): if .env is +# missing at deploy time, Compose resolves this to an empty string and +# SILENTLY binds to 0.0.0.0 instead of failing — always confirm with +# `docker compose config | grep host_ip` before `up -d`. +TAILSCALE_BIND_IP=100.95.58.48