wiki-vault/Sources/Homelab/2026-06-07-tailscale-tsnet-dispatch-path-routing.md

2.7 KiB

created path project tags type
2026-06-07 Sources/Homelab traefik-deployment
tailscale
traefik
tls
dispatch
dns
session-notes

Addendum to 2026-06-07-tailscale-tsnet-traefik-access — extending remote tailnet access from the Traefik dashboard to actual services (petal-dispatch).

Outcome

petal-dispatch is now reachable remotely at https://traefik.taila7f44e.ts.net/dispatch/ (path-based, reusing the single .ts.net box cert). Same petal-dispatch service backend as the LAN dispatch.herbylab.dev route — just a second router.

Key Learnings

  • Tailscale issues certs only for actual node names. tailscale cert dispatch.taila7f44e.ts.net fails: invalid domain ...; must be one of ["traefik.taila7f44e.ts.net"]. Per-service .ts.net hostnames are not possible without a node per service. All remote services must therefore share the one box cert and be distinguished by path, not subdomain.
  • Path-based routing on the shared cert is the pattern. Add a router with Host(traefik.taila7f44e.ts.net) && PathPrefix(/) + a stripPrefix middleware, pointing at the existing service. No new cert, no new service block.
  • Duplicate top-level http: keys in one dynamic YAML file fail silently. Appending a second http: block (rather than nesting routers under the existing one) means the last block wins and the earlier routers vanish — no parse error. Everything must live under a single http: key. This briefly clobbered the dashboard router too.
  • Subpath asset caveat (open): path-based routing means the app runs under /dispatch, not root. If the web client builds asset URLs from /, the page loads but CSS/JS 404. Needs a base-href fix in the petal-dispatch web client.

Config landed

/opt/traefik/dynamic/tailscale.yml — single http: block, both routers + stripPrefix middleware:

http:
  routers:
    tailscale-dashboard:
      rule: "Host(`traefik.taila7f44e.ts.net`)"
      service: api@internal
      tls: {}
      entryPoints: [websecure]
    tailscale-dispatch:
      rule: "Host(`traefik.taila7f44e.ts.net`) && PathPrefix(`/dispatch`)"
      service: petal-dispatch
      middlewares: [dispatch-stripprefix]
      tls: {}
      entryPoints: [websecure]
  middlewares:
    dispatch-stripprefix:
      stripPrefix:
        prefixes: ["/dispatch"]

Follow-ons

  • Verify petal-dispatch renders correctly under /dispatch subpath — check browser console for asset 404s; set base-href in web client if needed.
  • Add path-based routers for any other services wanted remotely (same pattern, append router under the single http: block).
  • Carries forward from the parent note: static .ts.net cert renewal (no auto-renew), and the tailnet Global Nameserver decision.