rhythmic-librarian-54602
02/19/2026, 4:25 AMtall-airline-16756
02/19/2026, 4:25 AM<http://domain.com|domain.com> with your actual domain and test from the host using curl before rolling out.
1) Preferred: reverse_proxy with handle_path (rewrites the path before proxying)
• This is simplest and clean: requests to /rtc/v1/... are forwarded to the backend as /rtc/...
• Example Caddyfile site block:
<http://domain.com|domain.com> {
# other global options...
@rtcV1 path /rtc/v1/*
handle @rtcV1 {
# handle_path removes the prefix /rtc/v1 so backend receives /rtc/...
handle_path {
rewrite * /rtc{path}
}
reverse_proxy localhost:7880
}
# other handlers / reverse_proxy rules...
}
• Behavior: Client requests to https://domain.com/rtc/v1/session become proxied to http://localhost:7880/rtc/session (the /v1 prefix removed). TLS and Host header remain intact by default.
2) Alternative: rewrite directive + reverse_proxy
• If you prefer an explicit rewrite followed by a single upstream proxy:
<http://domain.com|domain.com> {
@rtcV1 path /rtc/v1/*
rewrite @rtcV1 /rtc{path}
reverse_proxy localhost:7880
}
• Behavior: The rewrite changes the request path on Caddy before the request reaches reverse_proxy. This is simpler when most traffic goes to the same backend.
Extra notes and tips
• If you need to preserve the original Host header or set a specific Host header for the backend, add header adjustments:
reverse_proxy localhost:7880 {
header_up Host {http.request.host}
}
• If some clients use /rtc/ already, ensure your rules don’t conflict: place the /rtc/v1 rule before generic /rtc rules.
• Test locally with curl using --resolve to hit your Caddy instance and see the forwarded path:
◦ Example:
curl -v -H "Host: domain.com" "https://domain.com/rtc/v1/validate" --resolve domain.com:443:127.0.0.1
If you want, paste your full current Caddy site block (redact secrets) and I’ll return a ready-to-drop-in snippet matching your existing config style.rhythmic-librarian-54602
02/19/2026, 4:29 AMlogging:
logs:
default:
level: INFO
storage:
"module": "file_system"
"root": "/data"
apps:
tls:
certificates:
load_files:
- certificate: /certs/fullchain.pem
key: /certs/wildcard.key
layer4:
servers:
main:
listen: [":443"]
routes:
- match:
- tls:
sni:
- "<http://livekit-turn.example.com|livekit-turn.example.com>"
handle:
- handler: tls
- handler: proxy
upstreams:
- dial: ["localhost:5349"]
- match:
- tls:
sni:
- "<http://livekit.example.com|livekit.example.com>"
handle:
- handler: tls
connection_policies:
- alpn: ["http/1.1"]
- handler: proxy
upstreams:
- dial: ["localhost:7880"]
- match:
- tls:
sni:
- "<http://livekit-whip.example.com|livekit-whip.example.com>"
handle:
- handler: tls
connection_policies:
- alpn: ["http/1.1"]
- handler: proxy
upstreams:
- dial: ["localhost:8080"]tall-airline-16756
02/19/2026, 4:29 AM- match:
- tls:
sni:
- "<http://livekit.example.com|livekit.example.com>"
handle:
- handler: tls
connection_policies:
- alpn: ["http/1.1"]
- handler: route
routes:
- match:
- header:
Host:
- "<http://livekit.example.com|livekit.example.com>"
path:
- /rtc/v1/*
handle:
- handler: rewrite
uri: /rtc{http.request.uri.path.1}
- handler: reverse_proxy
upstreams:
- dial: ["localhost:7880"]
- handle:
- handler: reverse_proxy
upstreams:
- dial: ["localhost:7880"]
Explanation of key pieces
• The matcher with path: /rtc/v1/* matches requests under that prefix.
• The rewrite handler uses uri: /rtc{http.request.uri.path.1} to remove the /rtc/v1 prefix and produce /rtc/....
◦ Example: request to /rtc/v1/validate -> rewritten to /rtc/validate.
• The reverse_proxy sends the rewritten request to localhost:7880.
• The final route without a match sends any other requests for the same SNI to the same upstream unchanged.
Notes and testing
• After updating the file, reload Caddy:
◦ If you run Caddy directly: caddy reload --config /path/to/caddy.yaml
◦ Or use your system/service manager to reload the service.
• Test with curl from the VM to ensure the path is rewritten as expected:
◦ curl -v -H "Host: livekit.example.com" "https://livekit.example.com/rtc/v1/validate" --resolve livekit.example.com:443:127.0.0.1
• If you prefer a single reverse_proxy that handles path prefix stripping (using handle_path) instead of rewrite, tell me and I’ll produce that variant.
If you want, paste your full updated caddy.yaml after you apply this and I’ll sanity-check it for indentation and any conflicts with the other SNI routes (turn / whip).rhythmic-librarian-54602
02/19/2026, 4:37 AMlogging:
logs:
default:
level: INFO
storage:
"module": "file_system"
"root": "/data"
apps:
tls:
certificates:
load_files:
- certificate: /certs/fullchain.pem
key: /certs/wildcard.key
layer4:
servers:
main:
listen: [":443"]
routes:
- match:
- tls:
sni:
- "livekit-turn.example.com"
handle:
- handler: tls
- handler: proxy
upstreams:
- dial: ["localhost:5349"]
- match:
- header:
Host:
- "livekit.example.com"
path:
- /rtc/v1/*
handle:
- handler: rewrite
uri: /rtc{http.request.uri.path.1}
- handler: reverse_proxy
upstreams:
- dial: ["localhost:7880"]
- handle:
- handler: reverse_proxy
upstreams:
- dial: ["localhost:7880"]
- match:
- tls:
sni:
- "livekit-whip.example.com"
handle:
- handler: tls
connection_policies:
- alpn: ["http/1.1"]
- handler: proxy
upstreams:
- dial: ["localhost:8080"]tall-airline-16756
02/19/2026, 4:38 AMrhythmic-librarian-54602
02/19/2026, 4:40 AMlogging:
logs:
default:
level: INFO
storage:
"module": "file_system"
"root": "/data"
apps:
tls:
certificates:
load_files:
- certificate: /certs/fullchain.pem
key: /certs/wildcard.key
layer4:
servers:
main:
listen: [":443"]
routes:
- match:
- tls:
sni:
- "<http://livekit-turn.example.com|livekit-turn.example.com>"
handle:
- handler: tls
- handler: proxy
upstreams:
- dial: ["localhost:5349"]
- match:
- header:
Host:
- "<http://livekit.example.com|livekit.example.com>"
path:
- /rtc/v1/*
handle:
- handler: rewrite
uri: /rtc{http.request.uri.path.1}
- handler: reverse_proxy
upstreams:
- dial: ["localhost:7880"]
- handle:
- handler: reverse_proxy
upstreams:
- dial: ["localhost:7880"]
- match:
- tls:
sni:
- "<http://livekit-whip.example.com|livekit-whip.example.com>"
handle:
- handler: tls
connection_policies:
- alpn: ["http/1.1"]
- handler: proxy
upstreams:
- dial: ["localhost:8080"]