I want a caddy sub route for clients coming from /...
# ask-ai
r
I want a caddy sub route for clients coming from /rtc/v1/ to rewrite or reverse proxy to /rtc/
t
Thanks — I’m responding to your request to route client requests from /rtc/v1/* to /rtc/* in Caddy. Below are two safe options: a path rewrite (keeps URL shown to client) and a reverse-proxy with path translation. Pick the one that fits your use case. Notes before you apply • These snippets assume Caddy is terminating TLS and proxying HTTPS requests to your LiveKit backend at localhost:7880 (as you showed earlier). • Replace
<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:
Copy code
<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:
Copy code
<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:
Copy code
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.
r
I'm using a caddy.yaml in my livekit vm, help me update on this file:
Copy code
logging:
  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"]
t
Thanks — I’ll update your existing caddy.yaml to add a route that matches /rtc/v1/* and forwards it to the backend as /rtc/* (removing the /v1 prefix). I’ll preserve your current listeners and upstreams. Two safe approaches in caddy.yaml: • Rewrite before proxy (simple): Caddy rewrites the path then proxies to the same upstream. • handle_path-style (explicit path-handling): Uses a matcher and a route that rewrites the path before proxying. Below is a ready-to-drop-in patch for your provided caddy.yaml using the rewrite-then-proxy approach. It adds a route for the SNI that serves livekit.example.com and rewrites requests matching /rtc/v1/* to /rtc/* before reverse-proxying to localhost:7880. Replace your existing route for the livekit.example.com SNI with this block (keeps TLS + http/1.1 ALPN and the same upstream):
Copy code
- 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).
r
Yes, here is the full updated caddy.yaml file, do a sanity-check, rules check, indentation and make sure it is correct a valid :
Copy code
logging:
  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"]
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!
r
Yes, here is the full updated caddy.yaml file, do a sanity-check, rules check, indentation and make sure it is correct a valid :
Copy code
logging:
  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"]