Background
Tailscale is installed as a host-level service on the Ubuntu Server (Lenovo ThinkCentre, Tailscale IP in the 100.x.x.x range). It is configured with --ssh only — no subnet routing, no --advertise-routes.
Currently, remote access requires specifying ports directly (e.g. http://<tailscale-ip>:8096 for Jellyfin) because the *.woggles.work domains resolve to the LAN IP (192.168.0.243) and are not reachable outside the home network.
Goal
Enable *.woggles.work to resolve correctly when accessing the server remotely over Tailscale, so the same URLs work both on the home network and remotely.
How Tailscale MagicDNS works
Tailscale MagicDNS assigns each device a stable DNS name on the tailnet (e.g. thinkcentre.<tailnet>.ts.net). With split DNS configured, Tailscale can override resolution of specific domains for tailnet devices — so *.woggles.work can resolve to the Tailscale IP when accessed remotely, rather than the LAN IP.
This means Traefik continues to handle all routing (ports 80/443), and the existing *.woggles.work virtual hosts work without any changes to Traefik config.
Implementation notes
Current stack
docker-compose.yml — all services on a single proxy bridge network
- Traefik listens on ports 80 and 443 on the host, routes by hostname to containers
- Pi-hole runs with
network_mode: host and handles local DNS for *.woggles.work → 192.168.0.243
- Wildcard TLS cert issued via Cloudflare DNS-01 challenge (covers
*.woggles.work)
- No changes to
docker-compose.yml should be needed for this feature
Tailscale split DNS approach
- In the Tailscale admin console → DNS → enable MagicDNS
- Add a split DNS entry: nameserver for
woggles.work → the server's Tailscale IP (so tailnet devices use the server's Pi-hole to resolve *.woggles.work)
- Pi-hole already resolves
*.woggles.work → 192.168.0.243 (see pihole/etc-dnsmasq.d/02-local-dns.conf) — this needs to resolve to the Tailscale IP for remote clients, or a second resolution rule is needed
Alternative approach
Add a split DNS override directly in the Tailscale admin console (not via Pi-hole) pointing woggles.work → the server's Tailscale IP. This bypasses Pi-hole for remote clients but avoids modifying Pi-hole config.
TLS consideration
The wildcard cert (*.woggles.work) is already valid — Traefik will serve it regardless of which IP the client connected through. No cert changes needed.
Verification
- On a device outside the home network with Tailscale connected:
https://jellyfin.woggles.work loads Jellyfin
https://homepage.woggles.work loads the dashboard
- On the home network (Tailscale connected or not), existing URLs still work
Files to be aware of
docker-compose.yml — Traefik and service definitions
traefik/traefik.yml — static Traefik config
traefik/dynamic/ — TLS and service routing rules
pihole/etc-dnsmasq.d/02-local-dns.conf — local DNS overrides
docs/tailscale.md — Tailscale reference doc (update with new access instructions)
README.md — setup steps (step 9 covers Tailscale; may need updating)
Background
Tailscale is installed as a host-level service on the Ubuntu Server (Lenovo ThinkCentre, Tailscale IP in the 100.x.x.x range). It is configured with
--sshonly — no subnet routing, no--advertise-routes.Currently, remote access requires specifying ports directly (e.g.
http://<tailscale-ip>:8096for Jellyfin) because the*.woggles.workdomains resolve to the LAN IP (192.168.0.243) and are not reachable outside the home network.Goal
Enable
*.woggles.workto resolve correctly when accessing the server remotely over Tailscale, so the same URLs work both on the home network and remotely.How Tailscale MagicDNS works
Tailscale MagicDNS assigns each device a stable DNS name on the tailnet (e.g.
thinkcentre.<tailnet>.ts.net). With split DNS configured, Tailscale can override resolution of specific domains for tailnet devices — so*.woggles.workcan resolve to the Tailscale IP when accessed remotely, rather than the LAN IP.This means Traefik continues to handle all routing (ports 80/443), and the existing
*.woggles.workvirtual hosts work without any changes to Traefik config.Implementation notes
Current stack
docker-compose.yml— all services on a singleproxybridge networknetwork_mode: hostand handles local DNS for*.woggles.work→192.168.0.243*.woggles.work)docker-compose.ymlshould be needed for this featureTailscale split DNS approach
woggles.work→ the server's Tailscale IP (so tailnet devices use the server's Pi-hole to resolve*.woggles.work)*.woggles.work→192.168.0.243(seepihole/etc-dnsmasq.d/02-local-dns.conf) — this needs to resolve to the Tailscale IP for remote clients, or a second resolution rule is neededAlternative approach
Add a split DNS override directly in the Tailscale admin console (not via Pi-hole) pointing
woggles.work→ the server's Tailscale IP. This bypasses Pi-hole for remote clients but avoids modifying Pi-hole config.TLS consideration
The wildcard cert (
*.woggles.work) is already valid — Traefik will serve it regardless of which IP the client connected through. No cert changes needed.Verification
https://jellyfin.woggles.workloads Jellyfinhttps://homepage.woggles.workloads the dashboardFiles to be aware of
docker-compose.yml— Traefik and service definitionstraefik/traefik.yml— static Traefik configtraefik/dynamic/— TLS and service routing rulespihole/etc-dnsmasq.d/02-local-dns.conf— local DNS overridesdocs/tailscale.md— Tailscale reference doc (update with new access instructions)README.md— setup steps (step 9 covers Tailscale; may need updating)