TLS / HTTPS in Self-Hosting
Problem
I have a bunch of services running on my VPS. Most of them are exposed to the Internet. For those, the authentication I rely on is Cloudflare Zero Trust. To log in to the services that are behind this authentication, one will be asked to log in with their email (you can decide what email addresses is allowed) and one-time password, or through a OIDC I also self-host.

However, I have services that cannot be exposed to the broader Internet at all. For example, AdGuard Home.
As a DNS server, it does not come with authentication mechanism at all. If you decide to host it to the Internet, you basically cannot stop anyone from accessing it. Zero Trust also won't work because your clients won't know how to get pass by the Cloudflare's authentication by themselves, so it will be blocking all traffic from reaching AdGuard Home.
In this case, you have to serve this kind of applications in a LAN, and use tools like VPN to connect to the LAN when you want to use the applications. So, nobody can even access the applications without connecting to your LAN because the IPs will be some private ones.
However, this poses a new problem. If you just access those apps with raw IP addresses or have some internal DNS setup, you can only connect to those with HTTP. Most browsers yell at your or warn you about the danger of websites that don't support HTTPS.
In one sentence, how to get HTTPS / SSL working for our internal services that are running on a local network such as your home lab's?
Get to know about HTTPS
I won't be writing about the basic concepts of HTTPS / SSL and how that works, as other people have already done great jobs of explaining these. I recommend the following resources.
This video above explains how SSL works, how to get a free SSL from Let's Encrypt, how to use certbot
to make the process easier.
This video demonstrates how to use Nginx Proxy Manager
to let it easily deal with Let's Encrypt certificates issuing and renewal. Also, it talks about how to get SSL certificates for services that you don't intend to expose to the Internet (i.e. your home lab).
DNS Challenge
Read this doc for more about different challenge types, and specifically, the DNS Challenge
. This, compared to HTTP Challenge
, does not require your server to have ports reachable from Internet.

Most of the time, this challenge needs API token from your DNS provider because the process of challenge requires changing of some TXT
records of the DNS of your hostname.
Here comes the interesting part. Due to the reason that different DNS providers have different APIs, the popular reverse proxies might or might not have this DNS Challenge functionality built in.
Nginx Proxy Manager
It is built in, so you just need to go to the UI and choose the DNS provider in the drop-down menu.
Traefik
It's also built-in.
Caddy

However, for Caddy, it's not the same. Different providers show as different modules, and you need to pick the ones you need and have a custom build of Caddy.
How to with Coolify?
It will be different depending on which proxy you use, Traefik or Caddy.
Traefik

Thankfully, there is an official doc for this.
Caddy
This is where things become interesting. As described above, Caddy has DNS Challenge providers as modules. At the time of this writing, there is no way to specify which variant of Caddy you want in Coolify. So we have to figure something out on our own.
After some trying, this is what I figured out.
Create a new certbot
project

I followed this tutorial to create a new Docker container with certbot/dns-cloudflare
image. Change this to your own DNS provider's variant.
Mount the generated certificates to Caddy
In the above tutorial we have a line in volume
that says this:
- ./letsencrypt:/etc/letsencrypt
The container spits out the certificates in a subfolder of /etc/letsencrypt
. So, we have to map this to a file system location that is also visible to the Caddy proxy.
What I do is:
- '/data/coolify/proxy/caddy/data/caddy/certificates/certbot-ycsh/letsencrypt:/etc/letsencrypt'
If you install Coolify in the official way, you should have the Coolify configs and data under /data/coolify
as well. And, if you are using Caddy as the proxy of your choice, you can find out that /data/coolify/proxy/caddy/data
is mapped to /data
in the proxy.
And I found out that, for certificates under /data/caddy/certificates
Caddy knows to pick them up automatically, without you having to make any modification to other services that you deployed.
Conclusion
There you have it! Now you can enjoy your private services with the benefit of HTTPS.