4 ms·
> The problem for me in understanding that particular config is that I don't know enough about HTTP to know if you can set headers with asterisks in them. I can
by francislavoie 4y ago
> The problem for me in understanding that particular config is that I don't know enough about HTTP to know if you can set headers with asterisks in them. I can't look at that config snippet and figure out immediately if it's matching incoming requests and sending the matched requests to the backend or if it's adding the headers to incoming requests (that are matched some other way) before sending them to the backend.
It's _just_ matching, when it's inside a @ named matcher. No manipulation of the headers is going on. The docs would say so if it did. See https://caddyserver.com/docs/caddyfile/matchers#header https://caddyserver.com/docs/caddyfile/matchers#header
And as for reverse_proxy, all headers are passed through as-is, with a few exceptions which are documented here: https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#defaults https://caddyserver.com/docs/caddyfile/directives/reverse_pr...
> The root of the confusion for me is that other reverse proxies match on a location for that type of stuff (ex: /wss/) and I simply don't know enough about websockets to make an educated guess about how Caddy is deciding where the traffic gets routed. That's not the kind of thing I'd show up on your forum asking about either. I can figure it out if I need to, but that likely involves spinning up a Caddy server and watching the traffic to see what's going on.
Actually, asking on the forums is exactly what you should do, if you're confused. We can help there.
And yes -- the initial websocket connection (which is actually HTTP first, then "upgraded" to a raw TCP duplex pipe) contains those two headers which can be used to reliably match websocket connections. It's more reliable to do it this way than by path, because you can completely multi-plex a regular HTTP app and a websocket app this way even if they both share the same request paths. Some people end up dedicating a separate port for websocket connections for their apps because of concerns of path overlap, but matching on headers let you avoid that.
I'm not sure where you found that config, but I'd hope that there was at least a mention of what it's doing. It was probably originally taken from here in the docs https://caddyserver.com/docs/caddyfile/matchers#named-matchers https://caddyserver.com/docs/caddyfile/matchers#named-matche... which does have a mention of what that matcher is doing.
> Something as simple as `set-header` or `match-header` instead of `header` would make it easier for me to read and learn the config because it adds enough context that I can immediately figure out what the config is doing.
That's redundant, because you're inside of a named matcher, i.e. a thing starting with @, so that's your hint that it's matching.
Also the 'header' directive (outside matchers) doesn't _only_ set headers, it can also delete them or make in-place replacements, or even set a default if none is already set. See https://caddyserver.com/docs/caddyfile/directives/header https://caddyserver.com/docs/caddyfile/directives/header
> I'm talking about make a huge difference for someone that doesn't know everything.
Well, it's a balance. For the Caddyfile, we decided to focus on ergonomics rather than absolute clarity. We could make the syntax more verbose (and early betas of Caddy v2 had a much more verbose matcher syntax) but we want it to be easy to write configs once you've gotten your bearings. Yes there's a learning curve, but there's a learning curve for everything.
> The download page only gives me a binary, right? I need to deal with setting up a system service. It's not hard, but it's extra steps because I need to redo it every time there's an update or I need to automate it somehow.
If you're on debian, you can install Caddy with a systemd service by using our apt repo https://caddyserver.com/docs/install#debian-ubuntu-raspbian https://caddyserver.com/docs/install#debian-ubuntu-raspbian and then if you need to swap out the binary with a custom one, you can follow these steps https://caddyserver.com/docs/build#package-support-files-for-custom-builds-for-debianubunturaspbian https://caddyserver.com/docs/build#package-support-files-for... and then after that point if you need to upgrade versions, you can actually run "sudo caddy upgrade" which will hit the Download page to fetch a new build with the same plugins that you had in your existing binary, but with the latest version of Caddy https://caddyserver.com/docs/command-line#caddy-upgrade https://caddyserver.com/docs/command-line#caddy-upgrade.
> For my specific use case, running a Docker container (locked to a stable tag) that auto updates is ideal.
See my other reply where I explain the setup for Docker. It's super easy!
> Is it reasonable to expect the users of Docker images to be on the same level as the developers of them?
If you're using Docker, it's not a stretch to expect that you can at least copy a Dockerfile from the docs and build it (either with 'docker build' or via your docker-compose.yml). You don't have to build it from CI, you can just build it in-place on the server you're running it on.
> Traefik has Cloudflare DNS support baked in to the official Docker image. It's not nearly as easy as Caddy, but it has it.
And the downside of that is that their binary is significantly more bloated because of it. It has to pull in the Cloudflare Go library for their API, as well as the APIs/SDKs for all the other DNS providers they support. That increases the attack surface a considerable amount. We decided we didn't want to have the bloat and risk by shipping them by default, so they're plugins. Also, most of them are not maintained by us, by rather by the community, because we can't be expected to actually use all these DNS providers ourselves, we can only maintain the ones for providers we actually use ourselves. Nobody ever needs all the DNS providers plugged in at the same time, you'll only ever need one at a time (outside of some weird setups where you're serving domains owned by customers or something).
We've worked hard to make sure building with plugins is as easy as possible, and I really think we've achieved that. You just need Go, and xcaddy (a little helper program we wrote), then you run 'xcaddy build --with <plugin>' and it makes a build for you. The 'builder' docker image variant gives you Go + xcaddy so you can produce a build with whatever plugins you want, very easily.
- donmcronald 4y agoThanks a ton for taking the time to write this reply. I went over it and re-read some of the docs and it makes a lot more sense to me now. The thing that made it click for me is realizing how directives act differently depending on their context/scope (I'm not sure what the right term is). I really appreciate the explanation for the websocket matching. I spent a lot of time tying to find an explanation for that and couldn't find a good overview anywhere. Understanding the way the connection is upgraded helped me understand how everything is matched and sent to the backend. Now that I understand one scenario fairly well the docs are magically easier to read (imagine that! - lol). > Well, it's a balance. For the Caddyfile, we decided to focus on ergonomics rather than absolute clarity. We could make the syntax more verbose (and early betas of Caddy v2 had a much more verbose matcher syntax) but we want it to be easy to write configs once you've gotten your bearings. Yes there's a learning curve, but there's a learning curve for everything. Yes. Everything is like that. When you're learning, you're like me, complaining the config is too terse and magical. Once you know it, you're like me, complaining the config is too verbose and explicit. :-) The plugin/build thing is a bit of a mixed bag. I get the reasoning and the build system is very good/simple (building a Docker image is trivial). I replied to your other example and gave a really unpolished thought dump of why I don't want to maintain my own image. Maybe you could convince some of the infrastructure providers like Cloudflare to maintain community images with their DNS plugins baked in. Thanks again for taking the time to reply. I'm probably going to set up a custom Docker image and give things another try. If I do and I end up using Caddy, hopefully I can pay it forward at some point :-)
- francislavoie 4y ago> The thing that made it click for me is realizing how directives act differently depending on their context/scope (I'm not sure what the right term is). The Concepts page explains https://caddyserver.com/docs/caddyfile/concepts#structure https://caddyserver.com/docs/caddyfile/concepts#structure. Essentially, "directives" are top-level things inside of a site block (or things within 'route' or 'handle' as well, which wrap other directives), and things inside directives are "subdirectives", i.e. options/config for directives. Matchers are just matchers. Things inside an "empty" block at the top of the Caddyfile are "global options" (similar relative placement to directives, but can only appear in the global options block at the top). > Maybe you could convince some of the infrastructure providers like Cloudflare to maintain community images with their DNS plugins baked in. We have no contacts at Cloudflare. They'd have to reach out to us, tbh. But I don't think they are likely to see it as a benefit to them to spend the time either. Ultimately, the plugin very rarely changes, it's pretty stable at this point. > Thanks again for taking the time to reply. I'm probably going to set up a custom Docker image and give things another try. If I do and I end up using Caddy, hopefully I can pay it forward at some point :-) Glad to hear. Next time you need help, the forums are the best place to ask. It actually supports markdown, and it's actually meant for Caddy support https://caddy.community/ https://caddy.community/