DEV Community

Tyler Smith
Tyler Smith

Posted on • Edited on • Originally published at caddyexamples.com

Routing multiple paths to a reverse proxy using Caddy

Sometimes your app will need to route a handful of paths to one service and all other paths to another. Caddy's named matchers allow you to define a set of path directives then route them all to a single reverse proxy.

:80 {
    bind 0.0.0.0
    encode zstd gzip
    @webapp {
        path /
        path /posts /posts/*
        path /tags /tags/*
        path /static /static/*
    }

    handle @webapp {
        reverse_proxy webapp:3000
    }
    handle {
        reverse_proxy wordpress:80
    }
}
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can omit the handle blocks:

:80 {
    bind 0.0.0.0
    encode zstd gzip
    @webapp {
        path /
        path /posts /posts/*
        path /tags /tags/*
        path /static /static/*
    }

    reverse_proxy @webapp webapp:3000
    reverse_proxy wordpress:80
}
Enter fullscreen mode Exit fullscreen mode

You may wonder why we're matching most path directives against two different routes, using path /posts /posts/* instead of path /posts*.

Using path /posts* could include paths that you don't intend to proxy. If we used path /posts* and path /static*, we would also match on the following routes:

  • /postscript
  • /posts-authors
  • /static-electricity
  • /static-site-generators

This may be the desired behavior in your application, but it's probably not.

Top comments (3)

Collapse
 
vaviloff profile image
Vaviloff

Thanks, that was very useful!

You could also shorten this config a little, for example to match both /path and /path/*, simply write /path*:

    @webapp {
        path /
        path /posts*
        path /tags*
        path /static*
    }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
tylerlwsmith profile image
Tyler Smith

Hey Vaviloff, I'm glad you found the post useful!

You could shorten the config, but it may proxy requests to @webapp that you weren't expecting. With the configuration you posted, the following routes would also be proxied to @webapp:

  • /postscript
  • /posts-authors
  • /static-electricity
  • /static-site-generators

The config I posted will only match against /posts or /post/*, which I think is the behavior that most people are expecting.

I realize that this isn't obvious, so I added a section about it in my post above. Thank you for the feedback: it made this post better 🙂

Collapse
 
vaviloff profile image
Vaviloff

You could shorten the config, but it may proxy requests to @webapp that you weren't expecting

Ah, that's actually a very good point indeed, thanks for making a note!