Caddy is a really nice server but the documentation for v2 is kind of strange. Every documented config setting is for the new json format, but there is almost no information or examples for a complete json config. And all complete examples are with the old Caddyfile which has now no documentation anymore.
>Every documented config setting is for the new json format
I did my v2 migration this past weekend and for few minutes thought this as well.
I think part of the problem is that when you use the site search for some Directives all that comes up is a selection of the corresponding Module docs and not the Directive docs.
For example, if I search "reverse_proxy" I get links to pages like [0] but no link to [1].
If the search could prioritize exact-matches to document titles that may help.
I'm open to that! Do you know how to do that with Algolia's site search? I'm kind of new to it and a collaborator actually did most of the initial set up.
Examples can be found on the wiki on the community forums (which is linked to right at the top of sidebar in the docs site): https://caddy.community/c/wiki/13
If you still need v1 documentation, you can download an archive of the old website here (linked in the bottom of the docs sidebar) https://caddyserver.com/caddy-v1-docs-archive.tar.gz but please upgrade to Caddy v2, it's better in every way.
I think there is a more positive interpretation of comments like GP regarding the v2 documentation. There might be content but is not discovered easily. I have experienced this myself, the structure of the docs, currently, is not structured in a way that makes it easy to find what you need.
A lot of the meat is interspersed in random replies to questions both in github issues and community posts. Also, I have the impression that some content is not accessible (linked?) from the side bar in the docs page but only through links from content pages.
Most google and github search return content for v1, most tutorials online are for v1.
I don’t think the feedback was meant to detract from the effort put to document things, it just highlights that current documentation could be better organized.
We love Caddy, especially for the read-friendly nature of Caddyfiles and the built-in LE. But, we do find the docs and plugin situations difficult enough for deeper customization + debugging that we still also use Nginx elsewhere, and are only now getting serious about a V1 -> V2 migration. The below are about our V1 docs experience and looking at V1 -> V2 migration two times and being scared off, and hopefully actually doing it the third time.
1. Docs:
-- Common full working configurations are unclear: Finding them requires Google searches hitting broken examples in support forums, when you are lucky that they exist. This is common stuff like proxying, auth API gates, etc. (There was a small V1 github repo that was helpful, it may exist for V2 as well now?)
-- The doc style seems to prioritize terseness vs. clarity. (Even in math, we know an error-correcting language uses repetition & spacing to provide value beyond what a minimal number of characters can do ;-))
-- Examples... aren't. Ex: They are generally 'out-of-context', so unclear how to put into a full working configuration, even at the syntax level
2. Plugins:
The philosophy of pushing basic capabilities to the community via plugins makes sense for a small-staffed effort, though like the JavaScript nodejs/npm situation, that causes its own problems. The above examples like auth are so basic that even if they're via the community, they're part of a migration of a real implementation, and even if the core is fine, they're central enough that they need to be great too: features, docs, etc. Node kind of got away with it b/c a few people took on big lifts for stuff like the HTTP libraries, and that was a big part of the success. Our earlier analysis of basic V2 plugins showed they were a WIP, and while we're now revisiting, it was disappointing to see V1 stopped.
Hope that helps! We are not paying users, but we do evangelize to federal + F500 IT types.
Regarding full configurations, what do you want to have there? It seems infeasible to provide a full configuration that works for everyone, since everyone's sites and deployments and requirements are different, even if a little bit. Aren't there thousands, nay millions, of ways to configure any number of sites and services in any number of environments? I hesitate to get in the territory of "this is exactly how you do this, no need to read and learn how it works" -- because then we have a lot of uninformed, confused users (we learned this from experience in v1). I think our biggest mistake in v1 was making things too easy.
As for plugins, Caddy 2 is nearly infinitely extensible, and I myself can't commit to building everything that is needed... we definitely rely on the community to build what they need, and then share it. It worked in v1, I think it will work in v2, too! It will also happen much more quickly and probably be higher quality in the long run.
Maybe as an exercise, try working backwards for some top 5 scenarios (reverse proxy, multi-domain, static server, bastion, ...), or better, record a session of someone trying it out for the ~first time. Ex: "I'd like to host multiple sites on one subdomain: that means reverse proxying several pages and doing an auth header check (ex: JWT)".
As a user, I'd check the tutorials + corresponding docs. It's tantalizingly close, but some quick gotchas already:
-- There is a reverse proxy tutorial... but it's too minimal. No multiple paths, route rewriting, ... . It does get you to the reverse proxy directive docs, which has more examples, and then another jump to matchers.
-- There is no auth tutorial section, which I would have thought would be somewhere in the ~top 5 scenarios. A search for 'jwt' gets me to the JWT plugin, but unclear what a sample config for a route would be, say for a boring Django / Rails / auth0 setup of "Authorization: Bearer ..." -> "/some/check/route": https://caddyserver.com/docs/modules/http.authentication.pro....
One of the toughest parts of writing is reading your own work :)
Good ideas, and maybe add some easy starters: This is how you use php‘s framework laravel, this is how you do reverse proxying to nodejs.
The crucial part for me would be that every of these examples will be done with the old Caddyfile and the new json format. With enough samples you would get a good feeling on how to transform these caddyfiles to the json format.
To be clear, you can still use the Caddyfile in v2, and frankly it's what I would recommend, especially for a Laravel app. It'll just be as simple as this:
> I have the impression that some content is not accessible (linked?) from the side bar in the docs page but only through links from content pages.
That may be true, but we have hundreds of content pages in the new docs. It's a bit unmanageable to have them all in a sidebar.
Not sure what we can do about search results and content on other sites, either, other than encouraging contributions to our wiki so people can find things easier.
It would be helpful to understand why you found that to be the case.
We get off-hand comments like this about the docs on occasion, and without explanation, we can't do anything to improve the docs to resolve the complaints.
We put in a ton of effort on the docs, and we think they're great. What are you missing? Did you spend the time going through and reading the docs?
First, just gotta say, I love Caddy, and thanks to you, mholt, and the rest of the team for everything you do.
I'm actually a recent Caddy convert, and only picked it up after I saw the v2 GA announcement here on HN. I'm also not using it at large scale: it's just the frontend reverse proxy for my home infra, which is itself frontended by CloudFlare's strict-level DDoS protection/proxy.
I set everything up a few months ago, and my pain with the documentation was that it tended to only address the extremes of dead-simple Cadddyfile examples or very intricate JSON reference. Given that I was working with CloudFlare, thinks were a little more complicated: I had to setup my own Dockerfile to recompile against the externally-maintained CloudFlare module (which, btw, thank you to ever maintains the builder container for making that dead simple with Docker's copy feature). Then some more extra stuff in the Caddyfile to pass in the API key, as well as to work properly with a totally different cert sitting on the web server I was reverse proxying.
That being said, I came back this last weekend to fix up some other stuff, and it seemed like the docs were more complete in general. I found a lot of Caddyfile reference that I needed very easily. So either discoverability or content was improved, or I was just not acquainted enough with Caddy to find it last time (which is totally possible).
And just 2cents from a user who also PMs some OSS software: mad respect for being out here and asking these questions. I completely feel how hard it can be to get anyone to answer this in good faith, and the slow build of anxiety that comes in seeing vague complaints like this littered throughout the internet. Even if I know that they don't mean it personally, it can get me very worked up, especially after many years of reading it.
And yet, doing it repeatedly is the only way to know wtf to improve. I can completely relate with Caddy on the telemetry stuff too, God knows that's an even more difficult sell.
I've also seen the negative sentiment to the v2 docs. I've been hesitant to jump in on the community site because I've seen a lot of - very polite, like yours - RTFM responses, citing the work you've put in etc.
I am probably one of those people who would have flamed someone 20 years ago for posting a critique like this without _any_ time to help directly, but I'm not too proud to give you a "moron in a hurry" perspective, because I think it answers your question.
Firstly - maybe do nothing. This is just what losing your old users looks like. They make a lot of noise that things aren't the same, that they're lost, confused etc. and want you to sink a lot of effort into making them comfortable. It's probably not worth it! You know what your success metrics for Caddy look like - so if v2 is succeeding in terms of adoption etc. - just let users go, or trust that they will work it out eventually.
But as one of these muddled users from 5 years ago who has put v2 into production despite the confusion: the v1 docs were brilliant. They were written hand-in-hand with a piece of software that had a target user in mind, and was so clearly hungry for adoption. The Caddyfile remains excellent, an ambitious design to map out what admins truly wanted to configure in a web server, removing everything else.
I think that explains negative sentiment to the v2 docs - Caddy is not built around the Caddyfile any more. So the docs don't centre it, and so caddy doesn't look like it's designed to do the same things. With v1, I felt that as I understood the Caddyfile, I understood caddy, an important and magical new binary on my system. That was almost certainly a flattering lie, but it never faltered. Every experience I had with v1 backed it up.
The v2 docs make clear that the Caddyfile is _legacy_, and that my old understanding doesn't help. The "Getting started" guide introduce Caddy's config with a JSON config eight brackets deep. Eight! Then it tells you about the API that you might want to use to reconfigure it. Then it tells you about the Caddyfile, but makes clear that it's compiled to the "real" config, and that you'll miss some features in using it.
I briefly look for the JSON reference, and it's nothing like as simple as the Caddyfile. I dig 3 brackets down before to find the configuration for the HTTP server (wait, what, that's just a module now), and there's a lot of boilerplate in that. So there's this mental conflict as I read - the docs say that Caddyfile is _a_ valid way of configuring caddy, but it's clear I'm missing out a true understanding of the program which now has a lot of boilerplate. BOOOOO to boilerplate. Like caddy has spilled its guts into the JSON - the hardwired elegance is a bolt-on. I'm sure this is a lot like how v1 worked, except the v1 docs didn't want me to love its guts.
The v2 docs document Caddy very well, but they sugar-coat the effort of re-understanding a server that old users felt they understood before. It is just not as easy as it was (NB it is still quite easy).
I am happy I can continue using v2 because of the nearly-the-same Caddyfile, but at some point I will have to understand the JSON to really feel in control of my server - maybe that's only 2-3x more work than writing this comment has been :) but that's work the v1 docs never made me do.
You're right about old users, we're not losing sleep over it, we just at least want to lend those users a hand to help them get over the hump to transition to v2. Generally, users should forget everything they knew about Caddy v1 and spend the time to learn Caddy v2 with fresh eyes.
I will say I'm probably the biggest champion of the Caddyfile config language right now, and it's definitely _not_ legacy. It's here to stay. It's just that the v1 Caddyfile hindered the underlying design of Caddy and made it too inflexible. In v1, the Caddyfile was the _only_ config language, and its syntax and design did not allow for flexibility.
For example, in Caddy v1, request matching was not a generalized concept, it was implemented per directive. Each directive had to do its own decisions whether it should apply on any given request, and parse the config for that, etc. In v2, request matching is generalized, and can apply to any directive that is an HTTP handler. Much easier to understand, and much more flexible, much more powerful.
It's true that in v2, the Caddyfile isn't the primary configuration language, but that doesn't mean it's not the users' primary configuration language. The Caddyfile is essentially a layer of magic that maps to the underlying JSON to make it easy to write configs easily and quickly.
Matt decided to explain upfront that JSON is the primary internal config language, because it's important to understanding how Caddy works. It's dangerous to have people run servers without understanding at least a few of the fundamental principles that make them run. That's the purpose of the Getting Started guide, to guide the user through the fundamentals of Caddy so they have a basis of understanding.
Too many people want to go fast and aren't willing to spend the time reading, which is frustrating. Running any kind of web server is a time investment.
I changed over months and months ago to v2. It was painful, but docs were being written at the time, and the community was able to help me with most of my problems. The one last problem I've not solved yet is having caddy 2 work with bitwarden whereby bitwarden's ssl does not conflict with caddy 2. I was unable to figure out how to work with it, so my bitwarden ssl expires every month or two and I have to manually update the ssl by bringing down my personal site for a couple of minutes.
Can you share what your setup is like? I have bitwarden_rs self-hosted with Caddy in the front doing TLS termination and proxying the request to Bitwarden_rs and haven't experienced any issues for more than a year and half now. There are many ways in how Caddy can be configured (e.g. maybe even just keeping the certs updated, but not serving any HTTP requests [0]). Feel free to drop a thread on the Caddy forum and we can help you out!
Bitwarden's docs say it's possible to bring your own certs[0]. The Bitwarden marketplace image on DigitalOcean asks whether you want it to manage its own certs or not. From minor googling, it seems you can change your mind later by modifying a yaml file[1]. HN threading isn't best format for support. If this still doesn't help, let's move the discussion elsewhere.