Caddy+Cloudflare on Docker SSL Error only on internal domain

1. The problem I’m having:

I have purchased two domains through the Cloudflare registrar. One for services that I want to be accessible externally and the other for services that are restricted to the local network. I was able to get the services that I want exposed to work easily; however when I tried to get the local services to resolve I encountered a “ERR_SSL_PROTOCOL_ERROR”.

2. Error messages and/or full log output:

C:\Users\anon>curl -vL home.localvps.dev
* Host home.localvps.dev:80 was resolved.
* IPv6: (none)
* IPv4: 10.0.0.202
*   Trying 10.0.0.202:80...
* Connected to home.localvps.dev (10.0.0.202) port 80
* using HTTP/1.x
> GET / HTTP/1.1
> Host: home.localvps.dev
> User-Agent: curl/8.10.1
> Accept: */*
>
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://home.localvps.dev/
< Server: Caddy
< Date: Sun, 16 Feb 2025 02:15:44 GMT
< Content-Length: 0
<
* shutting down connection #0
* Clear auth, redirects to port from 80 to 443
* Issue another request to this URL: 'https://home.localvps.dev/'
* Host home.localvps.dev:443 was resolved.
* IPv6: (none)
* IPv4: 10.0.0.202
*   Trying 10.0.0.202:443...
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* schannel: next InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAGE (0x80090326) - This error usually occurs when a fatal SSL/TLS alert is received (e.g. handshake failed). More detail may be available in the Windows System event log.
* closing connection #1
curl: (35) schannel: next InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAGE (0x80090326) - This error usually occurs when a fatal SSL/TLS alert is received (e.g. handshake failed). More detail may be available in the Windows System event log.
C:\Users\anon>curl -vL https://home.localvps.dev/
* Host home.localvps.dev:443 was resolved.
* IPv6: (none)
* IPv4: 10.0.0.202
*   Trying 10.0.0.202:443...
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* schannel: next InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAGE (0x80090326) - This error usually occurs when a fatal SSL/TLS alert is received (e.g. handshake failed). More detail may be available in the Windows System event log.
* closing connection #0
curl: (35) schannel: next InitializeSecur

3. Caddy version:

v2.9.1

4. How I installed and ran Caddy:

Installed through docker with a docker compose file.

a. System environment:

Caddy is ran using docker on a Ubuntu 22.04.5 LTS Container in Proxmox version 8.1.4

b. Command:

sudo docker compose -f caddy.yaml up -d

c. Service/unit/compose file:

---
services:
  # Reverse proxy used to expose services
  caddy:
    image: caddy:latest
    restart: unless-stopped
    container_name: caddy
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
      - "2019:2019"
    volumes:
      - ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./docker/caddy/site:/srv
      - ./docker/caddy/data:/data
      - ./docker/caddy/config:/config
volumes:
  caddy_data:
    external: true
  caddy_config:

d. My complete Caddy config:

Here is the Caddyfile. Not posting all of it because I’m hosting a lot of services. Each service is formatted the same way.

{
email   example@gmail.com
}

#Exposed Services
resume.starswept.dev {
        reverse_proxy 10.0.0.202:8002
}

#Local Services
ha.localvps.dev {
        reverse_proxy 10.0.0.56:8011
}

diagrams.localvps.dev {
        reverse_proxy 10.0.0.202:8015
}

5. Links to relevant resources:


5. Additional Information

For a while I was able to resolve home.localvps.dev but not the other local services. However, I tried deleting the data directory in my caddy folder and regenerating it when I restarted the container and I stopped being able to access the home.localvps.dev service. It now appears to be having the same issue as the other services. I am led to believe it is an issue with receiving certificates. Perhaps I set things up wrong on the Cloudflare end?

5. Update

So here is what I did. I went into cloudflare set the A record to a TTL of 1 minute. I set the ip address to my public ip address. Then I deleted the data folder. I restarted the container and waited. The services became accessible externally. Then I changed the ip address back to the internal ip for caddy. Now the services are accessible locally but not remotely.
I am unsure if adding a new service to the caddyfile will need me to repeat this process. I don’t think my setup is done correctly and I feel as if this was a jank and bad solution. If anyone has any ideas on wtf I just did let me know, because I don’t even know why this really worked.

They’re not reachable from the Internet, and Let’s Encrypt requires them to be accessible for the validations necessary to issue certificates by the challenges HTTP-01 or TLS-ALPN-01

To get certificates for internal-only domain names, you’ll need to use the DNS challenge. This article describes how to do that.