fix(deploy): name the container blocking a port and silence phantom cleanup
Gitea Actions Runner Test / test-job (push) Successful in 2s
CI / check (push) Successful in 30s
CI / tests-integration (push) Successful in 1m43s
CI / tests-unit (push) Successful in 1m47s
CI / tests-ui (push) Successful in 2m33s
CI / preflight (push) Skipped
CI / deploy (push) Failing after 1m30s

Two follow-ups from the blocked deploy.

The rollback path called `docker logs` and `docker rm -f` on the candidate
unconditionally. When the port check refuses to start it, the container was
never created, so both printed "No such container: epicnext-cms-app" — noise
that looked like a second, unrelated failure and buried the real message.
Both calls are now guarded by `docker inspect`.

assert_port_free() now reports which container holds the port and flags it when
it is not a blue/green slot this script manages. The previous output listed
every container and said only "port already in use", which is a dead end: on
this host the holder is `epicnext-cms` (a `docker compose up` replica on port
3002), while the deploy manages slot A as `epicnext-cms-app`. The names differ
because docker-compose.yml pins `container_name: epicnext-cms` for the `cms`
service; slot B happens to match, which is why 3003 deploys fine and 3002 never
can. The message now names the squatter, explains that live traffic is
unaffected, and gives the next action.

Deploy simulation: 26 passed.
This commit is contained in:
openhands committed 2026-10-03 18:37:12 +02:00
1 parent 8ee144745a
commit 8ec3df541e
1 file changed
+22 -3
+22 -3
View File
@@ -166,6 +166,25 @@ assert_port_free() {
printf '%s\n' "$holders" >&2
echo "--- containers currently running ---" >&2
docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}' >&2 || true
# Blame de container die de poort vasthoudt. De blauwe/groene release
# beheert zijn slots zelf, dus een container met een andere naam die hier
# toevallig op dezelfde poort draait (vaak gestart met `docker compose up`)
# is per definitie een losse replica. Zonder deze aanwijzing blijft een
# mislukte deploy een dode hoek in: het log meldde alleen een bezette poort,
# niet wie erachter zat.
echo "--- who holds port $port ---" >&2
docker ps --filter "publish=$port" --format '{{.Names}}\t{{.Image}}\t{{.Status}}' >&2 || true
local squatters=""
while IFS= read -r squatter; do
[ -n "$squatter" ] || continue
case "$squatter" in
"$name"|epicnext-cms-green|epicnext-cms-app) continue ;;
esac
echo " $squatter is not a managed blue/green slot for port $port." >&2
done < <(docker ps --format '{{.Names}}' 2>/dev/null || true)
echo "" >&2
echo "Stop or remove it, then re-run the deploy. Live traffic is unaffected:" >&2
echo "the nginx upstream keeps serving the other slot until cutover." >&2
return 1
}
@@ -243,7 +262,7 @@ finish() {
if [ "$cutover_started" -eq 0 ]; then
# De live release draait nog ongestoord; alleen de kandidaat opruimen.
echo "Deployment failed before cutover; the live release was never stopped" >&2
if [ "$candidate_attempted" -eq 1 ] && [ -n "$new_container" ]; then
if [ "$candidate_attempted" -eq 1 ] && [ -n "$new_container" ] && docker inspect "$new_container" >/dev/null 2>&1; then
docker logs "$new_container" --tail 50 >&2 || true
docker rm -f "$new_container" || true
fi
@@ -251,9 +270,9 @@ finish() {
# nginx wijst nu naar de kandidaat. Eerst het verkeer terug, dan pas de
# kandidaat weghalen, anders zou de site 502-en terwijl we terugdraaien.
echo "Deployment failed after cutover; rolling back to port $old_port" >&2
if [ -n "$new_container" ]; then docker logs "$new_container" --tail 50 >&2 || true; fi
if [ -n "$new_container" ] && docker inspect "$new_container" >/dev/null 2>&1; then docker logs "$new_container" --tail 50 >&2 || true; fi
if [ -n "$old_port" ]; then switch_upstream "$old_port" || true; fi
if [ -n "$new_container" ]; then docker rm -f "$new_container" || true; fi
if [ -n "$new_container" ] && docker inspect "$new_container" >/dev/null 2>&1; then docker rm -f "$new_container" || true; fi
if [ -n "$old_container" ] && docker start "$old_container" >/dev/null 2>&1; then
if healthy "$old_port"; then
echo "Rollback verified on port $old_port"