1. Caddy version (caddy version
):
V2.3.0
2. How I run Caddy:
Docker-compose Caddy2 cluster with shared storage mounted at /etc/caddy
.
a. System environment:
Centos 8 with Docker
b. Command:
caddy run --config /etc/caddy/config/caddy/autosave.json --watch
c. Configuration files:
version: "3.7"
services:
caddy:
container_name: caddy
image: caddy:latest
build:
context: .
dockerfile: ./Dockerfile
restart: unless-stopped
network_mode: host
volumes:
- ./caddy:/etc/caddy
environment:
- XDG_CONFIG_HOME=/etc/caddy/config
- XDG_DATA_HOME=/etc/caddy/data
- PROXY_HOST=127.0.0.1
- PROXY_PORT=8080
- INITIAL_HOSTNAME=mydomain.com
- ADMIN_API_HOST=0.0.0.0
- ADMIN_API_PORT=2019
FROM caddy:alpine
RUN apk add gettext
ADD ./caddy-template.json /opt/caddy/caddy-template.json
ADD ./run.sh /opt/run.sh
CMD /opt/run.sh
caddy-template.json
{"admin":{"listen":"$ADMIN_API_HOST:$ADMIN_API_PORT"},"apps":{"http":{"servers":{"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"$PROXY_HOST:$PROXY_PORT"}]}]}]}],"match":[{"@id":"default","host":["$INITIAL_HOSTNAME"]}],"terminal":true}]}}}}}
run.sh
#!/bin/sh
[ -d /etc/caddy/config/caddy ] || mkdir -p /etc/caddy/config/caddy/
[ -d /etc/caddy/data/caddy ] || mkdir -p /etc/caddy/data/caddy/
if [[ ! -f /etc/caddy/config/caddy/autosave.json ]]; then
envsubst < /opt/caddy/caddy-template.json > /etc/caddy/config/caddy/autosave.json
fi
caddy run --config /etc/caddy/config/caddy/autosave.json --watch
3. The problem I’m having:
There is a race-condition with clustered Caddy nodes when simultaneously modifying multiple configuration requests by admin API. It takes approximately 1 minute for each node to recognise the configuration changes and apply. Caddy2 needs to give time for each node in the cluster to update changes before processing another modification request, else some requests get overridden and do not apply.
One node gets the API call and processes it, while the other node also gets another API call and processes it. Both nodes use --watch and it is a race which node catches the configuration change first and applies to itself, thus overwriting its own processed call.
I get this problem every time by running curl -X PUT -H "Content-Type: application/json" -d '{"@id":"ryan","host":["ryan.fakedomain.com"]}' "http://127.0.0.1:2019/config/apps/http/servers/srv0/routes/0/match/0"
on both nodes simultaneously, but with different hostnames and @id
for each API call of course.