Reverse proxy specific path with root pointing to dir of static files?

1. Output of caddy version:

v2.6.2

2. How I run Caddy:

a. System environment:

Arch Linux on vultr, no docker

b. Command:

sudo caddy reload --config /etc/caddy/Caddyfile

d. My complete Caddy config:

mywebsite.com {
        encode gzip zstd
        root * /home/a/web/

        #Remember to comment the below forbidden block out when you're installing, and uncomment it when done.
        @forbidden path /data/* /conf/* /bin/* /inc/* /install.php
        handle @forbidden {
                respond * 403
        }
        #End of the forbidden block

        route {
                handle_path /_media/* {
                        rewrite * /lib/exe/fetch.php?media={path}&{query}
                }
                handle_path /_detail/* {
                        rewrite * /lib/exe/detail.php?media={path}&{query}
                }
                handle /_export/* {
                        @export path_regexp export ^/_export/([^/]+)/(.*)
                        rewrite @export /doku.php?do=export_{re.export.1}&{query}&id={re.export.2}
                }
                handle /Wiki {
                        rewrite * /wiki/doku.php?{query}
                }
                try_files {path} /doku.php?id={path}&{query}
        }
        reverse_proxy /* localhost:8000 # NEED ROOT URL TO POINT TO SERVER@8000 , DOING THIS OUT HERE BREAKS THE /wiki
        file_server
        php_fastcgi unix//run/php-fpm/php-fpm.sock
}

3. The problem I’m having:

So at /home/a/web/ I have /home/a/web/wiki/ and a bunch of other stuff there for static files. Accessing the https://mywebsite.com/wiki works fine but now I want to have it so when you navigate to https://mywebsite.com/ , the root, it should go to the reverse_proxy, which it does but it breaks the /wiki saying 404 not found

5. What I already tried:

I tried putting it in the route and doing:

handle /* {
    reverse_proxy /* localhost:8000
}

but still no luck

Here is revised Caddyfile based on your config:

mywebsite.com {
        encode gzip zstd
        root * /usr/local/www
        php_fastcgi 127.0.0.1:9000   #or php_fastcgi unix//run/php-fpm/php-fpm.sock

        @forbidden path /data/* /conf/* /bin/* /inc/* /install.php
        handle @forbidden {
                respond * 403
        }

        handle /_media/* {
                respond "Hello media"
        }
        handle /_detail/* {
                respond "Hello detail"
        }
        handle /_export/* {
                respond "Hello export"
        }

        handle /wiki {
                respond "Hello Wiki"
        }

        reverse_proxy localhost:8000 {
                header_up Host {http.reverse_proxy.upstream.hostport}
        }
        file_server
        try_files {path} {path}/ /index.php
}

I tried and ran the above code without breaking the https://mywebsite.com/wiki after access https://mywebsite.com/ It could be try_files before file_server, (before it doesn’t make sense) , and when I remove header_up Host {http.reverse_proxy.upstream.hostport} , the root page will not load.

1 Like

I tried this and it still breaks /wiki/ for me giving me 404 while the reverse proxy does work. I have a working nginx config here:
Where anything /wiki/* goes to dokuwiki and everything /* just about goes to the reverse proxy

# NGINX CONFIG
server {
    server_name MYWEBSITE.com www.MYWEBSITE.com;
    root /home/a/webdir;
    location / {
        proxy_pass http://localhost:8000;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location /game {
        try_files $uri $uri/=404;
    }
    location /wiki {
        try_files $uri $uri/ @dokuwiki;
        index index.php doku.php;
    }
    # redirect Wiki -> wiki
    location /Wiki {
        rewrite ^/Wiki(.*)$ https://MYWEBSITE.com/wiki/$1 redirect;
    }

    # comment out when setup as we need to get to /wiki/install.php
    location ~ /(data|conf|bin|inc|vendor)/ {
      deny all;
    }

    location @dokuwiki {
        rewrite ^/_media/(.*) /lib/exe/fetch.php?media=$1 last;
        rewrite ^/_detail/(.*) /lib/exe/detail.php?media=$1 last;
        rewrite ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2 last;
        rewrite ^/(.*) /doku.php?id=$1&$args last;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {
        # include snippets/fastcgi-php.conf;
        #include snippets/fastcgi.conf;
        fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/MYWEBSITE.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/MYWEBSITE.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

Trying to match the nginx config closely and interestingly I still get 200s of nothing when I go to /cache/image.png which the reverse proxy should handle… When I change it to handle /* I actually get the image back but then the /wiki/ breaks!

# CURRENT CADDY CONFIG
MYWEBSITE.com {
        encode gzip zstd
        root * /home/a/webdir/
        # fastcgi only things that go to /wiki/*
        php_fastcgi /wiki/* unix//run/php-fpm/php-fpm.sock

        #Remember to comment the below forbidden block out when you're installing, and uncomment it when done.
        @forbidden path /data/* /conf/* /bin/* /inc/* /install.php
        handle @forbidden {
                respond * 403
        }
        #End of the forbidden block

        file_server /wiki/*
        file_server /game/*

        route {
                handle_path /_media/* {
                        rewrite * /lib/exe/fetch.php?media={path}&{query}
                }
                handle_path /_detail/* {
                        rewrite * /lib/exe/detail.php?media={path}&{query}
                }
                handle /_export/* {
                        @export path_regexp export ^/_export/([^/]+)/(.*)
                        rewrite @export /doku.php?do=export_{re.export.1}&{query}&id={re.export.2}
                }
                # i need /Wiki to redirect to /wiki because of an app that is using a hardcoded url to here
                handle /Wiki {
                        rewrite * /wiki/doku.php?{query}
                }
                handle /wiki {
                        try_files {path} /doku.php?id={path}&{query}
                }
                # changing this to /* works but breaks the wiki
                handle / {
                        reverse_proxy 127.0.0.1:8000
                }
        }
}

Let’s break down one by one

handle /wiki only handle MYWEBSITE.com/wiki , but not MYWEBSITE.com/wiki/something/else
my might want to try handle /wiki*

Be careful with that. Keep in mind the directive order.

In that config, you have both reverse_proxy, php_fastcgi and file_server all at the top-level, and none of them are using request matchers. That means the reverse_proxy will always take precedence and all requests will go to that proxy upstream (other than the ones in handle blocks).

Don’t use the try_files directive like that, since php_fastcgi will already do the appropriate rewrites itself. See the php_fastcgi docs.

This is only ever necessary when proxying to an HTTPS upstream. And it can be simplified by using the placeholder shortcut. See the docs: reverse_proxy (Caddyfile directive) — Caddy Documentation

2 Likes

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