Trying to properly rewrite one URL as another but then strip that URL as I reverse proxy to docker?

1. Output of caddy version:

v2.6.1 h1:EDqo59TyYWhXQnfde93Mmv4FJfYe00dO60zMiEt+pzo=

2. How I run Caddy:

sudo docker-compose up -d

a. System environment:

Docker on Bodhi Linux

b. Command:

Paste command here.

c. Service/unit/compose file:

services:
    synapse:
        image: matrixdotorg/synapse:latest
        container_name: synapse                                
        restart: unless-stopped
        volumes:
            - ./data:/data
        environment:                                                
            - SYNAPSE_SERVER_NAME=synhang.host
            - SYNAPSE_REPORT_STATS=no
            - VIRTUAL_HOST=synhang.ddns.net

    caddy:
        image: caddy:latest
        container_name: synapse-caddy
        restart: unless-stopped
        ports:
            - 80:80
            - 443:443
        volumes:
            - ./Caddyfile:/etc/caddy/Caddyfile
            - ./site:/srv
            - ./caddy_data:/data:rw
            - ./caddy_config:/config:rw

d. My complete Caddy config:

synhang.ddns.net {
	tls myemail@proton.me
	file_server 
        handle_path /chat* {
             rewrite * /_matrix/static{uri}
             reverse_proxy synapse:8008
        }
        handle_path /_matrix* {
             reverse_proxy synapse:8008
        }
}

3. The problem I’m having:

I need all URLs ending in /_matrix* to redirect to the synapse container. However, I get a 404 error when doing this from my domain, even though logging directly into localhost:8008 redirects correctly. I believe the issue is that the synapse server is set to accept connections at 8008 with no trailing path in the URL (i.e. not synapse:8008/_matrix/static) and then it redirects to /_matrix/static, however these directories don’t actually exist. When I rewrite the url as /_matrix/static I believe it is requesting synapse:8008/_matrix/static which doesn’t actually exist. So how can I force this to redirect to synapse:8008. I also need all URLs include /_matrix* to redirect to synapse:8008. I also want /chat* to redirect to synapse:8008. How would I achieve this?

Also, if I why is it necessary to include the reverse_proxy directive in the chat* handle_path directive? Once it rewrites /chat* as /_matrix/static shouldn’t it then be handled by the /_matrix* handle_path and reverse proxy from there? I can only get it to work when using rewrite followed by reverse proxy.

4. Error messages and/or full log output:

Paste logs/commands/output here.
USE THE PREVIEW PANE TO MAKE SURE IT LOOKS NICELY FORMATTED.

5. What I already tried:

6. Links to relevant resources:

There’s a lot to unpack here, and I’m not sure I totally understand what you’re trying to do or what you’re saying you have trouble with.

This isn’t a redirect, it’s a proxy.

A redirect in HTTP terminology is specifically to respond with a Location header which instructs the client to make a new request at a different URL, typically with a 3xx status code.

Please show logs. Turn on the debug global option to see the reverse_proxy debug logs to see exactly what the request looks like just before Caddy sends it upstream, and what the response from upstream contains (headers/status).

I don’t understand what you’re trying to say here. Why rewrite to /_matrix/static if it doesn’t exist?

It’s also confusing because of your use of “redirect” which doesn’t mean that.

Do you mean that they should get proxied without stripping /_matrix? Then use handle, not handle_path. The handle_path directive is specifically meant as a shortcut for handle + uri strip_prefix.

The handle and handle_path directives’ job is to set up mutually exclusive routes. Only the first matched one will run. If all you want to do is perform a rewrite then fall through, then you shouldn’t use multiple handle or handle_path beside eachother.

This might be closer to what you’re trying to do, if I understand (I don’t :sweat_smile:)

synhang.ddns.net {
	tls myemail@proton.me

	@synapse path /chat* /_matrix*
	handle @synapse {
		handle_path /chat* {
			rewrite * /_matrix/static{uri}
		}

		reverse_proxy synapse:8008
	}

	handle {
		root * /srv
		file_server
	}
}

So basically, this makes a handle that matches both of those path patterns, and another handle (at the bottom) that catches anything else with the file server.

Inside the first route, if it’s /chat* then it will strip that from the path, then rewrite. Then after the handle is done (whether or not it matched), it falls through and reaches the reverse_proxy which sends the request upstream.

Another way to do it would be with uri replace instead of handle_path/uri strip_prefix which would replace this:

		handle_path /chat* {
			rewrite * /_matrix/static{uri}
		}

with this

		uri replace ^/chat /_matrix/static

This is slightly more succinct, using a regular expression to match /chat at the start of the path and just replace that part with /_matrix/static.

2 Likes

I was misunderstanding some of the caddy terminology lol. Turns out I was using handle_path but I should have been using reverse_proxy instead. The backend server (synapse in this case) will automatically open the URL */_matrix/static when you access the synapse container on port 8008, however, there is no directory on the container with that name (as far as I can tell). However, once I properly set up the reverse proxy following this guide Configuring a Reverse Proxy - Synapse it functioned properly.

1 Like

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