Based on the documentation the POST /load endpoint accepts mutliple configuration formats (i.e. Caddyfile).
Does this functionality also extend to the other endpoints?
I have a use case in which I want to load Caddy with a default configuration that should always exist. After startup and a few conditions have been evalulated I want to update Caddy’s configuration and being able to use API — Caddy Documentation with the Caddyfile configuration format would be ideal.
No, and the reason is that the other endpoints (/config/*) traverse the JSON structure and manipulate it directly, whereas with a config adapter, that mapping is undefined. For example, it’s not clear what it means to PATCH to a particular path in the config and know how to interpret a partial config from a config adapter in a way that makes sense at that spot. So you have to use JSON.
The Caddyfile is designed for manual, file-oriented workflows, not automation. Sure, you can automate it, but the Caddyfile adapter is not optimized for efficiency (in config loading, I mean) and you lose a lot of flexibility / capabilities with a config file (this is true of any other config format, not just Caddyfile).
But if all you need are small changes, and you insist on using a Caddyfile, then perhaps you can just automate a little change in your Caddyfile and then POST /load it?
I appreciate what you’re saying with JSON v Caddyfile too. At the end of the day though, even with automation, a human usually authors the configuration first. It’s much easier to write the configuration in Caddyfile as opposed to Caddy configuration JSON - it’s a hell of a structure to get your head around.
There are many ways to work around this (including your suggestion), which I can happily do.
Yep, you’re totally right! Consider using caddy adapt to convert your Caddyfile to JSON, then you can make small changes more easily. This way you can maintain a Caddyfile and with a little automation (e.g. a couple lines in a bash script or something) youu can diff the output and POST/PATCH/PUT/WHATEVS the change?
I dunno. What kinds of small changes are you making? What do you have against using /load in your case?
I am thinking I’ll just keep a Caddyfile to make it easy for humans and use a Docker CMD to convert it to JSON using caddy adapt.
The plan is to have two containers.
The first (static) will contain Caddy and is the webserver for my application. Caddy will start with a default configuration containing a website which I always need to exist.
I then have another container (supervisor) which will dynamically configure Caddy for extra websites from a database. supervisor will make a request against the Caddy Configuration API (in static) to updaye Caddy’s configuration.
So one website stays regardless of anything else. Others come and go overtime. I was just hoping to store the configuration for the website that always remains in one spot rather than two, but it’s a little hard trying to use Caddyfile and POST /load.
Again, nothing major and easy to work around.
I have a similar setup which is working really well but I use etcd and confd in the middle to fuse supervisor and static together (i.e. supervisor updates etcd, and I use confd in static to rewrite Caddy configuration files and reload Caddy). I want to remove etcd and confd entirely now that the Caddy Configuration API exists.
Ahh, gotcha – that makes a lot of sense, thanks for the explanation!
What are the two spots, exactly?
For what it’s worth… there is one item on my TODO list which I didn’t get around to yet, which is basically a way to give Caddy a config that tells it how to get the real config. It seems recursive (and it kind of is, if one isn’t careful, I guess), but the idea is that you can give Caddy a single, unchanging config that tells it how to load its initial config—for example, an HTTP request—and then it will use that at startup instead. That way, you could have just one copy of your Caddyfile that Caddy will request when it starts up. Would that be useful?
Our goal with Caddy 2 is (among other things) to simplify your infrastructure. I’m really happy about reading this:
I hope you succeed here. Can you tell me how it turns out?
The two spots are in the supervisor container and the static container. static needs the initial configuration so the always-available site is available. supervisor also needs the always-available site configuration so that when it replaces all configuration using POST /load in can include it with the additional sites configuration, such that the always-available site remains available.
I do like that idea. It does raise a bunch of questions however about initial delay, timeouts, retries, future reloads, etc and might just add more fat to Caddy then what it’s worth?
I’ll try and remember to report back here with how we achieve it. The Configuration API will definitely help to simplify things though.