# Tailscale exit-node LAN proxy LAN HTTP proxy that egresses through the dedicated Hetzner Tailscale exit node, so proxied clients appear on the internet as `89.167.72.79` without routing the docker host itself through the tunnel. - client endpoint: `192.168.0.35:3128/tcp` (HTTP/HTTPS forward proxy); - `tinyproxy` accepts LAN clients (`Allow 192.168.0.0/22`) and forwards upstream over SOCKS5 to the Tailscale container; - `ts-proxy` runs Tailscale in **userspace** mode and sends outbound traffic through the exit node `fedora-technohim` (`100.121.234.85`); - userspace mode adds **no host route/firewall changes** — the docker host's own services (NPM, KMS, IPsec) keep egressing via the normal gateway; - tinyproxy's access log ships to the logging stack (Alloy → Loki) via the syslog log-driver (`tag: tailscale-proxy`); the Grafana dashboard `logging/grafana-dashboards/tailscale-proxy.json` visualises it. The stack deliberately keeps credential-bearing / stateful files outside Git: | Host path | Purpose | Required mode | |---|---|---| | `/mnt/containers/tailscale-proxy/ts.env` | `TS_AUTHKEY=` | `0600`, owner `root:root` | | `/mnt/containers/tailscale-proxy/state/` | Tailscale node state (persists identity across restarts) | dir, owner `root:root` | | `/mnt/containers/tailscale-proxy/tinyproxy.conf` | tinyproxy config (also tracked in this directory as the source of truth) | `0644` | Before deploying: create `ts.env` on the host with a Tailscale auth key, and in the Tailscale admin console approve the exit node and allow this node to use it. Deploy this directory as a Portainer Git stack named `tailscale-proxy`, or run it with Docker Compose using project name `tailscale-proxy`. The absolute configuration files must already exist on the host before deployment. Full build record and rationale (userspace vs TUN dead-ends, SOCKS5-vs-HTTP, monitoring) is in ops-knowledge: `diagnostics/2026-07-23-02-tekhnohim-docker-tailscale-exit-proxy-stack.md`.