Caddyfile and v2

Hi Gonzalo, Is there a file called /var/www/talks/talks/vim? If not, that would explain why there’s a 404…

Nop, it’s a directory. Inside there is an index.html file, css/ and js/ directories, etc.

Edit: you ment /var/www/talks/talks/vim or /var/www/talks/vim?

That should work then.

When you paste this command:

ls -l /var/www/talks/talks/vim/index.html

What is the output?

(I mean /var/www/talks/talks/vim, which is what the file server is looking for)

/var/www/talks/talks/vim does not exist, but /var/www/talks/vim does.

$ ls -la /var/www/talks/
total 36
drwxr-xr-x 9 gonzalo staff 4096 Dec 9 19:21 .
drwxr-xr-x 6 gonzalo staff 4096 Jan 7 21:57 …
drwxr-xr-x 7 gonzalo staff 4096 Jan 8 21:54 beyond-php
drwxr-xr-x 7 gonzalo staff 4096 Jul 26 2014 erlang-meetup
drwxr-xr-x 8 gonzalo staff 4096 Jan 8 21:54 go-in-sp
drwxr-xr-x 8 gonzalo staff 4096 Jan 8 21:54 grpc
drwxr-xr-x 8 gonzalo staff 4096 Jan 8 21:54 vim
drwxr-xr-x 8 gonzalo staff 4096 Jan 8 21:54 vim-go
drwxr-xr-x 2 gonzalo staff 4096 Jan 8 21:54 ways2do

Well, that’s clearly why it’s a 404. :man_shrugging:

There’s no magic here, so if you absolutely require /var/www/talks/vim to be accessed when the request path is /talks/vim using a root of /var/www/talks, you have 3 options:

  • Move the file to /var/www/talks/talks/vim
  • Use strip_prefix /talks/* /talks/
  • Set the root to /var/www instead (but note that other files/folders within /var/www could be accessible then)

As with other static file servers, Caddy concatenates the site root with the request URI to form the absolute file path. It’s unconventional to access static files that are not relative to the site’s root. Essentially you have to rewrite the URI, move the root of the site, or move the files.

Ok thanks, will try.

Everything inside /var/www/talks/ are directories, holding static site data. When you say file, it also should work with those?

Yes; index files are used automatically if they exist (similar to other static file servers).

That’s great to hear.

I just tried the first of the second option (strip_prefix):

gon.cat {
    root /talks/* /var/www/talks
    strip_prefix /talks/* /talks/
    root * /var/www/home
    file_server
}

But still gives 404 on https://gon.cat/talks/vim

JSON config is:

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [
            ":443"
          ],
          "routes": [
            {
              "match": [
                {
                  "host": [
                    "gon.cat"
                  ]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "vars",
                          "root": "/var/www/talks"
                        }
                      ],
                      "match": [
                        {
                          "path": [
                            "/talks/*"
                          ]
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "vars",
                          "root": "/var/www/home"
                        },
                        {
                          "handler": "subroute",
                          "routes": [
                            {
                              "handle": [
                                {
                                  "handler": "rewrite",
                                  "strip_path_prefix": "/talks/"
                                }
                              ],
                              "match": [
                                {
                                  "path": [
                                    "/talks/*"
                                  ]
                                }
                              ]
                            },
                            {
                              "handle": [
                                {
                                  "handler": "file_server",
                                  "hide": [
                                    "Caddyfile"
                                  ]
                                }
                              ]
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    }
  }
}

You might want to try the latest on the v2 branch (build from source) which will be beta 13 in a few days, hopefully.

Hello Matt,

I just tried aad9f90c (latest v2 commit) and same results.

JSON config is:

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [
            ":443"
          ],
          "routes": [
            {
              "match": [
                {
                  "host": [
                    "gon.cat"
                  ]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "vars",
                          "root": "/var/www/talks"
                        }
                      ],
                      "match": [
                        {
                          "path": [
                            "/talks/*"
                          ]
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "vars",
                          "root": "/var/www/home"
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "rewrite",
                          "strip_path_prefix": "/talks/"
                        }
                      ],
                      "match": [
                        {
                          "path": [
                            "/talks/*"
                          ]
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "file_server",
                          "hide": [
                            "/etc/caddy/Caddyfile"
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            }
          ]
        }
      }
    }
  }
}

I have a feeling that this should be strip_prefix /talks/* /talks (no trailing slash)

Edit: also you may want to try strip_prefix /talks* /talks or any of these combinations with or without / :stuck_out_tongue:

Can you post a link to a zip file that contains the folder you’re using as your site root? We’ll try to reproduce your issue, but we need your exact site structure in order to have a reliable test environment. The alternative is we enlist your detective skills to help narrow down the problem.

Hi again,

I’m now running beta v13 and trying to have this setup implemented.

Quick recap, at the moment I have this:

gon.cat {
     strip_prefix /talks/* /talks/
     root /talks/* /var/www/talks/
     root * /var/www/home
     file_server
}

https://gon.cat works serving a simple static page and it’s served properly with the contents of /var/www/home. Then at /var/www/talks/vim I have and index.html file with the same permissions as the other sites served:

gonzalo@do2:~$ ls -l /var/www/talks/vim/index.html
-rw-r--r-- 1 gonzalo staff 14631 Jun  1  2019 /var/www/talks/vim/index.html

But I’m not able to serve /var/www/talks/vim/index.html at https://gon.cat/talks/vim, got a 404.

I tried removing the strip_prefix line, also adding slashes doing all the possible combinations without luck.

Thanks!

Ah… duh, this is because the adapted JSON contains:

"routes": [
	{
		"handle": [
			{
				"handler": "vars",
				"root": "/var/www/talks/"
			}
		],
		"match": [
			{
				"path": [
					"/talks/*"
				]
			}
		]
	},
	{
		"handle": [
			{
				"handler": "vars",
				"root": "/var/www/home"
			}
		]
	},
	...

which is normally what you’d want (the more specific handler goes first) but in this case, they need to be mutually exclusive. The second overwrites the first.

One way to solve this would be to structure your Caddyfile more like nginx config’s location blocks:

gon.cat

handle /talks/* {
    strip_prefix /talks/
    root /var/www/talks
}
handle {
    root /var/www/home
}
file_server

Another way would be for us/me to make the root directive mutually exclusive from all other root directive (kind of like handle and rewrite are).

Another way would be to define a matcher that makes them mutually exclusive yourself (i.e. “not /talks/” instead of catch-all).

Another way would be to define multiple sites:

gon.cat {
    root /var/www/home
    file_server
}

gon.cat/talks/* {
    root /var/www/talks
    strip_prefix /talks/
    file_server
}
1 Like

Thanks @matt!

This make the trick:

gon.cat {
    handle /talks/* {
        strip_prefix /talks/* /talks/
        root * /var/www/talks
    }
    handle {
        root * /var/www/home
    }
    file_server
} 

I had to add extra args to the strip_prefix and root directives but now it’s working \o/

1 Like

Oh. yeah, I forgot about that (the matcher tokens). But you can use * in your case since handle already does the path filtering for you:

gon.cat {
    handle /talks/* {
        strip_prefix * /talks/
        root * /var/www/talks
    }
    handle {
        root * /var/www/home
    }
    file_server
} 

Tbh though I think the second example (two sites, as opposed to handle) looks a little cleaner, but that’s just my opinion. I think it’s just a matter of preference!

I just changed it for the sake of testing and also works:

gon.cat {
    root * /var/www/home
    file_server
}

gon.cat/talks/* {
    root * /var/www/talks
    strip_prefix * /talks/
    file_server
}

Thanks again! :partying_face:

1 Like

Awesome!

Just to make your life easier (or to give you more choices), I’ve just made root directives mutually exclusive: httpcaddyfile: Make root directive mutually exclusive · caddyserver/caddy@490cd02 · GitHub

So with that, your original Caddyfile should work:

root /talks/* /var/www/talks/
root * /var/www/home
1 Like

Grea to hear that! I just compiled and run latest v2 version ec56c257089f42ef88ec3a5ec818965c0fa5d57f and this conf:

gon.cat {
    strip_prefix * /talks/
    root /talks/* /var/www/talks
    root * /var/www/home
    file_server
}

But could not make it work. If you need the JSON conf let me know.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.