I understand that Caddy is stateless. How can I manage the distribution of the configuration file? Also, if changes are made via the API to one Caddy instance, how can I ensure these changes are reflected in the other replicas?
We run caddy in docker swarms and want to make dynamic changes over API so will the data persist across those replicas?
Config persistence and sharing across the replica members is definitely possible! You just need to be mindful about your setup. I believe there are 2 approaches:
Push-Based: Remote Administration
One approach is to use the remote administration feature. This allows you to push changes to a Caddy instance using the Caddy admin API with mTLS authentication. If you’re running a cluster with multiple Caddy nodes, you’ll have to loop through their URLs or have a gateway that distributes the push across all nodes. There are 2 posts that can help you with the remote administration feature:
This article by @yroc92 focuses on how to get started with remote administration
This Wiki post touches on remote administration as foundation for another feature, so you’ll need to split out the information you need from the collection of concepts it introduces.
Pull-Based: Periodic Loader
You can tell Caddy to reload its config periodically using the load_delay property in the JSON config. The property should be inside admin>config in the JSON structure, a sibling to load and persist (note: we’re aware of its absence in the online doc; this is under investigation).
The load_delay property accepts a duration, which can be an integer or a string. An integer is interpreted as nanoseconds. If a string, it is a Go time.Duration value such as 300ms, 1.5h, or 2h45m; valid units are ns, us/µs, ms, s, m, h, and d.
http loader – bundled in standard Caddy: Caddy will call an HTTP endpoint to fetch the new configuration. The receiving HTTP endpoint may read the new Caddy configuration from the filesystem or an s3 bucket, etc. This way, all Caddy instances in your cluster will call the same URL for their configuration, so they’ll receive the same configuration.
storage loader – 3rd-party plugin (Disclaimer: I’m the author of the plugin): This loader uses any Caddy storage as the source of the config, which means you can use a distributed storage (e.g. RDBMS, Redis, s3, Consul, etc.) so all instances receive the config from the same source that’s backed by distributed solution. You’ll find a list of available Caddy storage modules on this page:
Key tip in implementing this is to ensure the load_delay is always present in the new configuration as long as you want Caddy to try to refresh its config. If it’s missing in the newly loaded config, Caddy will stop the periodic refresh and keep the latest loaded config.
Bonus
There’s a mysql config adapter which accepts a JSON of MySQL connection configuration, including a refreshInterval field to pull the new config periodically from MySQL table. You can find it in the list here:
Extra Bonus
The Caddy Decker Proxy module can also be used to distribute config in swarm mode