Reverse proxy into docker container sub-path

I’m inclined to think this issue lies with the upstream server.

I’ve tried to demonstrate Caddy’s behaviour here with a simple Caddyfile:

~/Projects/test
➜ caddy version
v2.1.1 h1:X9k1+ehZPYYrSqBvf/ocUgdLSRIuiNiMo7CvyGUQKeA=

~/Projects/test
➜ cat Caddyfile
http://:8081 {
  log
  respond "{uri}" 200
}

http://dashboard.example.com:8080 {
  rewrite * /dashboard{uri}
  reverse_proxy localhost:8081
}

http://api.example.com:8080 {
  rewrite * /api{uri}
  reverse_proxy localhost:8081
}

So we’re only getting 200 responses with a body containing the requested URI. Otherwise we’re replicating identical behaviour to your other sites. A good request is one where the URI is prefixed with the subdomain of the requested site. Giving it a quick shot:

~/Projects/test
➜ curl http://api.example.com:8080/stuff --resolve api.example.com:8080:127.0.0.1
/api/stuff⏎

2020/07/29 16:39:14.644	INFO	http.log.access	handled request	{"request": {"method": "GET", "uri": "/api/stuff", "proto": "HTTP/1.1", "remote_addr": "[::1]:53165", "host": "api.example.com:8080", "headers": {"User-Agent": ["curl/7.64.1"], "Accept": ["*/*"], "X-Forwarded-For": ["127.0.0.1"], "X-Forwarded-Proto": ["http"], "Accept-Encoding": ["gzip"]}}, "common_log": "::1 - - [30/Jul/2020:02:39:14 +1000] \"GET /api/stuff HTTP/1.1\" 200 10", "duration": 0.000052311, "size": 10, "status": 200, "resp_headers": {"Server": ["Caddy"], "Content-Type": []}}
~/Projects/test
➜ curl http://dashboard.example.com:8080/stuff --resolve dashboard.example.com:8080:127.0.0.1
/dashboard/stuff⏎

2020/07/29 16:39:18.317	INFO	http.log.access	handled request	{"request": {"method": "GET", "uri": "/dashboard/stuff", "proto": "HTTP/1.1", "remote_addr": "[::1]:53167", "host": "dashboard.example.com:8080", "headers": {"X-Forwarded-For": ["127.0.0.1"], "X-Forwarded-Proto": ["http"], "Accept-Encoding": ["gzip"], "User-Agent": ["curl/7.64.1"], "Accept": ["*/*"]}}, "common_log": "::1 - - [30/Jul/2020:02:39:18 +1000] \"GET /dashboard/stuff HTTP/1.1\" 200 16", "duration": 0.000037235, "size": 16, "status": 200, "resp_headers": {"Content-Type": [], "Server": ["Caddy"]}}

Everything is checking out, in terms of server behaviour. How the upstream is discriminating between the two is unclear to me. A client requesting /dashboard/foo to a site with no rewriting should result in an identical path to a client requesting /foo to a site that appends /dashboard, as shown above.

3 Likes