diff --git a/plugins/caddy-vhosts/internal-functions b/plugins/caddy-vhosts/internal-functions index 472a4b684..003ea1d37 100755 --- a/plugins/caddy-vhosts/internal-functions +++ b/plugins/caddy-vhosts/internal-functions @@ -18,10 +18,27 @@ fn-caddy-route-labels() { output="" if [[ -n "$caddy_domains" ]]; then - # Joining the same site declared by the web container so this container's - # handler directives are merged into the existing site block by - # caddy-docker-proxy. - output="--label 'caddy=${caddy_domains}'" + # Mirror web's site-declarator computation in docker-args-process-deploy so + # both containers join the same Caddyfile site block. caddy treats DOMAIN + # and DOMAIN:80 as separate sites - if web declares DOMAIN:80 and we + # declare DOMAIN, caddy-docker-proxy renders two unrelated site blocks + # and the route's handle never sees port-80 traffic. + local letsencrypt_email port_map scheme host_port + local has_443_mapping=false + letsencrypt_email="$(fn-caddy-computed-letsencrypt-email)" + while read -r port_map; do + scheme="$(awk -F ':' '{ print $1 }' <<<"$port_map")" + host_port="$(awk -F ':' '{ print $2 }' <<<"$port_map")" + if [[ "$scheme" == "https" ]] || [[ "$host_port" == "443" ]]; then + has_443_mapping=true + fi + done < <(plugn trigger ports-get "$APP") + + if [[ -n "$letsencrypt_email" ]] && [[ "$has_443_mapping" == "true" ]]; then + output="--label 'caddy=${caddy_domains}'" + else + output="--label 'caddy=${caddy_domains//, /:80, }:80'" + fi fi while IFS='|' read -r route_proc route_port route_path route_strip; do diff --git a/tests/unit/proxy-route-caddy.bats b/tests/unit/proxy-route-caddy.bats index f64f6f412..f9c4ca33f 100644 --- a/tests/unit/proxy-route-caddy.bats +++ b/tests/unit/proxy-route-caddy.bats @@ -42,6 +42,13 @@ teardown() { run /bin/bash -c "docker inspect ${TEST_APP}.api.1 --format '{{json .Config.Labels}}' 2>&1 | jq . 2>/dev/null || docker inspect ${TEST_APP}.api.1 --format '{{json .Config.Labels}}' 2>&1" echo "api labels: $output" + # Also dump the web container's labels so we can compare site declarators + # between web and api - caddy treats DOMAIN and DOMAIN:80 as separate + # sites, and a mismatch keeps caddy-docker-proxy from merging the two + # containers' directives into a single site block. + run /bin/bash -c "docker inspect ${TEST_APP}.web.1 --format '{{json .Config.Labels}}' 2>&1 | jq . 2>/dev/null || docker inspect ${TEST_APP}.web.1 --format '{{json .Config.Labels}}' 2>&1" + echo "web labels: $output" + # Give the daemon a moment to read the new labels. sleep 5