Reverse proxy to a upstream server with a path or subfolder

1. Caddy version (caddy version):


2. How I run Caddy:

docker run caddy with my custom Caddyfile

a. System environment:


The Question

I am migrating from nginx to Caddy, to reverse proxy my websites.
When users visit my domain, I want to show content that is in a subpath of another domain.
The upstream server has the content in subfolders I don’t want the users see it. It must be transparent to the users.

In nginx, it works like this. Notice that I can inform the subfolder in the proxy_pass configuration:

        location /api/v4/ {
            # proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header        X-Forwarded-Proto $scheme;
            proxy_pass    ;
            proxy_pass_request_headers      on;

How to do it in Caddy? I tried many configurations but I couldn’t find a solution. In the reverse_proxy configuration can only have scheme, host and port, and neither paths or parameters:

localhost {
    reverse_proxy { 
     #how to setup the upstream subfolder here?

So to summary up, when user visit http://localhost I want to show the content of without changing the URL the user sees.

Use the rewrite directive to add a prefix to the path before proxying:

rewrite * /slate-easypnr-api-v4{uri}

If you also need to strip a prefix to replace that segment, then I recommend using handle_path to strip it first:

handle_path /api/v4* {
	rewrite * /slate-easypnr-api-v4{uri}
1 Like

Thank you @francislavoie
It seems I am close to a solution. Excellent.

Now, I had to preserve the original host in the header of the request towards the upstream server.
I added header_up Host to make it work. Is there a more elegant way for doing it?
I tried header_up Host {host} but it seems the server does not understand…

There’s a section in the docs that explain what to do when you’re proxying to an HTTPS upstream:

1 Like

Thanks for pointing it.
It was confusing for me why it is host_port and not host in this case.
But with your help it finally worked.

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