1. The problem I’m having:
Full disclosure. Brand new to Caddy - quite new to docker. 40+ years programmer and DBA.
This is a problem involving Caddy but possibly not caused by it. Hoping someone here might offer advice at least.
Asked for help at the NextCloud forums but was told “outside of our scope - go ask the Caddy people” so here I am
We are currently evaluating a product called NextCloud to see if we can adopt it and migrate away from some other products. Wanting to use Docker containers as much as possible, I followed a tutorial here to install the components (NextCloud, Nginx, Redis, Caddy and Mariadb and in five separate containers and everything went (mostly) to plan.
Unfortunately when I started up the containers and tried to access the site I realised that it was not going to work. My browser returns an SSL_ERROR_INTERNAL_ERROR_ALERT. When I look in the Caddy docker log I can see that it is trying to automatically get a cert from acme.zerossl.com which is failing because the machine is on a private network and is not DNS addressable from the outside world. (The reason for this is that this instance of NextCloud will be internal to employees. When they are on the road they reach our internal network via a CloudFlare tunnel and a Warp client).
I read in the docs that Caddy will not try to get an automatic certificate if there is I used an IP address rather than a FQDN so I tried to substitute the internal IP address of 192.168.0.156 for the previous “nc.pfs.lan” but still cannot connect.
I’ve included the full yaml file I am using plus the output of the relevant docker log command.
Grateful for any and all suggestions (well almost any).
Rgds
Nigel.
$ cat docker-compose.yaml
version: "3.8"
services:
caddy:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
container_name: reverse-proxy
ports:
- 80:80
- 443:443
environment:
- CADDY_INGRESS_NETWORKS=nextcloud_network
networks:
- nextcloud_network
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- caddy_data:/data
restart: unless-stopped
web:
image: nginx:alpine
container_name: nextcloud-web
networks:
- nextcloud_network
links:
- nextcloud
labels:
caddy: 192.168.0.156
caddy.reverse_proxy: "{{upstreams}}"
caddy.header: /*
caddy.header.Strict-Transport-Security: '"max-age=15552000;"'
caddy.rewrite_0: /.well-known/carddav /remote.php/dav
caddy.rewrite_1: /.well-known/caldav /remote.php/dav
caddy.rewrite_2: /.well-known/webfinger /index.php/.well-known/webfinger
caddy.rewrite_3: /.well-known/nodeinfo /index.php/.well-known/nodeinfo
volumes:
- nextcloud_data:/data:z,ro
- ./nginx.conf:/etc/nginx/nginx.conf:ro
restart: unless-stopped
db:
image: mariadb:10.11
container_name: mariadb-database
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
networks:
- nextcloud_network
volumes:
- db_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD
- MYSQL_USER
- MYSQL_PASSWORD
- MYSQL_DATABASE
restart: unless-stopped
redis:
image: redis:alpine
container_name: redis-dbcache
networks:
- nextcloud_network
restart: unless-stopped
nextcloud:
image: nextcloud:stable-fpm
container_name: nextcloud-app
networks:
- nextcloud_network
volumes:
- nextcloud_data:/data:z
- ./php-fpm-www.conf:/usr/local/etc/php-fpm.d/www.conf:ro
environment:
- MYSQL_USER
- MYSQL_PASSWORD
- MYSQL_DATABASE
- MYSQL_HOST
- REDIS_HOST
- OVERWRITEPROTOCOL
- OVERWRITEHOST
- TRUSTED_PROXIES
- APACHE_DISABLE_REWRITE_IP
restart: unless-stopped
depends_on:
- caddy
- db
- redis
cron:
image: nextcloud:stable-fpm
container_name: nextcloud-cron
networks:
- nextcloud_network
volumes:
- nextcloud_data:/data:z
entrypoint: /cron.sh
restart: unless-stopped
depends_on:
- db
- redis
networks:
nextcloud_network:
external: true
volumes:
caddy_data: {}
db_data: {}
nextcloud_data: {}
2. Error messages and/or full log output:
$ docker logs reverse-proxy
{"level":"info","ts":1687400511.9819803,"logger":"docker-proxy","msg":"Running caddy proxy server"}
{"level":"info","ts":1687400511.9832118,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1687400511.9836187,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1687400511.983723,"logger":"docker-proxy","msg":"Running caddy proxy controller"}
{"level":"info","ts":1687400511.9890149,"logger":"docker-proxy","msg":"Start","CaddyfilePath":"","LabelPrefix":"caddy","PollingInterval":30,"ProcessCaddyfile":true,"ProxyServiceTasks":true,"IngressNetworks":"[nextcloud_network]","DockerSockets":[""],"DockerCertsPath":[""],"DockerAPIsVersion":[""]}
{"level":"info","ts":1687400511.990484,"logger":"docker-proxy","msg":"Connecting to docker events","DockerSocket":""}
{"level":"info","ts":1687400511.9989831,"logger":"docker-proxy","msg":"IngressNetworksMap","ingres":"map[3547cffe8599f928f017fd6d2ae2ddf75cf92efa6d97d8145cd50ca9fd00078f:true nextcloud_network:true]"}
{"level":"info","ts":1687400512.0153003,"logger":"docker-proxy","msg":"Swarm is available","new":false}
{"level":"info","ts":1687400512.0169148,"logger":"docker-proxy","msg":"New Caddyfile","caddyfile":"# Empty caddyfile"}
{"level":"warn","ts":1687400512.0171936,"logger":"docker-proxy","msg":"Caddyfile to json warning","warn":"[Caddyfile:1: Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies]"}
{"level":"info","ts":1687400512.017205,"logger":"docker-proxy","msg":"New Config JSON","json":"{}"}
{"level":"info","ts":1687400512.0172515,"logger":"docker-proxy","msg":"Sending configuration to","server":"localhost"}
{"level":"info","ts":1687400512.018118,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"55118","headers":{"Accept-Encoding":["gzip"],"Content-Length":["41"],"Content-Type":["application/json"],"User-Agent":["Go-http-client/1.1"]}}
{"level":"info","ts":1687400512.0181642,"msg":"config is unchanged"}
{"level":"info","ts":1687400512.018171,"logger":"admin.api","msg":"load complete"}
{"level":"info","ts":1687400512.018248,"logger":"docker-proxy","msg":"Successfully configured","server":"localhost"}
{"level":"info","ts":1687400512.9820335,"logger":"docker-proxy","msg":"New Caddyfile","caddyfile":"192.168.0.156 {\n\theader /* {\n\t\tStrict-Transport-Security max-age=15552000;\n\t}\n\treverse_proxy 172.18.0.7\n\trewrite /.well-known/caldav /remote.php/dav\n\trewrite /.well-known/carddav /remote.php/dav\n\trewrite /.well-known/nodeinfo /index.php/.well-known/nodeinfo\n\trewrite /.well-known/webfinger /index.php/.well-known/webfinger\n}\n"}
{"level":"info","ts":1687400512.9829779,"logger":"docker-proxy","msg":"New Config JSON","json":"{\"apps\":{\"http\":{\"servers\":{\"srv0\":{\"listen\":[\":443\"],\"routes\":[{\"match\":[{\"host\":[\"192.168.0.156\"]}],\"handle\":[{\"handler\":\"subroute\",\"routes\":[{\"handle\":[{\"handler\":\"headers\",\"response\":{\"set\":{\"Strict-Transport-Security\":[\"max-age=15552000;\"]}}}],\"match\":[{\"path\":[\"/*\"]}]},{\"group\":\"group0\",\"handle\":[{\"handler\":\"rewrite\",\"uri\":\"/index.php/.well-known/webfinger\"}],\"match\":[{\"path\":[\"/.well-known/webfinger\"]}]},{\"group\":\"group0\",\"handle\":[{\"handler\":\"rewrite\",\"uri\":\"/index.php/.well-known/nodeinfo\"}],\"match\":[{\"path\":[\"/.well-known/nodeinfo\"]}]},{\"group\":\"group0\",\"handle\":[{\"handler\":\"rewrite\",\"uri\":\"/remote.php/dav\"}],\"match\":[{\"path\":[\"/.well-known/carddav\"]}]},{\"group\":\"group0\",\"handle\":[{\"handler\":\"rewrite\",\"uri\":\"/remote.php/dav\"}],\"match\":[{\"path\":[\"/.well-known/caldav\"]}]},{\"handle\":[{\"handler\":\"reverse_proxy\",\"upstreams\":[{\"dial\":\"172.18.0.7:80\"}]}]}]}],\"terminal\":true}]}}}}}"}
{"level":"info","ts":1687400512.9830692,"logger":"docker-proxy","msg":"Sending configuration to","server":"localhost"}
{"level":"info","ts":1687400512.9833546,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"55118","headers":{"Accept-Encoding":["gzip"],"Content-Length":["936"],"Content-Type":["application/json"],"User-Agent":["Go-http-client/1.1"]}}
{"level":"info","ts":1687400512.9841971,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1687400512.984468,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1687400512.9846375,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1687400512.9847274,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0000fe7e0"}
{"level":"info","ts":1687400512.9870853,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/data/caddy"}
{"level":"info","ts":1687400512.9886067,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"warn","ts":1687400513.0205412,"logger":"pki.ca.local","msg":"installing root certificate (you might be prompted for password)","path":"storage:pki/authorities/local/root.crt"}
{"level":"info","ts":1687400513.0208957,"msg":"warning: \"certutil\" is not available, install \"certutil\" with \"apt install libnss3-tools\" or \"yum install nss-tools\" and try again"}
{"level":"info","ts":1687400513.0209532,"msg":"define JAVA_HOME environment variable to use the Java trust"}
{"level":"info","ts":1687400513.1081877,"msg":"certificate installed properly in linux trusts"}
{"level":"info","ts":1687400513.1084201,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1687400513.1085315,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Receive-Buffer-Size for details."}
{"level":"info","ts":1687400513.1086173,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1687400513.1086614,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1687400513.1086671,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["192.168.0.156"]}
{"level":"warn","ts":1687400513.1090505,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [192.168.0.156]: no OCSP server specified in certificate","identifiers":["192.168.0.156"]}
{"level":"info","ts":1687400513.1092398,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1687400513.1092494,"logger":"admin.api","msg":"load complete"}
{"level":"info","ts":1687400513.1095586,"logger":"docker-proxy","msg":"Successfully configured","server":"localhost"}
{"level":"info","ts":1687400513.1300268,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"}
3. Caddy version:
$ docker-compose exec caddy caddy version
v2.6.4 h1:2hwYqiRwk1tf3VruhMpLcYTg+11fCdr8S3jhNAdnPy8=
4. How I installed and ran Caddy:
a. System environment:
Via yaml file and docker-compose up
b. Command:
docker-compose up -d
c. Service/unit/compose file:
d. My complete Caddy config:
All in previous yaml file