TLS connect errors when trying to set up Nextcloud-AIO behind Caddy

1. The problem I’m having:

I am trying to install and configure Nextcloud-AIO on my server, behind a Caddy reverse proxy. I already have Caddy, using the caddy-docker-proxy plugin—I’d link that plugin here, but I’m running afoul of the max number of allowed links—running in a separate container for my domain, and it correctly directs traffic to other subdomains; for instance, recipes.xanderwhart.us.

I can get the Nextcloud-AIO container up and running, but in its configuration flow, it asks for the domain that the instance will use. When I enter and submit “cloud.xanderwhart.us”, I get the following message in the UI:

Domain does not point to this server or the reverse proxy is not configured correctly.

My logs for nextcloud-aio-mastercontainer also contain error messages, corresponding with the times when I click “submit domain”, which I have pasted below in section 2.

Because of this TLS issue, I am posting for help here, because this appears to be, at least in part, a TLS/proxying issue.

Many of the guides I’ve seen for installing Nextcloud-AIO behind Caddy suggest running an instance of Caddy within the same container; however, because I have other hosted services that I wish to proxy, I don’t believe this would work. My standalone Caddy container is listening on 80 and 443 already.

All that said, I am way out of my depth here, and what I want most is for it to work:

  • Nextcloud-AIO properly installs at cloud.xanderwhart.us
  • Other services (at xanderwhart.us and subdomains) can be accessed correctly as well

2. Error messages and/or full log output:

From nextcloud-aio-mastercontainer logs:

nextcloud-aio-mastercontainer  | NOTICE: PHP message: The response of the connection attempt to "https://cloud.xanderwhart.us:443" was: 
nextcloud-aio-mastercontainer  | NOTICE: PHP message: Expected was: 49401199e9d5ff73c176ba30245b59673e46bae182b49e60
nextcloud-aio-mastercontainer  | NOTICE: PHP message: The error message was: TLS connect error: error:0A000438:SSL routines::tlsv1 alert internal error

The Docker log for the Caddy container can be found here, since it is a very long log file and I want to preserve people’s scroll wheels in this thread.

3. Caddy version:

Installed from image lucaslorentz/caddy-docker-proxy:2.8.4-alpine

4. How I installed and ran Caddy:

a. System environment:

  • Operating system: OpenMediaVault 7.4.16-1 (Sandworm), which is based on Debian 12 (Bookworm)
  • Architecture: x86_64
  • Docker version: 27.4.0

b. Command:

Running Caddy via Docker Compose; see below

c. Service/unit/compose file:

services:
  caddy:
    image: lucaslorentz/caddy-docker-proxy:2.8.4-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    environment:
      - CADDY_INGRESS_NETWORKS=caddy
    networks:
      - caddy
      - nextcloud-aio
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./Caddyfile:/etc/caddy/Caddyfile
      #- ./site:/srv
      - caddy_data:/data
      - caddy_config:/config

networks:
  caddy:
    external: true
  nextcloud-aio:
    external: true

volumes:
  caddy_data:
  caddy_config:

d. My complete Caddy config:

Caddyfile:

{
        debug
}

https://cloud.xanderwhart.us:443 {
        reverse_proxy nextcloud-aio-apache:11000 {
                transport http {
                        tls_insecure_skip_verify
                }
        }
}

e. Nextcloud-AIO compose file:

# https://github.com/nextcloud/all-in-one
# For custom configuration consult -> https://github.com/nextcloud/all-in-one/blob/main/compose.yaml
services:
  nextcloud-aio-mastercontainer:
    image: nextcloud/all-in-one:latest
    init: true
    restart: always
    container_name: nextcloud-aio-mastercontainer
    volumes:
      - nextcloud_aio_mastercontainer:/mnt/docker-aio-config
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - 5050:8080
    environment:
      # - APACHE_ADDITIONAL_NETWORK=caddy
      - APACHE_PORT=11000
      - APACHE_IP_BINDING=0.0.0.0
      - NEXTCLOUD_DATADIR=/akhet/system/appdata/nextcloud_data
    networks:
      - caddy
      
volumes:
  nextcloud_aio_mastercontainer:
    name: nextcloud_aio_mastercontainer

networks:
  caddy:
    external: true
###########################
# https://wiki.omv-extras.org/doku.php?id=omv7:docker_in_omv
###########################

5. Links to relevant resources:

I would provide one more (a link to the OpenMediaVault community wiki page with instructions for installing and setting up Docker and Nextcloud-AIO), but I have reached the limit of links I can add

Thank you for all the help you can provide.

Edit history

  1. Corrected accidental port in Caddyfile (was 5050, is now 443)

Your compose file maps ports for caddy to port 443:

yet your Caddyfile says port 5050:

Good spot, thank you. This appeared because I was (rather crudely) troubleshooting while I wrote this post; the Caddyfile has been returned to cloud.xanderwhart.us:443, as it was intended to be, and as it had been previously when the issue began. Even when the Caddyfile is configured for 443, the issue persists.

I will edit the initial post to avoid future confusion.

You reverse proxy to NAIO, port 11000:

but your NAIO container exposes only port 5050:

Edit: never mind, I missed the fact NAIO is using caddy network.

Can you exec to your caddy container and see if you can resolve the name nextcloud-aio-apache?

Sure thing, thank you. I tried using the troubleshooting command recommended in the Nextcloud-AIO setup guide:

spencer@alexandria:~$ sudo docker exec -it caddy-caddy-1 nc -z nextcloud-aio-apache 11000; echo $?
0
spencer@alexandria:~$ sudo docker exec -it caddy-caddy-1 nc -z nextcloud-aio-apache 443; echo $?
1
spencer@alexandria:~$ sudo docker exec -it caddy-caddy-1 nc -z nextcloud-aio-apache; echo $?
1
spencer@alexandria:~$ sudo docker exec -it caddy-caddy-1 nc -z nextcloud-aio-apache 80; echo $?
1

I think this shows that Caddy will resolve nextcloud-aio-apache:11000, but not any other ports. But I could be misunderstanding.

If there is a preferred way to check if Caddy will resolve that name, please let me know and I’ll be happy to try it.

No worries, you got it right. The following:

means that the container caddy-caddy-1 can talk to nextcloud-aio-apache on port 11000. However, your configuration says the name of the Caddy container is caddy, so I’m not sure where caddy-caddy-1 comes from.

Well, I’m lost at this point.

If we trace your configuration, then:

  1. container caddy exposes ports 80 and 443
  2. if I talk to http://cloud.xanderwhart.us, I get a response from a Caddy server redirecting me to https://cloud.xanderwhart.us
$ curl -is http://cloud.xanderwhart.us | grep -iE 'location|server'
Location: https://cloud.xanderwhart.us/
Server: Caddy
  1. caddy is configured to forward incoming HTTPS traffic for https://cloud.xanderwhart.us:443 to the back-end nextcloud-aio-apache:11000 via HTTP. I can talk to the port 443, but there’s no TLS and no certificate on cloud.xanderwhart.us:443:
$ openssl s_client -servername cloud.xanderwhart.us -connect cloud.xanderwhart.us:443 -status </dev/null 2>/dev/null
CONNECTED(00000003)
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 285 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

My best guess at this point is that you have no TLS key/cert for cloud.xanderwhart.us, meaning Caddy cannot obtain a TLS key/cert for cloud.xanderwhart.us.

Can you please try replacing

https://cloud.xanderwhart.us:443 {

in your Caddyfile with

cloud.xanderwhart.us {

You might get the same result, but I’m just humouring myself to see if that helps.

1 Like

I think you’re running multiple Caddy servers.

I don’t think so, but this was a helpful comment.

Because you’re right, the Caddyfile isn’t being respected. It just doesn’t seem like what I’m putting in the Caddyfile makes any difference. (A previous version of the Caddyfile also had a basic auth directive on it; I removed it for troubleshooting, but it hadn’t been working either. Notice, as well, that the Caddy log I shared didn’t contain any lines flagged with the debug level, despite setting that global option in my Caddyfile.)

The plugin I’m using with Caddy, caddy-docker-proxy, works by automatically generating a Caddyfile in-memory based on labels in Dockerfiles. I thought that it would just automatically pick up my Caddyfile and build on it, but I was mistaken.

The documentation here specifies an option:

--caddyfile-path string
        Path to a base Caddyfile that will be extended with Docker sites

which can also be set with the environment variable CADDY_DOCKER_CADDYFILE_PATH=<string>.

So I updated my Docker Compose file for Caddy:

# unchanged sections above omitted
    environment:
      - CADDY_INGRESS_NETWORKS=caddy,nextcloud-aio
      - CADDY_DOCKER_CADDYFILE_PATH=/etc/caddy/Caddyfile # I think this is a path inside the container?
# unchanged sections below omitted

This points, I think, to the Caddyfile that the container can access at /etc/caddy/Caddyfile, which if I’ve done my volume mapping correctly, should be where I have it located on my filesystem.

So I restarted the Caddy container with this new compose file, and…

…still nothing. Nextcloud-AIO is still failing to connect to cloud.xanderwhart.us. Sonofa—

Well, almost nothing. The debug global option set in the Caddyfile does seem to be registered now; my new logs now contain lots of entries at the debug level.

I also observe that if I run the openssl command from your recent post, I now see some responses, including a server certificate. So something has changed.

For the sake of starting with what is recommended by the installation guide, now that the Caddyfile is being respected, I’ve returned the Caddyfile configuration to:

https://cloud.xanderwhart.us:443 {
        reverse_proxy localhost:11000 {
                transport http {
                        tls_insecure_skip_verify
                }
        }
}

and this Nextcloud-AIO environment variable:

      - APACHE_IP_BINDING=127.0.0.1

I restarted the containers, but of course, our old refrain: still no change.

This from the logs is interesting to me:

{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","server_name":"cloud.xanderwhart.us"}},"error":"tls: first record does not look like a TLS handshake"}
caddy-1  | {"level":"error","ts":1736915663.03697,"logger":"http.log.error","msg":"tls: first record does not look like a TLS handshake","request":
{"remote_ip":"[MY PUBLIC IP]","remote_port":"49670","proto":"HTTP/1.1","method":"GET","host":"cloud.xanderwhart.us","uri":"/nextcloud/status.php","headers":{"Connection":["Keep-Alive"],"Accept-Language":["en-US,*"],"Authorization":[],"User-Agent":["Mozilla/5.0 (Linux) mirall/3.8.2 (build 15392) (Nextcloud, ubuntu-6.8.0-51-generic ClientArchitecture: x86_64 OsArchitecture: x86_64)"],"Accept":["*/*"],"X-Request-Id":["a3ef5c25-4d82-42bb-bdbc-45379ba142c4"],"Cookie":[],"Accept-Encoding":["gzip, deflate"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"","server_name":"cloud.xanderwhart.us"}},"duration":0.001337109,"status":502,"err_id":"ivevqxvg3","err_trace":"reverseproxy.statusError (reverseproxy.go:1299)"}

While I have you here, @timelordx, I really appreciate your help so far. I’m definitely out of my depth, and you’re really helping me. I don’t quite understand where to go from here, but it’s your questions and explanations that helped me think things through and get this little breakthrough, so thank you.