Combining rewrite and reverse_proxy

1. Caddy version (caddy version):

v2.2.0 h1:sMUFqTbVIRlmA8NkFnNt9l7s0e+0gw+7GPIrhty905A=

2. How I run Caddy:

brew services start caddy

a. System environment:

Mac OS Catalina

b. Command:

brew services start caddy

c. Service/unit/compose file:

not applicable

d. My complete Caddyfile or JSON config:

test.local {
	@ifmatch {
		not {
			path /test/*
	rewrite @ifmatch /test{path}
	reverse_proxy localhost:80

localhost:80 {
	root /* /Users/daniel/Sites

3. The problem I’m having:

I have a site that was previously called through localhost/test (so thats also what the site thinks the urls look like). Basically it’s a subfolder in Sites. Now I wanted to add a proxy to prettify the calling domain to test.local.

My expectation:

  • I request https://test.local
  • Request comes in, on test.local
  • It is (internally - not visible to the user) rewritten to test.local/test
  • The request is then forwarded to localhost:80/test
  • The content will be shown to the user under test.local

What happens instead:

  • I receive a 308 redirect to test.local/test/

4. Error messages and/or full log output:

*   Trying ::1...
* Connected to test.local (::1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: [NONE]
*  start date: Oct  8 09:57:49 2020 GMT
*  expire date: Oct  8 21:57:49 2020 GMT
*  subjectAltName: host "test.local" matched cert's "test.local"
*  issuer: CN=Caddy Local Authority - ECC Intermediate
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fdf0a00d600)
> GET / HTTP/2
> Host: test.local
> User-Agent: curl/7.64.1
> Accept: */*
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 308 
< date: Thu, 08 Oct 2020 15:10:01 GMT
< location: https://test.local/test/
< server: Caddy
< server: Caddy
< content-length: 0
* Connection #0 to host test.local left intact
* Closing connection 0

5. What I already tried:

6. Links to relevant resources:

My conclusion after reading tons of posts: Using subfolders maybe just isn’t a good idea…

Your backend application will need to be configured to run in a subfolder:

Or you can perform replacements in response bodies (somewhat finicky). That linked wiki has more details.

(This is not a Caddy-specific problem; just something that affects all apps that are reverse-proxied. Many apps are poorly-designed.)

This topic was automatically closed after 30 days. New replies are no longer allowed.