mcp: session-notes — Tailscale .ts.net path-based routing — petal-dispatch over tailnet

This commit is contained in:
Lovebug MCP 2026-06-07 01:26:29 +00:00
parent 09745b33bd
commit d575bc5ba4

View File

@ -0,0 +1,54 @@
---
created: '2026-06-07'
path: Sources/Homelab
project: traefik-deployment
tags:
- tailscale
- traefik
- tls
- dispatch
- dns
type: 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(`/<svc>`)` + 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:
```yaml
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.