Fall back to a Caddy restart when reload fails (admin API is off)

Confirmed on a real deployment: the template Caddyfile ships with
"admin off" (deliberate — no local API attack surface), which means
`caddy reload` can never work, since it depends on that same admin
endpoint. Every Caddyfile-editing code path was silently failing to
apply changes as a result — `docker logs caddy` showed
"admin endpoint disabled" and the reload command errored, but the
Caddyfile edit itself (which doesn't need the admin API) had already
succeeded, leaving the running config stale until something else
happened to restart the container.

Fixed in the two places that actually matter here: lib/common.sh's
configure_caddy_for_service (used by asterisk.sh and most other
Caddy-fronted services in the full repo) and asterisk-do.sh's own
self-contained Caddy block (both the standalone-bootstrap stub and the
main path). Each now tries the lightweight reload first — harmless,
and still works if a box ever has the admin API enabled — then falls
back to `docker restart caddy` if that fails, rather than leaving an
edited-but-unapplied Caddyfile.

Not fixed: the same duplicated pattern in ~35 other service files that
carry their own standalone-bootstrap copy of this logic. Those only
matter for the rare single-file standalone execution path for each of
those specific services and are unrelated to tonight's actual issue —
out of scope here.

Verified: full regression run on both asterisk.sh and asterisk-do.sh
still completes cleanly end to end.
This commit is contained in:
Claude
2026-07-19 17:43:52 +00:00
parent 4af9cfeae3
commit cb8ff3f4f0
3 changed files with 37 additions and 8 deletions
+12 -2
View File
@@ -512,10 +512,20 @@ CADDY_BLOCK
echo " ✓ Configuration added to Caddyfile"
echo " Reloading Caddy configuration..."
docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile 2>/dev/null || true
# The template Caddyfile ships with "admin off" (security hardening —
# no local API attack surface), so `caddy reload` never works here;
# it depends on that same admin endpoint. Try it anyway in case a
# box has admin enabled, but fall back to a full container restart
# (brief availability gap for everything Caddy fronts, but reliable
# regardless of the admin setting) rather than leaving the change
# sitting unapplied on disk.
if docker exec caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null; then
echo "$SERVICE_NAME is now accessible at: https://$SERVICE_DOMAIN"
elif docker restart caddy &>/dev/null; then
echo " ✓ Caddy restarted to apply changes (reload API is disabled by default)"
echo "$SERVICE_NAME should be accessible at: https://$SERVICE_DOMAIN"
else
echo " ⚠ Failed to reload Caddy. Check: docker logs caddy"
echo " ⚠ Failed to reload or restart Caddy. Check: docker logs caddy"
echo " You can restore from backup: $BACKUP_FILE"
fi
@@ -533,7 +543,7 @@ CADDY_BLOCK
echo " scp $SNIPPET_FILE caddy-host:~/caddy-snippets/"
echo " # then on the Caddy machine:"
echo " cat ~/caddy-snippets/${DEFAULT_SUBDOMAIN}.caddy >> /path/to/Caddyfile"
echo " docker exec caddy caddy reload --config /etc/caddy/Caddyfile"
echo " docker restart caddy # reload API is disabled by default; a restart is what applies it"
echo ""
echo " Or rsync all snippets at once:"
echo " rsync -av $SNIPPET_DIR/ caddy-host:~/caddy-snippets/"
+17 -4
View File
@@ -145,11 +145,17 @@ CBLOCK
printf '%s\n' "$_site_block" >> "$_caddyfile"
log_success "Added $_domain to Caddyfile"
docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile 2>/dev/null || true
# The template Caddyfile ships with "admin off", so `caddy
# reload` (which needs that same admin API) never actually
# works here. Try it anyway, fall back to a restart.
if docker exec caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null; then
log_success "$_name accessible at: https://$_domain"
elif docker restart caddy &>/dev/null; then
log_success "Caddy restarted to apply changes (reload API is disabled by default)"
log_success "$_name should be accessible at: https://$_domain"
else
log_warning "Reload failed — check: docker logs caddy"
log_info "Manual reload: docker exec caddy caddy reload --config /etc/caddy/Caddyfile"
log_warning "Reload/restart failed — check: docker logs caddy"
log_info "Manual fix: docker restart caddy"
fi
else
local _snippet_dir="$DOCKER_DIR/caddy-snippets"
@@ -721,11 +727,18 @@ CADDY_BLOCK
printf '%s\n' "$_SITE_BLOCK" >> "$_CADDYFILE"
log_success "Added ${DOMAIN_NAME} to Caddyfile (backup: $(basename "$_CADDY_BACKUP"))"
docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile 2>/dev/null || true
# The template Caddyfile ships with "admin off", so
# `caddy reload` (which needs that same admin API) never
# actually works here. Try it anyway, fall back to a
# restart — confirmed necessary on a real deployment.
if docker exec caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null; then
log_success "Web admin accessible at: https://${DOMAIN_NAME}"
elif docker restart caddy &>/dev/null; then
log_success "Caddy restarted to apply changes (reload API is disabled by default)"
log_success "Web admin should be accessible at: https://${DOMAIN_NAME}"
else
log_warning "Reload failed — check: docker logs caddy"
log_info "Manual reload: docker exec caddy caddy reload --config /etc/caddy/Caddyfile"
log_warning "Reload/restart failed — check: docker logs caddy"
log_info "Manual fix: docker restart caddy"
fi
fi
else
+8 -2
View File
@@ -143,11 +143,17 @@ CBLOCK
printf '%s\n' "$_site_block" >> "$_caddyfile"
log_success "Added $_domain to Caddyfile"
docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile 2>/dev/null || true
# The template Caddyfile ships with "admin off", so `caddy
# reload` (which needs that same admin API) never actually
# works here. Try it anyway, fall back to a restart.
if docker exec caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null; then
log_success "$_name accessible at: https://$_domain"
elif docker restart caddy &>/dev/null; then
log_success "Caddy restarted to apply changes (reload API is disabled by default)"
log_success "$_name should be accessible at: https://$_domain"
else
log_warning "Reload failed — check: docker logs caddy"
log_info "Manual reload: docker exec caddy caddy reload --config /etc/caddy/Caddyfile"
log_warning "Reload/restart failed — check: docker logs caddy"
log_info "Manual fix: docker restart caddy"
fi
else
local _snippet_dir="$DOCKER_DIR/caddy-snippets"