Ensure caddy_net exists via require_docker instead of per-service

43 services declare caddy_net as "external: true" in their compose
file, meaning they require it to already exist — but only Caddy's own
compose file actually creates it (authelia.sh was the sole exception,
with its own inline check-and-create). Installing any of the other 42
before Caddy fails outright with "network caddy_net declared as
external, but could not be found."

Adds ensure_caddy_network to lib/common.sh, called from require_docker
(which every install_* function already calls first), so the network
exists regardless of install order without touching each service file.
Removes authelia.sh's now-redundant duplicate of the same check.

Also documents in CLAUDE.md that network_mode: host services (asterisk/
asterisk-do) need host.docker.internal, not localhost, when Caddy
reverse-proxies to them — the fix from the previous commit.
This commit is contained in:
Claude
2026-07-20 04:14:56 +00:00
parent 6c48bdc707
commit b6046b3ca1
3 changed files with 38 additions and 7 deletions
+16
View File
@@ -330,3 +330,19 @@ networks:
```
And read the network name from `.env` using `CADDY_NET=$SITE_CADDY_NET`.
`external: true` means *this* service expects the network to already exist —
it doesn't create it. `require_docker` creates it for you (via
`ensure_caddy_network` in `lib/common.sh`) the first time any service calls
it, so as long as your `install_<name>()` calls `require_docker` before
`docker compose up` (it always should), the network is guaranteed to exist
regardless of whether Caddy itself has been installed yet.
**`network_mode: host` services (e.g. `asterisk`/`asterisk-do`) don't join
`caddy_net` at all** — Caddy reaching them (or anything else on the host
network) needs `host.docker.internal:PORT` in the Caddyfile, not
`localhost:PORT` or a container name. Caddy's own compose file
(`services/caddy.sh`) sets `extra_hosts: host.docker.internal:host-gateway`
so that hostname resolves; `configure_caddy_for_service`'s bare-port upstream
case already does this for you — don't hand-roll `localhost:PORT` in a
Caddy site block.
+20
View File
@@ -164,6 +164,7 @@ require_root() {
require_docker() {
if command -v docker &>/dev/null; then
ensure_caddy_network
return 0
fi
@@ -222,6 +223,25 @@ require_docker() {
local _docker_bin
_docker_bin="$(command -v docker 2>/dev/null || echo /usr/bin/docker)"
log_success "Docker installed ($("$_docker_bin" --version 2>/dev/null))"
ensure_caddy_network
}
# Create the shared caddy_net bridge network if it doesn't exist yet.
# Most services declare it "external: true" in their docker-compose.yml (see
# CLAUDE.md → Caddy network wiring) — meaning THEY require it to already
# exist, and only Caddy's own compose file (services/caddy.sh) actually
# creates it. Installing any caddy_net-dependent service before Caddy would
# otherwise fail outright with "network caddy_net declared as external, but
# could not be found." Called from require_docker so every service gets this
# for free regardless of install order. No-op in DRY_RUN; safe/idempotent
# otherwise — docker network create is a no-op if the network already exists.
ensure_caddy_network() {
[ "$DRY_RUN" = true ] && return 0
local _net="${SITE_CADDY_NET:-caddy_net}"
docker network inspect "$_net" &>/dev/null && return 0
docker network create "$_net" &>/dev/null \
&& log_info "Created Docker network ${_net} (needed by Caddy-fronted services)"
}
# ── SSH client config (~/.ssh/config) Host aliases ────────────────────────────
+2 -7
View File
@@ -387,13 +387,8 @@ AUTHELIA_USERS
chown -R 1000:1000 "$AUTHELIA_DIR/config" "$AUTHELIA_DIR/data"
log_success "Authelia configured at $AUTHELIA_DIR"
# ── Docker network ────────────────────────────────────────────────────────
if ! docker network ls --format '{{.Name}}' | grep -q "^${CADDY_NET}$"; then
docker network create "$CADDY_NET" >/dev/null 2>&1 && echo " ✓ Created docker network ${CADDY_NET}" \
|| echo " ⚠ Failed to create ${CADDY_NET}"
else
echo " ✓ Docker network ${CADDY_NET} already exists"
fi
# $CADDY_NET already exists at this point — require_docker (called at the
# top of this function) creates it via ensure_caddy_network in lib/common.sh.
# ── Caddyfile forward-auth snippet + portal block ────────────────────────
local CADDY_FILE="$DOCKER_DIR/caddy/Caddyfile"