Multiple reverse_proxy directives doesn't work as expected

1. Caddy version (caddy version):

v2.0.0 h1:pQSaIJGFluFvu8KDGDODV8u4/QRED/OPyIR+MWYYse8=

2. How I run Caddy:

sudo caddy start

a. System environment:

NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"

b. Command:

sudo caddy start

c. Service/unit/compose file:

N/A

d. My complete Caddyfile or JSON config:

The ones that work as expected:

This one goes to :4444 normally, with /app removed.

testingapp.com {
     log
     reverse_proxy /app/* 127.0.0.1:4444
     uri /app/* strip_prefix /app
}

This one goes to :5555 normally.

testingapp.com {
     log
     reverse_proxy /connect/* 127.0.0.1:5555
}

The one that doesn’t work, all requests are going to :5555 including /app/* (with /app removed though)

testingapp.com {
     log
     reverse_proxy /app/* 127.0.0.1:4444
     reverse_proxy /connect/* 127.0.0.1:5555
     uri /app/* strip_prefix /app
}

3. The problem I’m having:

4. Error messages and/or full log output:

5. What I already tried:

6. Links to relevant resources:

Typically we recommend a pattern like this:

testingapp.com {
    log
    handle /app/* {
        uri strip_prefix /app
        reverse_proxy 127.0.0.1:4444
    }
    handle /connect/* {
        reverse_proxy 127.0.0.1:5555
    }
}

This will make sure the two proxies are mutually exclusive. Should do the trick.

2 Likes

Perfect! Exactly what we are looking for. Thanks a lot.

That’s surprising, since this Caddyfile means:

  1. If the path starts with /app/, strip the prefix /app from the path.
  2. If the resulting path starts with /app/, proxy to :4444, or if the resulting path starts with /connect/, proxy to :5555.
  3. Else do nothing.

You can see the adapted JSON here:

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [
            ":443"
          ],
          "routes": [
            {
              "match": [
                {
                  "host": [
                    "testingapp.com"
                  ]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "rewrite",
                          "strip_path_prefix": "/app"
                        }
                      ],
                      "match": [
                        {
                          "path": [
                            "/app/*"
                          ]
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "127.0.0.1:5555"
                            }
                          ]
                        }
                      ],
                      "match": [
                        {
                          "path": [
                            "/connect/*"
                          ]
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "127.0.0.1:4444"
                            }
                          ]
                        }
                      ],
                      "match": [
                        {
                          "path": [
                            "/app/*"
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            }
          ],
          "logs": {}
        }
      }
    }
  }
}

Directive order is documented here: Caddyfile Directives — Caddy Documentation

How sure are you that all requests were being proxied to :5555, @karllawrence?

1 Like

Aye, I think @matt’s on to something. From that config, I would expect that requests to /app/* would be 200’d with empty response (default behaviour with nothing configured to do).

Uhh, unless the request was for /app/connect/*. In which case it would get sent to :5555. Semantics, though.

1 Like

@Whitestrake is right. It just happened that my :5555 was returning exactly empty 200 repsonse too which I was confused. It didn’t go to :5555 after further testing. It always returns empty response instead even if I changed my :5555 content to be something else.

2 Likes

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