Caddy enable HTTPS on plain IP address
2026-05-09
Caddy is a production-ready http(s) server with support for automatic certificate retrieval. I have an app running in a docker container provisioned by docker-compose and I wanted to enable HTTPS on it but without giving it a domain (it is an internal app accessible only from local network). This means that I cannot use the usual Let's Encrypt or any alternatives, since they only give certificates to full domains.
Adding caddy to docker-compose.yml was straight-forward however after restarting docker I couldn't access the HTTPS version of the app, which failed with a cryptic error message (here from curl).
OpenSSL: error:0A000438:SSL routines::tlsv1 alert internal error
Unable to establish SSL connection
Turns out that the problem does not stem from Caddy itself but how modern browsers treat plain-IP websites. When putting an IP address to the address bar and hitting enter, the browser (and most other HTTP(S) clients) do not send the hostname header, which is needed for the server to correctly choose the SSL certificate to use. This means that we need to provide a fallback hostname server-side to allow such clients to establish an SSL connection.
This is how my Caddyfile looks right now after the fixes:
{
default_sni IP_ADDRESS
skip_install_trust # we are running in a container
}
IP_ADDRESS {
tls internal
reverse_proxy http://app
}