# Rebuild and restart containers with retry logic echo "[DEPLOY] Building and starting containers..." if ! $DOCKER_COMPOSE up -d --build; then echo "[DEPLOY] ⚠️ First attempt failed - docker-compose up encountered an error" echo "[DEPLOY] Performing FULL cleanup of ghost containers left by failed attempt..." # CRITICAL: docker-compose up may have partially created containers before failing. # We must re-run the COMPLETE cleanup sequence, not just a quick port cleanup. # Step 1: Force stop and remove ALL fetch-china containers (including ghosts from failed attempt) echo "[DEPLOY] Step 1: Removing all fetch-china containers (including partial creates)..." docker ps -aq --filter "name=fetch-china" | xargs -r docker rm -f 2>/dev/null || true # Step 2: Run docker-compose down to clean up any resources echo "[DEPLOY] Step 2: Running docker-compose down..." $DOCKER_COMPOSE down -v --remove-orphans 2>/dev/null || true # Step 3: Remove containers by exact name (belt and suspenders) echo "[DEPLOY] Step 3: Removing containers by exact name..." docker rm -f fetch-china-backend fetch-china-frontend 2>/dev/null || true # Step 4: Clean up any container using ports 80 or 8000 (running OR stopped) echo "[DEPLOY] Step 4: Cleaning up port conflicts..." for PORT in 80 8000; do docker ps --filter "publish=${PORT}" -q 2>/dev/null | xargs -r docker stop 2>/dev/null || true docker ps -a --filter "publish=${PORT}" -q 2>/dev/null | xargs -r docker rm -f 2>/dev/null || true done # Step 5: Kill non-docker processes holding the ports echo "[DEPLOY] Step 5: Killing non-docker processes on ports 80/8000..." if command -v ss >/dev/null 2>&1; then for PORT in 80 8000; do HOLDER_PIDS=$(ss -ltnp "sport = :${PORT}" 2>/dev/null \ | grep -oE 'pid=[0-9]+' | cut -d= -f2 | sort -u || true) if [ -n "$HOLDER_PIDS" ]; then echo "[DEPLOY] Killing processes holding port ${PORT}: ${HOLDER_PIDS}" for PID in $HOLDER_PIDS; do kill -9 "$PID" 2>/dev/null || true done fi done elif command -v lsof >/dev/null 2>&1; then lsof -ti:80 2>/dev/null | xargs -r kill -9 2>/dev/null || true lsof -ti:8000 2>/dev/null | xargs -r kill -9 2>/dev/null || true fi # Step 6: Wait for cleanup to complete and ports to be released echo "[DEPLOY] Step 6: Waiting for cleanup to complete..." sleep 5 # Step 7: Final verification echo "[DEPLOY] Step 7: Final verification..." REMAINING=$(docker ps -aq --filter "name=fetch-china" 2>/dev/null || true) if [ -n "$REMAINING" ]; then echo "[DEPLOY] ⚠️ Still found containers: $REMAINING - force removing..." echo "$REMAINING" | xargs -r docker rm -f 2>/dev/null || true fi echo "[DEPLOY] ✓ Full cleanup completed, retrying docker-compose up..." $DOCKER_COMPOSE up -d --build fi