To be written. This article is not marked as draft because it is linked from elsewhere. When I get time, I will finish it. Draft below.


My server (from which this site is being served) runs on Linux (like most other servers). Now, I’ve had this server for many years and like many others who have hosted something on their servers, I too had installed nginx to redirect multiple domains and their subdomains to different directories and services hosted on the same server (and a couple of those hosted at other places too).

But the title of this post should tell you well enough that I replaced nginx with Caddy. Why though?

Problem with nginx

I come from a time when Apache (and LAMP) were a rage. I have seen nginx solve the C10K Problem and rise to the top, being used by all the biggies.

However, with time, HTTPS took over the web and that is where problems began. Certificates traditionally were issued by corporations that had their CA (Certificate Authority) installed on most operating systems. Let’s Encrypt made HTTPS a commonplace item where anyone could install its certbot and obtain certificates. This however was not a first-party solution. Nginx did not support it on its own. The secondary tool was not that great, made modifications to the nginx config files and that was not an intuitive way of doing things. I myself have caused mis-configurations trying to modify server blocks. Also, if you want to use the certbot for a wildcard domain, the setup requires some DNS challenge which I don’t really like - login to two different places, make sure you wait enough, and renewals are a pain.

On top of that, renewing certificates and adding new domains and/or subdomains under this system was a headache. If you have tried setting up the cert-manager on Kubernetes, you know how painful that can be as well!

The problem is - sometimes I am really active on my server, configuring things, optimizing stuff, monitoring usage and whatnot and sometimes I won’t touch it for months on end. It is in the second phase, when I don’t pay attention to my sites a lot is where the problem begins. Certificates expire and users see the warning pages they should not see! So that certificate management is what got me started.

Caddy Configuration

I really like the concepts in BSD and iOS - there is ONE way to do things. If that way does not work, then it’s not working and you gotta change something. Caddy does not follow that principle - it allows you to configure the server using either a Caddyfile or a caddy_config.json.

The Caddyfile format is very simple and you gotta learn the directives, the order, the arguments to make it work properly. That is quite some learning curve, but if you start to use JSON format (like I did), you will be pulling out your hair because there is not enough documentation and examples out there in the world.

LLMs to the rescue!

Of course I turned to ChatGPT, DeepSeek, Claude, Perplexity and whatever else I could find (going to the level of trying out Gemma and LLama locally). One thing became crystal clear in my mind (and I gotta say it with bold capital letters):

LLMs ARE DUMB AS DUCK

I am sure the feeling has been conveyed without profanity but there it is! LLMs know nothing. They cannot ‘think’. They are a probability distribution of approximations and ranks of words they have found so far around the context provided on the world wide web (I am just going to turn a blind eye towards the copyright infringements big tech just does and no one cares).

All, and I mean ALL (without a single isolated exception) questions that I asked any LLM about configuring caddy was wrong. I was given wrong order of directives, bad/wrong arguments of directives, directives that don’t exist (and never existed in older versions either) and this was beyond frustration. I am sure there are better LLMs out there that can do better but I guess, we are a long way from having something that is actually intelligent. Current generation is not.

Thank you kind humans!

Most of the examples that you would find on the internet about how to use Caddy would take you to some kind of a Caddyfile configuration. But as I said, I had already started with the JSON config and since this was a harder way to do things, I was enjoying it and was making progress.

But then, I was not (still ain’t) an expert at understanding Caddy’s config parameters. So what I wanted was to be able to convert a given Caddyfile to a JSON config (so that I could test those). There is the way to do it this way:

  1. Start a caddy server with the Caddyfile you want to use.
  2. Hit the Admin API and dump the JSON config (using GET /config/ endpoint).
  3. Modify and load that config in the main server.

But that is not a great way to do it. Looking a little deeper, I found this comment on the Caddy’s community website which says that to convert a Caddyfile to JSON, you gotta run the following command:

caddy adapt --config Caddyfile_test --adapter caddyfile

Later I also found this website which does the same thing online (or so it claims, I have not tested it enough to be confident).

All in all, it worked. This site and almost every subdomain of Techrail is being served by Caddy. I am not worried about the SSL certificates anymore now.

NOTE: There is one minor point that you should keep in mind: For caddy to do its magic, you MUST always have the DNS configured before you try to get the certs.

Mild success

I am not totally done. There is a lot that needs to be done to make project-dockter a reality but being able to make Caddy work was a big step in moving further.