Validate persisted ports against live host on every deploy
Previously the script only ran port resolution when no compose containers were already running, on the assumption that running containers meant the persisted port was still ours. On the shared optical-dev server that's wrong: another app can grab a port between our deploys, leaving us with a stale .env value that fails to bind. Now find_free_port treats a port as "available for us" if either nothing is listening, or one of our own compose containers is publishing it (so re-deploys don't shuffle). Other-app listeners trigger a re-pick and a warning. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8e969fe015
commit
88e4df59be
1 changed files with 38 additions and 21 deletions
|
|
@ -84,17 +84,35 @@ port_in_use() {
|
|||
[[ -n "$pid" ]]
|
||||
}
|
||||
|
||||
# Echo the compose project name of the docker container publishing $port,
|
||||
# or empty string if no docker container holds it (might be a host process
|
||||
# or a non-published container).
|
||||
port_owner_project() {
|
||||
local port=$1
|
||||
docker ps --format '{{.Label "com.docker.compose.project"}}|{{.Ports}}' 2>/dev/null \
|
||||
| awk -F'|' -v p=":${port}->" '$2 ~ p {print $1; exit}'
|
||||
}
|
||||
|
||||
# True (0) if the port is free for us to bind: either nothing's listening,
|
||||
# or one of our own compose containers is publishing it (recreating the
|
||||
# stack will hand it back to us). Other-process listeners → false.
|
||||
port_available_for_us() {
|
||||
local port=$1
|
||||
if ! port_in_use "$port"; then return 0; fi
|
||||
[[ "$(port_owner_project "$port")" == "$COMPOSE_PROJECT" ]]
|
||||
}
|
||||
|
||||
find_free_port() {
|
||||
local preferred=$1
|
||||
local start=$2
|
||||
local end=$3
|
||||
if ! port_in_use "$preferred"; then
|
||||
if port_available_for_us "$preferred"; then
|
||||
printf '%s' "$preferred"
|
||||
return 0
|
||||
fi
|
||||
local p
|
||||
for ((p=start; p<=end; p++)); do
|
||||
if ! port_in_use "$p"; then
|
||||
if port_available_for_us "$p"; then
|
||||
printf '%s' "$p"
|
||||
return 0
|
||||
fi
|
||||
|
|
@ -162,26 +180,25 @@ PREV_APP_PORT="$APP_PORT"
|
|||
|
||||
log "Resolving host ports (preferred: app=$APP_PORT db=$DB_PORT)…"
|
||||
|
||||
RUNNING=$(docker compose ps -q 2>/dev/null | wc -l | tr -d ' ')
|
||||
if [[ "$RUNNING" -gt 0 ]]; then
|
||||
ok "Project '$COMPOSE_PROJECT' has $RUNNING container(s) running — keeping current port assignment."
|
||||
else
|
||||
NEW_APP_PORT=$(find_free_port "$APP_PORT" 3102 3199) || NEW_APP_PORT=""
|
||||
NEW_DB_PORT=$(find_free_port "$DB_PORT" 5435 5499) || NEW_DB_PORT=""
|
||||
if [[ -z "$NEW_APP_PORT" || -z "$NEW_DB_PORT" ]]; then
|
||||
err "Could not find free ports."
|
||||
err " app desired=$APP_PORT scanned=3102-3199"
|
||||
err " db desired=$DB_PORT scanned=5435-5499"
|
||||
exit 1
|
||||
fi
|
||||
[[ "$NEW_APP_PORT" != "$APP_PORT" ]] && warn "app port $APP_PORT busy → using $NEW_APP_PORT"
|
||||
[[ "$NEW_DB_PORT" != "$DB_PORT" ]] && warn "db port $DB_PORT busy → using $NEW_DB_PORT"
|
||||
APP_PORT=$NEW_APP_PORT
|
||||
DB_PORT=$NEW_DB_PORT
|
||||
set_env_var ADEO_PORT "$APP_PORT"
|
||||
set_env_var ADEO_DB_PORT "$DB_PORT"
|
||||
ok "Ports: app=$APP_PORT db=$DB_PORT (persisted to .env)"
|
||||
# Always validate against live host state. `find_free_port` returns the
|
||||
# preferred port if it's free OR already held by one of our own compose
|
||||
# containers (so re-deploys don't shuffle ports). If another app on the
|
||||
# shared host has grabbed the port, we re-pick.
|
||||
NEW_APP_PORT=$(find_free_port "$APP_PORT" 3102 3199) || NEW_APP_PORT=""
|
||||
NEW_DB_PORT=$(find_free_port "$DB_PORT" 5435 5499) || NEW_DB_PORT=""
|
||||
if [[ -z "$NEW_APP_PORT" || -z "$NEW_DB_PORT" ]]; then
|
||||
err "Could not find free ports."
|
||||
err " app desired=$APP_PORT scanned=3102-3199"
|
||||
err " db desired=$DB_PORT scanned=5435-5499"
|
||||
exit 1
|
||||
fi
|
||||
[[ "$NEW_APP_PORT" != "$APP_PORT" ]] && warn "app port $APP_PORT taken by another app → using $NEW_APP_PORT"
|
||||
[[ "$NEW_DB_PORT" != "$DB_PORT" ]] && warn "db port $DB_PORT taken by another app → using $NEW_DB_PORT"
|
||||
APP_PORT=$NEW_APP_PORT
|
||||
DB_PORT=$NEW_DB_PORT
|
||||
set_env_var ADEO_PORT "$APP_PORT"
|
||||
set_env_var ADEO_DB_PORT "$DB_PORT"
|
||||
ok "Ports: app=$APP_PORT db=$DB_PORT (persisted to .env)"
|
||||
|
||||
# ---------- 4. Render apache-adeo.conf from template ----------
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue