Caddy makes certs as directories?

1. The problem I’m having:

When I start caddy, it frequently creates directories named
mail.dragonmail.social.crt mail.dragonmail.social.json mail.dragonmail.social.key
In the letsencrypt directory: caddy/data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/
This is a recent thing. It just started doing this within the last week or two. When I delete those directories, it switches to the zerossl certificates it already has and everything is fine. Do you know what would cause it to generate directories instead of files? It generates the directories, complains about the path being directories and not files, then closes. I then have to delete the directories manually, restart caddy, and let it automatically switch over to zerossl.

I’m still very new to reverse proxies and all the configs for this, so I’m going to assume I have things setup in my caddyfile and compose file in a way that is very inefficient or irksome. Sorry about that to anyone annoyed by my configs.

2. Error messages and/or full log output:

dragonmail:/media/configs$ docker compose logs caddy|grep caddy|grep directory|grep mail.dragonmail.social
caddy  | {"level":"error","ts":1735637166.7052178,"logger":"tls","msg":"deleting expired certificates staples","storage":"FileStorage:/data/caddy","error":"loading certificate file certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.crt: read /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.crt: is a directory"}
caddy  | Error: loading initial config: loading new config: http app module: start: finalizing automatic HTTPS: managing certificates for [trbl.dragonmail.cloud dragonmail.social track.dragonmail.cloud element.dragonmail.cloud firefly.dragonmail.cloud dragonmail.cloud srv.dragonmail.cloud portainer.dragonmail.social mail.dragonmail.social nextcloud.dragonmail.cloud auth.dragonmail.social auth.dragonmail.cloud matrix.dragonmail.cloud chat.dragonmail.cloud]: automate: manage [trbl.dragonmail.cloud dragonmail.social track.dragonmail.cloud element.dragonmail.cloud firefly.dragonmail.cloud dragonmail.cloud srv.dragonmail.cloud portainer.dragonmail.social mail.dragonmail.social nextcloud.dragonmail.cloud auth.dragonmail.social auth.dragonmail.cloud matrix.dragonmail.cloud chat.dragonmail.cloud]: mail.dragonmail.social: caching certificate: read /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.key: is a directory
caddy  | Error: loading initial config: loading new config: http app module: start: finalizing automatic HTTPS: managing certificates for [element.dragonmail.cloud matrix.dragonmail.cloud srv.dragonmail.cloud auth.dragonmail.social auth.dragonmail.cloud dragonmail.social mail.dragonmail.social dragonmail.cloud track.dragonmail.cloud portainer.dragonmail.social nextcloud.dragonmail.cloud trbl.dragonmail.cloud chat.dragonmail.cloud firefly.dragonmail.cloud]: automate: manage [element.dragonmail.cloud matrix.dragonmail.cloud srv.dragonmail.cloud auth.dragonmail.social auth.dragonmail.cloud dragonmail.social mail.dragonmail.social dragonmail.cloud track.dragonmail.cloud portainer.dragonmail.social nextcloud.dragonmail.cloud trbl.dragonmail.cloud chat.dragonmail.cloud firefly.dragonmail.cloud]: mail.dragonmail.social: caching certificate: read /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.key: is a directory
caddy  | Error: loading initial config: loading new config: http app module: start: finalizing automatic HTTPS: managing certificates for [track.dragonmail.cloud matrix.dragonmail.cloud chat.dragonmail.cloud auth.dragonmail.cloud firefly.dragonmail.cloud auth.dragonmail.social portainer.dragonmail.social mail.dragonmail.social srv.dragonmail.cloud trbl.dragonmail.cloud dragonmail.social element.dragonmail.cloud dragonmail.cloud nextcloud.dragonmail.cloud]: automate: manage [track.dragonmail.cloud matrix.dragonmail.cloud chat.dragonmail.cloud auth.dragonmail.cloud firefly.dragonmail.cloud auth.dragonmail.social portainer.dragonmail.social mail.dragonmail.social srv.dragonmail.cloud trbl.dragonmail.cloud dragonmail.social element.dragonmail.cloud dragonmail.cloud nextcloud.dragonmail.cloud]: mail.dragonmail.social: caching certificate: read /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.key: is a directory

It’s hard to get everything you need because the error doesn’t happen every time Caddy starts up. I can delete those directories and it loads using zerossl if I restart it. I also have a decent number of containers loaded up filling the logs. Here’s everything that mentions my mail server.
edit: or not…If I leave all this in, I pass the character limit for posts, so I’ll clip the top.

dragonmail:/media/configs$ docker compose logs caddy|grep caddy|grep mail.dragonmail.social

caddy  | {"level":"error","ts":1735637166.7052178,"logger":"tls","msg":"deleting expired certificates staples","storage":"FileStorage:/data/caddy","error":"loading certificate file certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.crt: read /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.crt: is a directory"}
caddy  | Error: loading initial config: loading new config: http app module: start: finalizing automatic HTTPS: managing certificates for [trbl.dragonmail.cloud dragonmail.social track.dragonmail.cloud element.dragonmail.cloud firefly.dragonmail.cloud dragonmail.cloud srv.dragonmail.cloud portainer.dragonmail.social mail.dragonmail.social nextcloud.dragonmail.cloud auth.dragonmail.social auth.dragonmail.cloud matrix.dragonmail.cloud chat.dragonmail.cloud]: automate: manage [trbl.dragonmail.cloud dragonmail.social track.dragonmail.cloud element.dragonmail.cloud firefly.dragonmail.cloud dragonmail.cloud srv.dragonmail.cloud portainer.dragonmail.social mail.dragonmail.social nextcloud.dragonmail.cloud auth.dragonmail.social auth.dragonmail.cloud matrix.dragonmail.cloud chat.dragonmail.cloud]: mail.dragonmail.social: caching certificate: read /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.key: is a directory
caddy  | {"level":"info","ts":1735637178.827913,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["element.dragonmail.cloud","matrix.dragonmail.cloud","srv.dragonmail.cloud","auth.dragonmail.social","auth.dragonmail.cloud","dragonmail.social","mail.dragonmail.social","dragonmail.cloud","track.dragonmail.cloud","portainer.dragonmail.social","nextcloud.dragonmail.cloud","trbl.dragonmail.cloud","chat.dragonmail.cloud","firefly.dragonmail.cloud"]}
caddy  | Error: loading initial config: loading new config: http app module: start: finalizing automatic HTTPS: managing certificates for [element.dragonmail.cloud matrix.dragonmail.cloud srv.dragonmail.cloud auth.dragonmail.social auth.dragonmail.cloud dragonmail.social mail.dragonmail.social dragonmail.cloud track.dragonmail.cloud portainer.dragonmail.social nextcloud.dragonmail.cloud trbl.dragonmail.cloud chat.dragonmail.cloud firefly.dragonmail.cloud]: automate: manage [element.dragonmail.cloud matrix.dragonmail.cloud srv.dragonmail.cloud auth.dragonmail.social auth.dragonmail.cloud dragonmail.social mail.dragonmail.social dragonmail.cloud track.dragonmail.cloud portainer.dragonmail.social nextcloud.dragonmail.cloud trbl.dragonmail.cloud chat.dragonmail.cloud firefly.dragonmail.cloud]: mail.dragonmail.social: caching certificate: read /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.key: is a directory
caddy  | {"level":"debug","ts":1735637894.3101144,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{"subjects":["portainer.dragonmail.social","nextcloud.dragonmail.cloud","element.dragonmail.cloud","firefly.dragonmail.cloud","matrix.dragonmail.cloud","auth.dragonmail.social","mail.dragonmail.social","track.dragonmail.cloud","trbl.dragonmail.cloud","auth.dragonmail.cloud","chat.dragonmail.cloud","srv.dragonmail.cloud","dragonmail.social","dragonmail.cloud"]},{}]}},"http":{"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"portainer:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"static_response","headers":{"Location":["/remote.php/dav/"]},"status_code":301}],"match":[{"path":["/.well-known/carddav"]}]},{"handle":[{"handler":"static_response","headers":{"Location":["/remote.php/dav/"]},"status_code":301}],"match":[{"path":["/.well-known/caldav"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"nextcloud-aio-apache:11000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"deferred":true,"delete":["server"],"set":{"Permissions-Policy":["accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"],"Strict-Transport-Security":["max-age=63072000; includeSubDomains;"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-Robots-Tag":["none"],"X-Xss-Protection":["1"]}}},{"encodings":{"gzip":{},"zstd":{}},"handler":"encode","prefer":["zstd","gzip"]},{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-element:80"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"body":"woah, there are like flies, and they're like....on fire","handler":"static_response"}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"deferred":true,"delete":["server"],"set":{"Access-Control-Allow-Origin":["*"],"Permissions-Policy":["accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"],"Referrer-Policy":["strict-origin-when-cross-origin"],"Strict-Transport-Security":["max-age=63072000; includeSubDomains;"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-Robots-Tag":["none"],"X-Xss-Protection":["1"]}}}]},{"group":"group6","handle":[{"handler":"subroute","routes":[{"group":"group1","handle":[{"handler":"rewrite","uri":"/"}],"match":[{"path":["/synapse-admin/"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse-admin:80"}]}]}]}],"match":[{"path":["/synapse-admin/*"]}]},{"group":"group6","handle":[{"handler":"subroute","routes":[{"group":"group0","handle":[{"handler":"rewrite","uri":"/"}],"match":[{"path":["/synapse-admin"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse-admin:80"}]}]}]}],"match":[{"path":["/synapse-admin"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse:8008"}]}],"match":[{"path":["/_synapse/client/*"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse:8008"}]}],"match":[{"path":["/_matrix/*"]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"authentik:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"stalwart-mail:8080"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"ryot:8000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"portainer:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"authentik:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"deferred":true,"delete":["server"],"set":{"Permissions-Policy":["accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"],"Strict-Transport-Security":["max-age=63072000; includeSubDomains;"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-Robots-Tag":["none"],"X-Xss-Protection":["1"]}}},{"encodings":{"gzip":{},"zstd":{}},"handler":"encode","prefer":["zstd","gzip"]},{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-element:80"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"body":"sticker picker not enabled","handler":"static_response"}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"encodings":{"gzip":{}},"handler":"encode","prefer":["gzip"]},{"body":"dragonmail, yaaaay","handler":"static_response"}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}},"srv1":{"listen":[":8080"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"nextcloud-aio-apache:8080"}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}},"srv2":{"listen":[":8448"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse:8008"}]}],"match":[{"path":["/_matrix/*"]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
caddy  | {"level":"info","ts":1735637894.3218915,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["track.dragonmail.cloud","matrix.dragonmail.cloud","chat.dragonmail.cloud","auth.dragonmail.cloud","firefly.dragonmail.cloud","auth.dragonmail.social","portainer.dragonmail.social","mail.dragonmail.social","srv.dragonmail.cloud","trbl.dragonmail.cloud","dragonmail.social","element.dragonmail.cloud","dragonmail.cloud","nextcloud.dragonmail.cloud"]}
caddy  | Error: loading initial config: loading new config: http app module: start: finalizing automatic HTTPS: managing certificates for [track.dragonmail.cloud matrix.dragonmail.cloud chat.dragonmail.cloud auth.dragonmail.cloud firefly.dragonmail.cloud auth.dragonmail.social portainer.dragonmail.social mail.dragonmail.social srv.dragonmail.cloud trbl.dragonmail.cloud dragonmail.social element.dragonmail.cloud dragonmail.cloud nextcloud.dragonmail.cloud]: automate: manage [track.dragonmail.cloud matrix.dragonmail.cloud chat.dragonmail.cloud auth.dragonmail.cloud firefly.dragonmail.cloud auth.dragonmail.social portainer.dragonmail.social mail.dragonmail.social srv.dragonmail.cloud trbl.dragonmail.cloud dragonmail.social element.dragonmail.cloud dragonmail.cloud nextcloud.dragonmail.cloud]: mail.dragonmail.social: caching certificate: read /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.key: is a directory
caddy  | {"level":"debug","ts":1735637925.866823,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{"subjects":["portainer.dragonmail.social","nextcloud.dragonmail.cloud","element.dragonmail.cloud","firefly.dragonmail.cloud","matrix.dragonmail.cloud","auth.dragonmail.social","mail.dragonmail.social","track.dragonmail.cloud","trbl.dragonmail.cloud","auth.dragonmail.cloud","chat.dragonmail.cloud","srv.dragonmail.cloud","dragonmail.social","dragonmail.cloud"]},{}]}},"http":{"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"portainer:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"static_response","headers":{"Location":["/remote.php/dav/"]},"status_code":301}],"match":[{"path":["/.well-known/carddav"]}]},{"handle":[{"handler":"static_response","headers":{"Location":["/remote.php/dav/"]},"status_code":301}],"match":[{"path":["/.well-known/caldav"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"nextcloud-aio-apache:11000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"deferred":true,"delete":["server"],"set":{"Permissions-Policy":["accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"],"Strict-Transport-Security":["max-age=63072000; includeSubDomains;"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-Robots-Tag":["none"],"X-Xss-Protection":["1"]}}},{"encodings":{"gzip":{},"zstd":{}},"handler":"encode","prefer":["zstd","gzip"]},{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-element:80"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"body":"woah, there are like flies, and they're like....on fire","handler":"static_response"}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"deferred":true,"delete":["server"],"set":{"Access-Control-Allow-Origin":["*"],"Permissions-Policy":["accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"],"Referrer-Policy":["strict-origin-when-cross-origin"],"Strict-Transport-Security":["max-age=63072000; includeSubDomains;"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-Robots-Tag":["none"],"X-Xss-Protection":["1"]}}}]},{"group":"group6","handle":[{"handler":"subroute","routes":[{"group":"group1","handle":[{"handler":"rewrite","uri":"/"}],"match":[{"path":["/synapse-admin/"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse-admin:80"}]}]}]}],"match":[{"path":["/synapse-admin/*"]}]},{"group":"group6","handle":[{"handler":"subroute","routes":[{"group":"group0","handle":[{"handler":"rewrite","uri":"/"}],"match":[{"path":["/synapse-admin"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse-admin:80"}]}]}]}],"match":[{"path":["/synapse-admin"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse:8008"}]}],"match":[{"path":["/_synapse/client/*"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse:8008"}]}],"match":[{"path":["/_matrix/*"]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"authentik:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"stalwart-mail:8080"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"ryot:8000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"portainer:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"authentik:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"deferred":true,"delete":["server"],"set":{"Permissions-Policy":["accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"],"Strict-Transport-Security":["max-age=63072000; includeSubDomains;"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-Robots-Tag":["none"],"X-Xss-Protection":["1"]}}},{"encodings":{"gzip":{},"zstd":{}},"handler":"encode","prefer":["zstd","gzip"]},{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-element:80"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"body":"sticker picker not enabled","handler":"static_response"}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"encodings":{"gzip":{}},"handler":"encode","prefer":["gzip"]},{"body":"dragonmail, yaaaay","handler":"static_response"}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}},"srv1":{"listen":[":8080"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"nextcloud-aio-apache:8080"}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}},"srv2":{"listen":[":8448"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse:8008"}]}],"match":[{"path":["/_matrix/*"]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
caddy  | {"level":"info","ts":1735637925.8812406,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["element.dragonmail.cloud","track.dragonmail.cloud","srv.dragonmail.cloud","portainer.dragonmail.social","matrix.dragonmail.cloud","nextcloud.dragonmail.cloud","auth.dragonmail.social","firefly.dragonmail.cloud","trbl.dragonmail.cloud","chat.dragonmail.cloud","dragonmail.social","mail.dragonmail.social","auth.dragonmail.cloud","dragonmail.cloud"]}
caddy  | {"level":"debug","ts":1735637925.886009,"logger":"tls","msg":"loading managed certificate","domain":"mail.dragonmail.social","expiration":1738800000,"issuer_key":"acme.zerossl.com-v2-DV90","storage":"FileStorage:/data/caddy"}
caddy  | {"level":"debug","ts":1735637925.8861198,"logger":"tls.cache","msg":"added certificate to cache","subjects":["mail.dragonmail.social"],"expiration":1738800000,"managed":true,"issuer_key":"acme.zerossl.com-v2-DV90","hash":"48d4b91beedb8581226c2d7f76daa8397475942dd06863ed7f4eea1725143200","cache_size":12,"cache_capacity":10000}
caddy  | {"level":"debug","ts":1735637925.8861349,"logger":"events","msg":"event","name":"cached_managed_cert","id":"d6000df2-e45c-4f17-967d-3c21629a0fd3","origin":"tls","data":{"sans":["mail.dragonmail.social"]}}
caddy  | {"level":"debug","ts":1735637932.007794,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{"subjects":["portainer.dragonmail.social","nextcloud.dragonmail.cloud","element.dragonmail.cloud","firefly.dragonmail.cloud","matrix.dragonmail.cloud","auth.dragonmail.social","mail.dragonmail.social","track.dragonmail.cloud","trbl.dragonmail.cloud","auth.dragonmail.cloud","chat.dragonmail.cloud","srv.dragonmail.cloud","dragonmail.social","dragonmail.cloud"]},{}]}},"http":{"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"portainer:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"static_response","headers":{"Location":["/remote.php/dav/"]},"status_code":301}],"match":[{"path":["/.well-known/carddav"]}]},{"handle":[{"handler":"static_response","headers":{"Location":["/remote.php/dav/"]},"status_code":301}],"match":[{"path":["/.well-known/caldav"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"nextcloud-aio-apache:11000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"deferred":true,"delete":["server"],"set":{"Permissions-Policy":["accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"],"Strict-Transport-Security":["max-age=63072000; includeSubDomains;"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-Robots-Tag":["none"],"X-Xss-Protection":["1"]}}},{"encodings":{"gzip":{},"zstd":{}},"handler":"encode","prefer":["zstd","gzip"]},{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-element:80"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"body":"woah, there are like flies, and they're like....on fire","handler":"static_response"}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"deferred":true,"delete":["server"],"set":{"Access-Control-Allow-Origin":["*"],"Permissions-Policy":["accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"],"Referrer-Policy":["strict-origin-when-cross-origin"],"Strict-Transport-Security":["max-age=63072000; includeSubDomains;"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-Robots-Tag":["none"],"X-Xss-Protection":["1"]}}}]},{"group":"group6","handle":[{"handler":"subroute","routes":[{"group":"group1","handle":[{"handler":"rewrite","uri":"/"}],"match":[{"path":["/synapse-admin/"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse-admin:80"}]}]}]}],"match":[{"path":["/synapse-admin/*"]}]},{"group":"group6","handle":[{"handler":"subroute","routes":[{"group":"group0","handle":[{"handler":"rewrite","uri":"/"}],"match":[{"path":["/synapse-admin"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse-admin:80"}]}]}]}],"match":[{"path":["/synapse-admin"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse:8008"}]}],"match":[{"path":["/_synapse/client/*"]}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse:8008"}]}],"match":[{"path":["/_matrix/*"]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"authentik:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"stalwart-mail:8080"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"ryot:8000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"portainer:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"authentik:9000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"deferred":true,"delete":["server"],"set":{"Permissions-Policy":["accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"],"Strict-Transport-Security":["max-age=63072000; includeSubDomains;"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-Robots-Tag":["none"],"X-Xss-Protection":["1"]}}},{"encodings":{"gzip":{},"zstd":{}},"handler":"encode","prefer":["zstd","gzip"]},{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-element:80"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"body":"sticker picker not enabled","handler":"static_response"}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"encodings":{"gzip":{}},"handler":"encode","prefer":["gzip"]},{"body":"dragonmail, yaaaay","handler":"static_response"}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}},"srv1":{"listen":[":8080"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"nextcloud-aio-apache:8080"}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}},"srv2":{"listen":[":8448"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"matrix-synapse:8008"}]}],"match":[{"path":["/_matrix/*"]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
caddy  | {"level":"info","ts":1735637932.0101542,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["mail.dragonmail.social","dragonmail.cloud","trbl.dragonmail.cloud","firefly.dragonmail.cloud","chat.dragonmail.cloud","nextcloud.dragonmail.cloud","element.dragonmail.cloud","matrix.dragonmail.cloud","portainer.dragonmail.social","srv.dragonmail.cloud","dragonmail.social","auth.dragonmail.social","track.dragonmail.cloud","auth.dragonmail.cloud"]}
caddy  | {"level":"debug","ts":1735637932.0103917,"logger":"tls","msg":"loading managed certificate","domain":"mail.dragonmail.social","expiration":1738800000,"issuer_key":"acme.zerossl.com-v2-DV90","storage":"FileStorage:/data/caddy"}
caddy  | {"level":"debug","ts":1735637932.010583,"logger":"tls.cache","msg":"added certificate to cache","subjects":["mail.dragonmail.social"],"expiration":1738800000,"managed":true,"issuer_key":"acme.zerossl.com-v2-DV90","hash":"48d4b91beedb8581226c2d7f76daa8397475942dd06863ed7f4eea1725143200","cache_size":1,"cache_capacity":10000}
caddy  | {"level":"debug","ts":1735637932.0106018,"logger":"events","msg":"event","name":"cached_managed_cert","id":"b6b580db-91da-4dac-8940-4b93392970ac","origin":"tls","data":{"sans":["mail.dragonmail.social"]}}
caddy  | {"level":"debug","ts":1735639698.6886683,"logger":"events","msg":"event","name":"tls_get_certificate","id":"b5fda0cf-d513-46e6-8a41-f5324b43b505","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4867,4866,49195,49199,52393,52392,49196,49200,49162,49161,49171,49172,156,157,47,53],"ServerName":"mail.dragonmail.social","SupportedCurves":[4588,29,23,24,25,256,257],"SupportedPoints":"AA==","SignatureSchemes":[1027,1283,1539,2052,2053,2054,1025,1281,1537,515,513],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"216.232.245.52","Port":37748,"Zone":""},"LocalAddr":{"IP":"172.19.0.5","Port":443,"Zone":""}}}}
caddy  | {"level":"debug","ts":1735639698.688689,"logger":"tls.handshake","msg":"choosing certificate","identifier":"mail.dragonmail.social","num_choices":1}
caddy  | {"level":"debug","ts":1735639698.6886992,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"mail.dragonmail.social","subjects":["mail.dragonmail.social"],"managed":true,"issuer_key":"acme.zerossl.com-v2-DV90","hash":"48d4b91beedb8581226c2d7f76daa8397475942dd06863ed7f4eea1725143200"}
caddy  | {"level":"debug","ts":1735639698.6887028,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"216.232.245.52","remote_port":"37748","subjects":["mail.dragonmail.social"],"managed":true,"expiration":1738800000,"hash":"48d4b91beedb8581226c2d7f76daa8397475942dd06863ed7f4eea1725143200"}
caddy  | {"level":"debug","ts":1735639698.6945336,"logger":"events","msg":"event","name":"tls_get_certificate","id":"d5647424-f846-47cb-9d95-4fbfb9a8b0fc","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4867,4866,49195,49199,52393,52392,49196,49200,49162,49161,49171,49172,156,157,47,53],"ServerName":"mail.dragonmail.social","SupportedCurves":[4588,29,23,24,25,256,257],"SupportedPoints":"AA==","SignatureSchemes":[1027,1283,1539,2052,2053,2054,1025,1281,1537,515,513],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"216.232.245.52","Port":37750,"Zone":""},"LocalAddr":{"IP":"172.19.0.5","Port":443,"Zone":""}}}}
caddy  | {"level":"debug","ts":1735639698.6945462,"logger":"tls.handshake","msg":"choosing certificate","identifier":"mail.dragonmail.social","num_choices":1}
caddy  | {"level":"debug","ts":1735639698.6945536,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"mail.dragonmail.social","subjects":["mail.dragonmail.social"],"managed":true,"issuer_key":"acme.zerossl.com-v2-DV90","hash":"48d4b91beedb8581226c2d7f76daa8397475942dd06863ed7f4eea1725143200"}
caddy  | {"level":"debug","ts":1735639698.694558,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"216.232.245.52","remote_port":"37750","subjects":["mail.dragonmail.social"],"managed":true,"expiration":1738800000,"hash":"48d4b91beedb8581226c2d7f76daa8397475942dd06863ed7f4eea1725143200"}
caddy  | {"level":"debug","ts":1735639702.0045316,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"stalwart-mail:8080","duration":3.30249475,"request":{"remote_ip":"216.232.245.52","remote_port":"37748","client_ip":"216.232.245.52","proto":"HTTP/2.0","method":"POST","host":"mail.dragonmail.social","uri":"/api/oauth","headers":{"Referer":["https://mail.dragonmail.social/"],"X-Forwarded-For":["216.232.245.52"],"X-Forwarded-Host":["mail.dragonmail.social"],"Accept-Language":["en-US,en;q=0.5"],"Priority":["u=0"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0"],"Authorization":["REDACTED"],"Sec-Fetch-Mode":["cors"],"Sec-Gpc":["1"],"Accept":["*/*"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Content-Length":["58"],"Sec-Fetch-Dest":["empty"],"Sec-Fetch-Site":["same-origin"],"Content-Type":["text/plain;charset=UTF-8"],"Origin":["https://mail.dragonmail.social"],"Te":["trailers"],"X-Forwarded-Proto":["https"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mail.dragonmail.social"}},"headers":{"Content-Type":["application/json; charset=utf-8"],"Content-Length":["3440"],"Date":["Tue, 31 Dec 2024 10:08:21 GMT"]},"status":200}
caddy  | {"level":"debug","ts":1735639722.9986265,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"stalwart-mail:8080","duration":1.517413918,"request":{"remote_ip":"216.232.245.52","remote_port":"37748","client_ip":"216.232.245.52","proto":"HTTP/2.0","method":"POST","host":"mail.dragonmail.social","uri":"/api/oauth","headers":{"Sec-Fetch-Dest":["empty"],"Origin":["https://mail.dragonmail.social"],"Sec-Fetch-Mode":["cors"],"X-Forwarded-Host":["mail.dragonmail.social"],"Content-Type":["text/plain;charset=UTF-8"],"Content-Length":["58"],"X-Forwarded-For":["216.232.245.52"],"X-Forwarded-Proto":["https"],"Sec-Gpc":["1"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0"],"Authorization":["REDACTED"],"Sec-Fetch-Site":["same-origin"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Accept":["*/*"],"Priority":["u=0"],"Accept-Language":["en-US,en;q=0.5"],"Referer":["https://mail.dragonmail.social/"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mail.dragonmail.social"}},"headers":{"Content-Length":["1837"],"Date":["Tue, 31 Dec 2024 10:08:42 GMT"],"Content-Type":["application/json; charset=utf-8"]},"status":200}
caddy  | {"level":"debug","ts":1735639723.0208046,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"stalwart-mail:8080","duration":0.003032554,"request":{"remote_ip":"216.232.245.52","remote_port":"37748","client_ip":"216.232.245.52","proto":"HTTP/2.0","method":"POST","host":"mail.dragonmail.social","uri":"/auth/token","headers":{"X-Forwarded-Proto":["https"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0"],"Accept":["*/*"],"X-Forwarded-Host":["mail.dragonmail.social"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Sec-Fetch-Mode":["cors"],"Te":["trailers"],"Referer":["https://mail.dragonmail.social/"],"X-Forwarded-For":["216.232.245.52"],"Origin":["https://mail.dragonmail.social"],"Content-Length":["108"],"Priority":["u=4"],"Accept-Language":["en-US,en;q=0.5"],"Sec-Gpc":["1"],"Sec-Fetch-Dest":["empty"],"Content-Type":["text/plain;charset=UTF-8"],"Sec-Fetch-Site":["same-origin"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mail.dragonmail.social"}},"headers":{"Content-Type":["application/problem+json"],"Content-Length":["101"],"Date":["Tue, 31 Dec 2024 10:08:42 GMT"]},"status":401}
caddy  | {"level":"debug","ts":1735639730.3962584,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"stalwart-mail:8080","duration":0.001131157,"request":{"remote_ip":"216.232.245.52","remote_port":"37748","client_ip":"216.232.245.52","proto":"HTTP/2.0","method":"POST","host":"mail.dragonmail.social","uri":"/api/oauth","headers":{"Origin":["https://mail.dragonmail.social"],"Accept-Encoding":["gzip, deflate, br, zstd"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["mail.dragonmail.social"],"Accept":["*/*"],"Authorization":["REDACTED"],"Sec-Fetch-Dest":["empty"],"X-Forwarded-For":["216.232.245.52"],"Referer":["https://mail.dragonmail.social/"],"Content-Type":["text/plain;charset=UTF-8"],"Sec-Fetch-Mode":["cors"],"Content-Length":["58"],"Sec-Gpc":["1"],"Sec-Fetch-Site":["same-origin"],"Accept-Language":["en-US,en;q=0.5"],"Priority":["u=0"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mail.dragonmail.social"}},"headers":{"Content-Type":["application/json; charset=utf-8"],"Content-Length":["3440"],"Date":["Tue, 31 Dec 2024 10:08:50 GMT"]},"status":200}
caddy  | {"level":"debug","ts":1735639765.2497106,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"stalwart-mail:8080","duration":0.000641123,"request":{"remote_ip":"216.232.245.52","remote_port":"37748","client_ip":"216.232.245.52","proto":"HTTP/2.0","method":"POST","host":"mail.dragonmail.social","uri":"/api/oauth","headers":{"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0"],"Origin":["https://mail.dragonmail.social"],"X-Forwarded-For":["216.232.245.52"],"X-Forwarded-Proto":["https"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Content-Type":["text/plain;charset=UTF-8"],"Content-Length":["58"],"Sec-Gpc":["1"],"Accept":["*/*"],"Authorization":["REDACTED"],"X-Forwarded-Host":["mail.dragonmail.social"],"Sec-Fetch-Dest":["empty"],"Sec-Fetch-Mode":["cors"],"Te":["trailers"],"Accept-Language":["en-US,en;q=0.5"],"Referer":["https://mail.dragonmail.social/"],"Sec-Fetch-Site":["same-origin"],"Priority":["u=0"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mail.dragonmail.social"}},"headers":{"Content-Type":["application/json; charset=utf-8"],"Content-Length":["3440"],"Date":["Tue, 31 Dec 2024 10:09:25 GMT"]},"status":200}
caddy  | {"level":"debug","ts":1735639829.9917073,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"stalwart-mail:8080","duration":0.000865706,"request":{"remote_ip":"216.232.245.52","remote_port":"37748","client_ip":"216.232.245.52","proto":"HTTP/2.0","method":"POST","host":"mail.dragonmail.social","uri":"/api/oauth","headers":{"Content-Type":["text/plain;charset=UTF-8"],"Sec-Fetch-Dest":["empty"],"Sec-Fetch-Site":["same-origin"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Origin":["https://mail.dragonmail.social"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["mail.dragonmail.social"],"Accept":["*/*"],"Referer":["https://mail.dragonmail.social/"],"Te":["trailers"],"Content-Length":["58"],"X-Forwarded-For":["216.232.245.52"],"Sec-Gpc":["1"],"Accept-Language":["en-US,en;q=0.5"],"Sec-Fetch-Mode":["cors"],"Authorization":["REDACTED"],"Priority":["u=0"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mail.dragonmail.social"}},"headers":{"Date":["Tue, 31 Dec 2024 10:10:29 GMT"],"Content-Type":["application/json; charset=utf-8"],"Content-Length":["3440"]},"status":200}

3. Caddy version:

Caddy v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=
I build caddy this way because I followed a tutorial that said if you want to get certificates, you need to build with the correct plugins:

4. How I installed and ran Caddy:

a. System environment:

b. Command:

---
name: "dragonmail"
networks:
  dragonio:
    name: 'dragonio'
    driver: 'bridge'
    external: true
  matrix_net:
    name: 'matrix_net'
    driver: 'bridge'
    external: true
  firefly:
    name: 'firefly'
    driver: 'bridge'
    external: true
#  wger_net:
#    name: 'wger_net'
#    driver: 'bridge'
#    external: true


volumes:
  nextcloud_aio_mastercontainer:
    name: 'nextcloud_aio_mastercontainer'
    external: true
  nextcloud_aio_nextcloud_data:
    name: 'nextcloud_aio_nextcloud_data'
    external: true
  nextcloud_aio_backupdir:
    name: 'nextcloud_aio_backupdir'
    external: true


services:
  caddy:
    #image: caddy:2.8.4
    container_name: caddy
    build: ./dockerfile-caddy
    #  context: .
    #  dockerfile: Dockerfile
    image: deeweb:latest
    ports:
      - 80:80
      - 443:443
      - 443:443/udp
    volumes:
      - /media/configs/caddy/Caddyfile:/etc/caddy/Caddyfile
      - /media/configs/caddy/config:/config
      - /media/configs/caddy/data:/data
      - /media/configs/caddy/site:/srv
    environment:
      PUID: '1000'
      PGID: '1000'
      TZ: 'America/vancouver'
      LINODE_TOKEN: ****
    networks:
      dragonio:
        aliases: []
    # depends_on:
    # - portainer
  ############################################################################################
  postgresql:
    image: docker.io/library/postgres:16-alpine
    container_name: postgressql
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 5s
    volumes:
      - /media/configs/authentik/database:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: ${PG_PASS:?database password required}
      POSTGRES_USER: ${PG_USER:-authentik}
      POSTGRES_DB: ${PG_DB:-authentik}
    env_file:
      - .env
    networks:
      dragonio:
        #ipv4_address: 10.10.10.2
        aliases: []
    depends_on:
     - caddy
  ############################################################################################
  redis:
    image: docker.io/library/redis:alpine
    command: --save 60 1 --loglevel warning
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 3s
    volumes:
      - /media/configs/authentik/redis:/data
    networks:
      dragonio:
        aliases: []
    depends_on:
     - caddy
  ############################################################################################
  authentik:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.1}
    container_name: authentik
    restart: unless-stopped
    command: server
    environment:
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
      AUTHENTIK_EMAIL__HOST: mail.dragonmail.social
      AUTHENTIK_EMAIL__PORT: 587
      AUTHENTIK_EMAIL__USERNAME: *****
      AUTHENTIK_EMAIL__PASSWORD: *****
      AUTHENTIK_EMAIL__USE_TLS: true
      AUTHENTIK_EMAIL__FROM: *****
    volumes:
      - /media/configs/authentik/media:/media
      - /media/configs/authentik/custom-templates:/templates
      - /media/configs/authentik/web_customizations/logo2.svg:/web/dist/assets/icons/dragonmaillogo.svg
      - /media/configs/authentik/web_customizations/icon.ico:/web/dist/assets/icons/dragonmailicon.ico
      - /media/configs/caddy/data/caddy/certificates/acme.zerossl.com-v2-dv90:/certs/caddy
    env_file:
      - .env
    expose:
      - 9000
      - 9443
    # ports:
    #   - 85:9000
    #   - 9445:9443
    # #  - "${COMPOSE_PORT_HTTP:-9000}:9000"
    # #  - "${COMPOSE_PORT_HTTPS:-9443}:9443"
    depends_on:
      - postgresql
      - redis
      - caddy
    networks:
      dragonio:
        aliases: []
  ############################################################################################
  worker:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.1}
    restart: unless-stopped
    command: worker
    environment:
      COMPOSE_PORT_HTTP: 80
      COMPOSE_PORT_HTTPS: 443
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
      AUTHENTIK_EMAIL__HOST: mail.dragonmail.social
      AUTHENTIK_EMAIL__PORT: 587
      AUTHENTIK_EMAIL__USERNAME: *****
      AUTHENTIK_EMAIL__PASSWORD: *****
      AUTHENTIK_EMAIL__USE_TLS: true
      AUTHENTIK_EMAIL__FROM: *****
    user: root
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /media/configs/authentik/media:/media
      - /media/configs/authentik/certs:/certs
      - /media/configs/authentik/custom-templates:/templates
      - /media/configs/authentik/web_customizations/logo2.svg:/web/dist/assets/icons/dragonmaillogo.svg
      - /media/configs/authentik/web_customizations/icon.ico:/web/dist/assets/icons/dragonmailicon.ico
      - /media/configs/authentik/web_customizations/mail-dragonite_4x.png:/web/dist/assets/icons/icon_left_brand.png
    env_file:
      - .env
    depends_on:
      - postgresql
      - redis
      - caddy
    networks:
      dragonio:
        aliases: []
   ###########################################################################################
  portainer:
    container_name: 'portainer'
    image: 'portainer/portainer-ce:latest'
    restart: 'always'
    networks:
      dragonio:
        aliases: []
    ports:
      - 9447:9443
    #   #- 7000:9000
    volumes:
      - '/media/configs/portainer/_data:/data'
      - '/var/run/docker.sock:/var/run/docker.sock'
  ##########################################################################################
  stalwart-mail:
    container_name: 'stalwart-mail'
    image: 'stalwartlabs/mail-server:latest'
    restart: 'unless-stopped'
    networks:
      dragonio:
        aliases: []
        #ipv4_address: 172.19.0.65
    expose:
      - 443
      - 8080
      - 25
      - 587
      - 465
      - 143
      - 993
      - 4190
      - 110
      - 995
    ports:
    #  - 8080:8080
    #  - 8443:443 # 443 is critical for web admin, jmap, rest, and oauth
      - 25:25 # smtp - receiving incoming emails from other mail servers. 
      - 587:587 # smtp submission with starttls. Prefer 465 with implicit tls
      - 465:465 # smtps - smtp with implicit tls
      - 143:143 # imap4
      - 993:993 #imaps - imap4 with tls
      - 4190:4190 #seive scripts
    #  - 110:110 #pop3
    #  - 995:995 #pop3 tls secure
    volumes:
      - '/media/mail_storage/stalwart_mail:/opt/stalwart-mail'
      - '/media/configs/caddy/data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.crt:/certs/mail.dragonmail.social.crt'
      - '/media/configs/caddy/data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.dragonmail.social/mail.dragonmail.social.key:/certs/mail.dragonmail.social.key'
    environment:
      PUID: '1000'
      PGID: '1000'
      TZ: 'America/Vancouver'
  ###########################################################################################
  nextcloud-aio-mastercontainer:
    container_name: 'nextcloud-aio-mastercontainer'
    image: 'nextcloud/all-in-one:latest'
    init: true
    restart: 'unless-stopped'
    networks:
      dragonio:
        aliases: []
    environment:
      APACHE_PORT: 11000
      APACHE_IP_BINDING: 0.0.0.0
      # SKIP_DOMAIN_VALIDATION: true
      TALK_PORT: 3478
      BORG_RETENTION_POLICY: --keep-within=7d --keep-weekly=4 --save-space
    #  NEXTCLOUD_TRUSTED_CACERTS_DIR: /certs
    ports:
      - 8080:8080
    volumes:
      - 'nextcloud_aio_mastercontainer:/mnt/docker-aio-config'
      - 'nextcloud_aio_nextcloud_data:/mnt/docker_nextcloud_data'
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
      - 'nextcloud_aio_backupdir:/root/nextcloud_backups/borg'
    depends_on:
      - caddy
      - authentik
    ###########################################################################################
  matrix-synapse:
    container_name: 'matrix-synapse'
    image: 'matrixdotorg/synapse:latest'
    init: true
    restart: 'unless-stopped'
    pull_policy: always
    networks:
      matrix_net:
        aliases: []
        ipv4_address: 10.10.10.4
      dragonio:
        aliases: []
    environment:
      SYNAPSE_SERVER_NAME: 'matrix.dragonmail.cloud'
      SYNAPSE_REPORT_STATS: 'yes'
      allow_unsafe_locale: true
    volumes:
      - '/media/matrix/synapse:/data'
    ports:
      - 8008:8008
    depends_on:
     - matrix-postgres
     - caddy
     - authentik
  ###########################################################################################
  matrix-element:
    container_name: 'matrix-element'
    image: 'vectorim/element-web:latest'
    restart: 'unless-stopped'
    #pull_policy: always
    volumes:
      - '/media/matrix/element/element-config.json:/app/config.json'
    #ports:
    #  - 8180:80
    networks:
      dragonio:
        aliases: []
      matrix_net:
        ipv4_address: 10.10.10.3
        aliases: []
    depends_on:
      - matrix-synapse
      - matrix-postgres
      - caddy
  ###########################################################################################
  matrix-postgres:
    #image: 'docker.io/library/postgres:16-alpine'
    image: 'postgres:14'
    container_name: 'matrix-postgres'
    restart: 'unless-stopped'
    #pull_policy: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 5s
    volumes:
      - '/media/matrix/database:/var/lib/postgresql/data'
    environment:
      POSTGRES_PASSWORD: ${PG_PASS:?database password required}
      POSTGRES_USER: 'synapse'
      POSTGRES_DB: 'synapse'
      allow_unsafe_locale: true
    env_file:
      - .env
    networks:
      matrix_net:
        ipv4_address: 10.10.10.2
        aliases: []
  ###########################################################################################
  matrix-synapse-admin:
    container_name: matrix-synapse-admin
    hostname: matrix-synapse-admin
    image: awesometechnologies/synapse-admin:latest
    ports:
      - "8195:80"
    restart: unless-stopped
    networks:
      matrix_net:
        aliases: []
      dragonio:
        aliases: []
    depends_on:
     - caddy
 ###########################################################################################
  ryot:
    image: ghcr.io/ignisda/ryot:latest
    env_file:
      - ./ryot/env.env
    environment:
      DATABASE_URL: postgres://postgres:postgres@ryot-db:5432/postgres
      FRONTEND_URL: https://track.dragonmail.cloud
      SERVER_OIDC_ISSUER_URL: https://auth.dragonmail.cloud/application/o/ryot/
      FRONTEND_OIDC_BUTTON_LABEL: "Login with Dragonmail"
      USERS_ALLOW_REGISTRATION: true
      USERS_DISABLE_LOCAL_AUTH: true
      TZ: America/Vancouver
    container_name: ryot
    pull_policy: always
    volumes:
      - /media/configs/ryot/icon.ico:/var/www/favicon.ico
      - /media/configs/ryot/icon.png:/var/www/apple-touch-icon.png
    #ports:
    ##  - 3000:3000
    #  - 8000:8000
    restart: unless-stopped
    networks:
      dragonio:
        aliases: []
    depends_on:
     - caddy
###########################################################################################
  ryot-db:
    image: postgres:16-alpine
    env_file:
      - ./ryot/env.env
    container_name: ryot-db
    restart: unless-stopped
    volumes:
      - /media/nextcloud/ryot_db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
      POSTGRES_DB: postgres
    networks:
      dragonio:
        aliases: []
###########################################################################################
  firefly-core:
    image: fireflyiii/core:latest
    hostname: app
    container_name: firefly-core
    restart: always
    volumes:
      - /media/nextcloud/firefly/core_upload:/var/www/html/storage/upload
    env_file: ./firefly/.env
    networks:
      - dragonio
      - firefly
    ports:
      - 8095:8080
    depends_on:
      - firefly-db
      - caddy
      - authentik
#######################################################
  firefly-db:
    image: mariadb:lts
    hostname: db
    container_name: firefly-db
    restart: always
    #env_file: ./firefly/.db.env
    env_file: ./firefly/.db.env
    networks:
      - firefly
    volumes:
      - /media/nextcloud/firefly/db:/var/lib/mysql
#######################################################
  firefly-cron:
    image: alpine
    restart: always
    container_name: firefly-cron
    command: sh -c "echo \"0 3 * * * wget -qO- http://app:8080/api/v1/cron/*****;echo\" | crontab - && crond -f -L /dev/stdout"
    networks:
      - firefly
#######################################################
#  firefly-importer:
#    image: fireflyiii/data-importer:latest
#    hostname: importer
#    restart: always
#    container_name: firefly_importer
#    networks:
#      - firefly
#    ports:
#      - '8096:8080'
#    depends_on:
#      - firefly-core
#      - caddy
#    env_file: ./firefly/.importer.env
###########################################################################################

c. Service/unit/compose file:

FROM caddy:2.8.4-builder AS builder

RUN xcaddy build \
    --with github.com/caddy-dns/linode \
    --with github.com/caddy-dns/godaddy

FROM caddy:2.8.4

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

d. My complete Caddy config:

dragonmail:/media/configs$ cat caddy/Caddyfile

{
  #admin :2019
  email *****
  acme_dns linode {env.LINODE_TOKEN}
  debug
}

#(matrix-well-known-header) {
#  header {
#    Access-Control-Allow-Origin "*"
#    Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
#    Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
#    Content-Type "application/json"
#  }
#}

#(matrix) {
#  handle /.well-known/matrix/server {
#    import matrix-well-known-header
#    respond `{"m.server":"matrix.dragonmail.cloud"}`
#  }
#  handle /.well-known/matrix/client {
#    import matrix-well-known-header
#    respond `{"m.homeserver":{"base_url":"https://chat.dragonmail.cloud"}}`
#  }
#}



dragonmail.social {
  respond "dragonmail test works, yaaaay! It lives!"
  encode gzip
  #tls {
  #  #email *****
  #  #acme_dns linode {env.LINODE_TOKEN}
  #  dns linode {env.LINODE_TOKEN}
  #}
}

#dragonmail.cloud {
#    handle /.well-known/matrix/server {
#        import matrix-well-known-header
#        respond `{"m.server":"matrix.dragonmail.cloud:443"}`
#    }
#
#    handle /.well-known/matrix/client {
#        import matrix-well-known-header
#        respond `{"m.homeserver":{"base_url":"https://matrix.dragonmail.cloud"}}`
#    }
#
#}

portainer.dragonmail.social {
  reverse_proxy http://portainer:9000
}

trbl.dragonmail.cloud {
  reverse_proxy http://portainer:9000
}

auth.dragonmail.social {
  reverse_proxy http://authentik:9000
}

auth.dragonmail.cloud {
  #reverse_proxy http://authentik:9000
  reverse_proxy authentik:9000
}

mail.dragonmail.social {
  reverse_proxy http://stalwart-mail:8080
}

https://nextcloud.dragonmail.cloud:443 {
  redir /.well-known/carddav /remote.php/dav/ 301
  redir /.well-known/caldav /remote.php/dav/ 301
  reverse_proxy nextcloud-aio-apache:11000
}

nextcloud.dragonmail.cloud:8080 {
  #redir /.well-known/carddav /remote.php/dav/ 301
  #redir /.well-known/caldav /remote.php/dav/ 301
  reverse_proxy nextcloud-aio-apache:8080
}

#vault.dragonmail.cloud {
#  respond "Not setup yet"
#  #reverse_proxy http://vaultwarden
#}

matrix.dragonmail.cloud {
  #@matrix {
  #  path /_matrix/* /_synapse/client/*
  #}
#
#    handle /.well-known/matrix/server {
#        #import matrix-well-known-header
#        respond `{"m.server":"matrix.dragonmail.cloud:443"}`
#    }
#
#    handle /.well-known/matrix/client {
#        #import matrix-well-known-header
#        respond `{"m.homeserver":{"base_url":"https://matrix.dragonmail.cloud"}}`
#    }
  
  # new, testing...
  handle /synapse-admin {
      rewrite /synapse-admin /
      reverse_proxy http://matrix-synapse-admin:80
  }
  
  # Why does it only work when I have both /synapse-admin and /synapse-admin/*   ???
  handle /synapse-admin/* {
      rewrite /synapse-admin/ /
      reverse_proxy http://matrix-synapse-admin:80
  }
  
   reverse_proxy /_matrix/* matrix-synapse:8008
   reverse_proxy /_synapse/client/* matrix-synapse:8008

  header {
      X-Content-Type-Options nosniff
      Referrer-Policy strict-origin-when-cross-origin
      Access-Control-Allow-Origin "*"
      Strict-Transport-Security "max-age=63072000; includeSubDomains;"
      Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"
      X-Frame-Options SAMEORIGIN
      X-XSS-Protection 1
      X-Robots-Tag none
      -server
  }
}

dragonmail.cloud:8448 {
  reverse_proxy /_matrix/* matrix-synapse:8008
}

element.dragonmail.cloud {
  encode zstd gzip
  #reverse_proxy element:80
  #reverse_proxy 10.10.10.3:80
  reverse_proxy matrix-element:80
  #reverse_proxy 192.168.3.50:8090

  header {
    X-Content-Type-Options nosniff
    Strict-Transport-Security "max-age=63072000; includeSubDomains;"
    Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"
    X-Frame-Options SAMEORIGIN
    X-XSS-Protection 1
    X-Robots-Tag none
    -server
  }
}

chat.dragonmail.cloud {
  encode zstd gzip
  #reverse_proxy element:80
  #reverse_proxy 10.10.10.3:80
  reverse_proxy matrix-element:80
  #reverse_proxy 192.168.3.50:8090

  header {
    X-Content-Type-Options nosniff
    Strict-Transport-Security "max-age=63072000; includeSubDomains;"
    Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"
    X-Frame-Options SAMEORIGIN
    X-XSS-Protection 1
    X-Robots-Tag none
    -server
  }
}


track.dragonmail.cloud {
  reverse_proxy http://ryot:8000
}

# not setup yet. Placeholder.
firefly.dragonmail.cloud {
  respond "woah, there are like flies, and they're like....on fire"
  #reverse_proxy http://firefly-core:8080 {
        #        header_up Host {http.request.host}
        #        #header_up X-Real-IP {http.request.remote}
        #        #header_up X-Forwarded-For {http.request.remote}
        #        #header_up X-Forwarded-Port {http.request.port}
        #        #header_up X-Forwarded-Proto {http.request.scheme}
        #        #header_up Connection {http.request.header.Connection}
        #        #header_up Upgrade {http.request.header.Upgrade}
        #}
}

srv.dragonmail.cloud {
  respond "sticker picker not enabled"
}

5. Links to relevant resources:

It isn’t Caddy creating the directories. It’s this segment in your stalwart_mail service:

Mounting non-existing paths in Docker Compose initializes them as empty directories (StackOverflow explainer), which is why Caddy suddenly finds directories. You’ll need to rewire how you share the certificates. I’ve seen at least 1 user in the forum using events with an exec handler to copy the generated certificates into a known, static location. You may come up with another idea.

1 Like

Ohhh, I see! Thank you very much!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.