Vue history subdirectory in Caddy v2

1. Caddy version (caddy version):

v2.3.0 h1:fnrqJLa3G5vfxcxmOH/+kJOcunPLhSBnjgIvjXV/QTA=

2. How I run Caddy:

caddy run --config ~/Caddyfile

a. System environment:

Macos 11.2.3
Ubuntu Docker 20.10.5

b. Command:

paste command here

c. Service/unit/compose file:

paste full file contents here

d. My complete Caddyfile or JSON config:

caddy
:8082 {
        encode gzip zstd
        route /cmp* {
                redir /cmp /cmp/ 308
                try_files {path} {path}/ /cmp/index.html
                file_server {
                        root /Users/alpha/html/dist
                }
        }
        log {
                level DEBUG
                output stdout
        }
}

nginx
server {
        listen       8081;
        server_name  localhost;
        location /cmp {
            alias   /Users/alpha/html/dist;
            index  index.html index.htm;
            try_files $uri $uri/ /cmp/index.html;
        }
}

3. The problem I’m having:

when I use vue history subfolder.
localhost:8081/cmp it’s nginx ,it’s work well
localhost:8082/cmp it’s caddy2 ,it’s bad

4. Error messages and/or full log output:

5. What I already tried:

google github caddyforum
I have try 100+ for change the Caddyfile

6. Links to relevant resources:

https://amattn.com/p/vuejs_vue-routers_history_mode_and_caddy2.html

The problem is that you’re only setting root for file_server. The try_files matcher also needs to be aware of the root to be able to do its job.

The solution is to use the root directive, rather than the root subdirective of file_server. The directive sets the root directive in the request context, so any subsequent handler can pick it up as their default. The root subdirective is more meant as an override for that default if necessary (usually isn’t).

It looks something like this:

	redir /cmp /cmp/ 308
	handle /cmp/* {
		root * /Users/alpha/html/dist
		try_files {path} {path}/ /cmp/index.html
		file_server
	}

Also made a few minor changes:

  • Use handle instead of route, because you don’t need route’s behaviour of overriding directive ordering
  • Add a / to the matcher to make things like /cmpfoo not also match
  • Move the redirect outside since its purpose is to make sure the request always has the /, and due to the previous fix, it would no longer match if it was inside the handle.

thanks for reply.
But this is still an error.
localhost:8081/cmp nginx ok
localhost:8082/cmp caddy 404

caddy
:8082 {
        encode gzip zstd
        redir /cmp /cmp/ 308
        handle /cmp/* {
                root * /Users/alpha/html/dist
                try_files {path} {path}/ /cmp/index.html
                file_server
        }
        log {
                level DEBUG
                output stdout
        }
}
2021/03/28 07:33:24.838	ERROR	http.log.access.log0	handled request	{"request": {"remote_addr": "[::1]:49191", "proto": "HTTP/1.1", "method": "GET", "host": "localhost:8082", "uri": "/cmp/", "headers": {"User-Agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"], "Sec-Fetch-Mode": ["navigate"], "Sec-Fetch-User": ["?1"], "Sec-Fetch-Dest": ["document"], "Accept-Language": ["zh-CN,zh;q=0.9"], "Sec-Ch-Ua": ["\"Google Chrome\";v=\"89\", \"Chromium\";v=\"89\", \";Not A Brand\";v=\"99\""], "Upgrade-Insecure-Requests": ["1"], "Connection": ["keep-alive"], "Cache-Control": ["max-age=0"], "Accept-Encoding": ["gzip, deflate, br"], "Sec-Ch-Ua-Mobile": ["?0"], "Sec-Fetch-Site": ["none"]}}, "common_log": "::1 - - [28/Mar/2021:15:33:24 +0800] \"GET /cmp/ HTTP/1.1\" 404 0", "duration": 0.00021841, "size": 0, "status": 404, "resp_headers": {"Server": ["Caddy"]}}

Is there no /cmp directory in your root? The file path Caddy looks at is assembled using the root + the request path, so /Users/alpha/html/dist/cmp/index.html for example. Caddy does not do any path stripping by default, unlike the location blocks from nginx.

To get similar behaviour, use handle_path instead of handle directive, which has built-in path stripping logic (and also remove /cmp from your try_files since it becomes redundant).

You may also add this to the top of your Caddyfile to see some additional debugging information in your logs:

{
	debug
}
1 Like

oh thank you very much it’s works well now.

1 Like

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