1. Output of caddy version
:
v2.5.2
2. How I run Caddy:
systemctl start caddy
a. System environment:
Arch Linux
b. Command:
systemctl start caddy
c. Service/unit/compose file:
https://github.com/archlinux/svntogit-community/blob/377137893476949e35f0a2f66df52b01acc97b32/trunk/caddy.service
d. My complete Caddy config:
{
servers {
protocol {
experimental_http3
}
}
email asb@asbradbury.org
}
(muxup_file_server) {
file_server {
index ""
precompressed br
disable_canonical_uris
}
}
www.muxup.com {
redir https://muxup.com{uri} 308
header Cache-Control "max-age=2592000, stale-while-revalidate=2592000"
}
muxup.com {
root * /var/www/muxup.com/htdocs
encode gzip
log {
output file /var/log/caddy/muxup.com.access.log
}
header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
vars short_cache_control "max-age=3600"
vars long_cache_control "max-age=2592000, stale-while-revalidate=2592000"
@method_isnt_GET_or_HEAD not method GET HEAD
@path_is_suffixed_with_html_or_br path *.html *.html/ *.br *.br/
@path_or_html_suffixed_path_exists file {path}.html {path}
@html_suffixed_path_exists file {path}.html
@path_or_html_suffixed_path_doesnt_exist not file {path}.html {path}
@path_is_root path /
@path_has_trailing_slash path_regexp ^/(.*)/$
handle @method_isnt_GET_or_HEAD {
error 405
}
handle @path_is_suffixed_with_html_or_br {
error 404
}
handle @path_has_trailing_slash {
route {
uri strip_suffix /
header @path_or_html_suffixed_path_exists Cache-Control "{vars.long_cache_control}"
redir @path_or_html_suffixed_path_exists {path} 308
error @path_or_html_suffixed_path_doesnt_exist 404
}
}
handle @path_is_root {
rewrite index.html
header Cache-Control "{vars.short_cache_control}"
import muxup_file_server
}
handle @html_suffixed_path_exists {
rewrite {path}.html
header Cache-Control "{vars.short_cache_control}"
import muxup_file_server
}
handle * {
header Cache-Control "{vars.long_cache_control}"
import muxup_file_server
}
handle_errors {
header -Cache-Control
respond "{err.status_code} {err.status_text}"
}
}
3. The problem I’m having:
I’ve recently started a new blog and serve it using Caddy. I’ve documented my Caddy setup here. As noted, I had some fairly specific goals in terms of things like redirect behaviour. As the config ended up being fairly involved, I wondered if anyone saw opportunities to simplify (while meeting my stated requirements). See also my test script
I’m pasting the list of goals from the blog post here for convenience:
- Enable new and shiny things like HTTP3 and serving Brotli compressed content.
- Set appropriate Cache-Control headers in order to avoid unnecessary re-fetching content. Set shorter lifetimes for served .html and 308 redirects vs other assets. Leave 404 responses with no Cache-Control header.
- Avoid serving the same content at multiple URLs (unless explicitly asked for) and don’t expose the internal filenames of content served via a different canonical URL. Also, prefer URLs without a trailing slash, but ensure not to issue a redirect if the target file doesn’t exist. This means (for example):
-
muxup.com/about/
should redirect tomuxup.com/about
-
muxup.com/2022q3////muxup-implementation-notes
should 404 or redirect. -
muxup.com/about/./././
should 404 or redirect -
muxup.com/index.html
should 404. -
muxup.com/index.html.br
(referring to the precompressed brotli file) should 404. -
muxup.com/non-existing-path/
should 404. - If there is a directory
foo
and afoo.html
at the same level, servefoo.html
forGET /foo
(and redirect to it forGET /foo/
).
-
- Never try to serve
*/index.html
or similar (except in the special case ofGET /
).
I believe the rules regarding //
and /./
are unimplementable until v2.6.0 (which includes #4948). EDIT: I also can’t see a straightforward way of modifying the above Caddyfile to give 404s for www.muxup.com/non-existent
requests but redirects if the target exists.
4. Error messages and/or full log output:
N/A.
5. What I already tried:
See Caddyfile above.
6. Links to relevant resources:
N/A.