deploy.sh: detect slug/port collisions against the live vhost

Fail fast if another app on optical-dev already claims /utilisation-dept/
in the shared Apache vhost or any sibling /opt/*/deploy/apache-*.conf,
and surface which 8200-8299 ports are already taken by sibling apps so
the port picker's choice is visible. Silently skips on dev laptops where
the vhost file isn't present.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
DJP 2026-05-16 12:55:19 -04:00
parent 04edbfdd2c
commit 4bf53124a8

View file

@ -107,6 +107,33 @@ docker compose version >/dev/null 2>&1 || { err "docker compose v2 required"; ex
[[ -f docker-compose.yml ]] || { err "docker-compose.yml missing"; exit 2; }
[[ -f "$APACHE_TMPL" ]] || { err "$APACHE_TMPL missing"; exit 2; }
# ─── server-side collision check ──────────────────────────────────────────
# Only runs on optical-dev where the shared vhost lives. On dev laptops the
# file won't exist, so this block silently skips.
VHOST=/etc/apache2/sites-enabled/optical-dev.oliver.solutions.conf
if [[ -r "$VHOST" ]]; then
# 1. Slug collision: is another app already claiming /utilisation-dept/?
# Look at the live vhost AND every sibling app's apache-*.conf.
sibling_confs=(/opt/*/deploy/apache-*.conf)
collision=$(grep -lE "(ProxyPass|Alias)[[:space:]]+${URL_PATH}/" \
"$VHOST" "${sibling_confs[@]}" 2>/dev/null \
| grep -v "/opt/${SLUG}/" || true)
if [[ -n "$collision" ]]; then
err "Another app claims ${URL_PATH}/ in:"
echo "$collision" | sed 's/^/ /' >&2
err "Pick a different slug, or remove the conflicting Include line."
exit 6
fi
# 2. Port range usage report: show what's already taken in 8200-8299
# so the operator knows where we sit.
taken_ports=$(grep -hoE 'http://127\.0\.0\.1:82[0-9][0-9]' \
"${sibling_confs[@]}" 2>/dev/null \
| grep -oE '82[0-9][0-9]' | sort -u || true)
if [[ -n "$taken_ports" ]]; then
log "Ports already claimed in 8200-8299 by sibling apps: $(echo $taken_ports | tr '\n' ' ')"
fi
fi
if [[ ! -f "$ENV_FILE" ]]; then
err ".env missing. Copy .env.example to .env and fill in required values (AIRTABLE_PAT, SESSION_SECRET, ADMIN_PASSWORD_BCRYPT) before deploying."
exit 3