Tailscale and networking
Private networking for the self-hosted control plane, including Tailscale and access patterns.
Written By Zoro
Last updated 3 days ago
Two different Tailscale topics appear in dFlow.
This page covers the control plane container and network posture from docker-compose.yml. For connecting Worker Nodes through a tailnet, use the in-product server flow and Add a self-hosted server under Worker Nodes and Compute in the sidebar (and Compute and worker node issues under Troubleshooting in the sidebar if SSH or mesh access fails).
Control plane: why NET_ADMIN and /dev/net/tun
The payload-app service in the reference Compose file adds:
cap_add: NET_ADMINdevices: /dev/net/tun
That matches product features that interact with Tailscale-style networking from inside the container. If you remove these, tailnet automation in the app may break. Keep them unless your security team signs off on a reduced-capability profile and you accept limited functionality.
Environment variables (control plane)
Set on payload-app (see Environment configuration):
Create keys in the Tailscale admin console with least privilege and rotation policy your org requires. Store them in a secret manager; inject at deploy time.
Network layout with Compose
The sample stack uses a bridge network custom-tailnet. That name is a Docker network label, not your Tailscale tailnet. Services talk to each other by service name (mongodb, redis, traefik, etc.) on that bridge.
Ingress options
- Public HTTP/S on ports 80 and 443 via Traefik (typical).
- Tailscale subnet routing or MagicDNS so operators hit the dashboard without public exposure (you still terminate TLS appropriately for your threat model).
- A corporate reverse proxy in front of Traefik; preserve
Hostheaders and WebSocket settings your team relies on.
Document whichever pattern you choose so application teams know the URL they should use (NEXT_PUBLIC_WEBSITE_URL must match).
Firewall checklist
- Allow 80 / 443 from the internet if you use public ingress.
- Restrict MongoDB and Redis ports to the Docker bridge or localhost only (default Compose does not publish them; keep it that way).
- For Worker Nodes, open SSH from the control plane (public IP or tailnet IP depending on setup).