This post will be a relatively short account of my preference for Caddy over Traefik.
A fair few months ago, enough that the details have been lost and all that remains is the lesson I drew, I tried to use Traefik for a new very simple deployment. I had previously successfully used Traefik for a toy project on my raspberry pi, with it automatically registering Let's Encrypt certificates with docker containers. That sounded nice, and with a little effort, it worked (and continues to work to this day).
As a result, I tried duplicating this same simple setup for another deployment that didn't need anything as remotely advanced as Kubernetes which I sometimes use. It was a simple project, since I was pretty much duplicating the configuration I already had. It didn't work. I spent many hours that day looking at the documentation trying different things, carefully looking over the spelling of names in my configurations, and could not see anything in the documentation that would suggest I had misconfigured, nor any notable point of difference with my working setup.
In the end, I was too frustrated with the experience of it not working when it should work, and started to feel like it was too 'magic'. I instead tried Caddy which I've used for other projects as well. Within about 10 minutes I had my complete setup working! It was night and day. Caddy is just simple, obvious, easy to set up, and simply works. I can't see myself using Traefik again.
While there are some success stories, the stories that resonate with me are the failure stories like these from Hacker News:
I wish I could like Traefik, but it really isn't easy.
The use case in our Hackerspace was to dispatch different Docker containers through our wild-card subdomains. Traefik is supposed to also automatically create TLS certificates. I had numerous problems with the Let's Encrypt functionality.
Debugging information is quite cryptic, the documentation seems all over to me, which is even more problematic given the number of breaking changes between 1.x and 2.x versions. The way you automatically configure things through Docker labels means that a simple typo can render your configuration ignored.
I worked on a project last year where we tried using Traefik on Kubernetes together with Let's Encrypt certs. It worked... sometimes.
We had significant issues with Traefik not allocating or renewing certs, resulting in some painful outages. The worst part was that there was no workaround; when adding a new domain to an ingress, it was completely incomprehensible why Traefik wasn't requesting a cert, or indeed why it wasn't renewing older ones that were close to expiration. We filed GitHub issues with concrete errors, but they were never addressed. At the time, I tried to debug Traefik to understand how it worked and maybe chase down some of those bugs. I don't like to speak ill of other people's code — let's just say that peeking under the covers made me realize perfectly why Traefik was so brittle and buggy.
I tried, really tried to use traefik for a year. It worked sometimes, the setup was complicated and the community support is very poor.
I eventually moved to caddy (https://caddyserver.com/) and it is fantastic. Works seamlessly and I got all my obvious and not so obvious questions answered.
In short, I do not recommend Traefik, and highly recommend Caddy over similar projects for deployments that are within its wheelhouse.