Reverse proxy and redirect on same directive

1. Caddy version (caddy version):


2. How I run Caddy:

Using docker-compose

a. System environment:

Ubuntu 20.04 with docker

b. Command:

I use this dockerfile

FROM caddy:2.4.3-builder-alpine AS builder

RUN xcaddy build \

FROM caddy:2.4.3-alpine

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

c. Service/unit/compose file:

      - slimurl_api
      - slimurl_portainer
    container_name: slimurl_caddy_server
    image: slimurl-caddy-server
    restart: unless-stopped
      - 80:80
      - 443:443
      - slimurl_caddy_data:/data
      - slimurl_caddy_config:/config
      - $PWD/caddy-server/.Caddyfile:/etc/caddy/Caddyfile
      - $PWD/caddy-server/logs:/var/log/caddy
      - slimurl

d. My complete Caddyfile or JSON config:

  order rate_limit before basicauth
  admin off

#To use snippet inside directive "import rate_limit_per_min {zoneName} {numRequests} {minutes}"
(rate_limit_per_min) {
  rate_limit {
      zone {args.0} {
      key    {}
      events {args.1}
      window {args.2}m

#Import same as above snippet, first argument is file where to save logs inside the "/var/log/caddy" folder
(log_to_file) {
  log {
    format filter {
		wrap json
		fields {
			request>headers>Authorization delete
  output file /var/log/caddy/{args.0} {
    roll_size     500mb
    roll_keep     10
    roll_keep_for 2880h

#Redirect* to uri without it {

#Handle the actual uri here {
  encode zstd gzip

  reverse_proxy /*  http://slimurl_api:80

  import log_to_file apiLog.log
  route /user/register {
    import rate_limit_per_min register_zone 3 60
  route /user/login {
    import rate_limit_per_min login_zone 5 20

#Frontend {
} {
  reverse_proxy http://slimurl_frontend:80

3. The problem I’m having:

I want to make it so that the frontend directive, reverse proxies to the http://slimurl_frontend:80 only for specific routes and every other route to be forwarded to a backend route{uri} but no matter what I try I cannot get it to work. If I try to use multiple directives my frontend either stops working or all my requests are forwarded to the backend. I would very much appreciate the help.

4. Error messages and/or full log output:

5. What I already tried:

I tried making a matcher and redirecting everything else not matched to the backend but it’s not working {
  @paths {
    path /login*
    path /profile*
    path /
  reverse_proxy @paths http://slimurl_frontend:80
  redir not @paths{uri}

### 6. Links to relevant resources:

The issue you’re running into is that Caddy sorts directives according to this predetermined directive order (redir gets sorted before reverse_proxy):

And also, you have the matcher syntax incorrect for your redir directive; see the matcher docs, the matcher must be a single token (no spaces) and one of three forms:

So there’s two ways to solve this. Either use a not + path matcher on redir and no matcher on reverse_proxy since redir gets sorted first OR use handle directives to implement mutual exclusivity (only the first matching handle will run): {
	@notPaths not path /login* /profile* /
	redir @notPaths{uri}

	reverse_proxy slimurl_frontend:80

OR {
	@paths path /login* /profile* /
	handle @paths {
		reverse_proxy slimurl_frontend:80

	handle {

Hey thank you so much for your reply.

I had to modify the directive a bit to allow .js .css and similar files but it is working great.

Thanks again :slight_smile:

1 Like

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