From 455259a8524eb1d37041159021b475ad1e8cde3e Mon Sep 17 00:00:00 2001 From: grabowski Date: Wed, 13 Aug 2025 16:51:34 +0700 Subject: [PATCH] Add multi-method connection strategy for container health checks Connection Methods (in order of preference): 1. Container IP direct connection (172.17.0.x:8000) 2. Docker exec from inside container (127.0.0.1:8000) 3. Host networking fallback (127.0.0.1:8080) Addresses Exit Code 28 (Timeout): - Container IP connection was timing out in CI environment - Docker exec bypasses network isolation issues - Multiple fallback methods ensure reliability Improved Error Handling: - Shorter timeouts (5s max, 3s connect) for faster fallback - Clear method identification in logs - Graceful degradation through connection methods Why Docker Exec Should Work: - Runs curl from inside the target container - No network isolation between runner and app container - Direct access to 127.0.0.1:8000 (internal) - Most reliable method in containerized CI environments Should resolve timeout issues and provide reliable health checks --- .gitea/workflows/release.yml | 46 ++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 0659f64..f3d3a67 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -230,12 +230,25 @@ jobs: CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ping-river-monitor-test) echo "Container IP: $CONTAINER_IP" - # Test using container IP directly (port 8000 inside container) + # Try multiple connection methods + response="" + + # Method 1: Try container IP directly if [ -n "$CONTAINER_IP" ]; then - response=$(curl -s --max-time 10 --connect-timeout 5 -w "HTTP_CODE:%{http_code}" http://$CONTAINER_IP:8000/health) - else - # Fallback to localhost if IP detection fails - response=$(curl -s --max-time 10 --connect-timeout 5 -w "HTTP_CODE:%{http_code}" http://127.0.0.1:8080/health) + echo "Trying container IP: $CONTAINER_IP:8000" + response=$(curl -s --max-time 5 --connect-timeout 3 -w "HTTP_CODE:%{http_code}" http://$CONTAINER_IP:8000/health 2>/dev/null || echo "TIMEOUT") + fi + + # Method 2: If container IP fails, try docker exec + if [[ "$response" == "TIMEOUT" ]] || [ -z "$response" ]; then + echo "Container IP failed, trying docker exec..." + response=$(docker exec ping-river-monitor-test curl -s --max-time 5 -w "HTTP_CODE:%{http_code}" http://127.0.0.1:8000/health 2>/dev/null || echo "EXEC_FAILED") + fi + + # Method 3: If exec fails, try host networking + if [[ "$response" == "EXEC_FAILED" ]] || [ -z "$response" ]; then + echo "Docker exec failed, trying host networking..." + response=$(curl -s --max-time 5 --connect-timeout 3 -w "HTTP_CODE:%{http_code}" http://127.0.0.1:8080/health 2>/dev/null || echo "HOST_FAILED") fi http_code=$(echo "$response" | grep -o "HTTP_CODE:[0-9]*" | cut -d: -f2) @@ -260,20 +273,29 @@ jobs: # Test API endpoints with container networking echo "🧪 Testing API endpoints..." - + # Get container IP for direct communication CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ping-river-monitor-test) echo "Using container IP: $CONTAINER_IP" - + endpoints=("health" "docs" "stations" "metrics") for endpoint in "${endpoints[@]}"; do echo "Testing /$endpoint..." - # Use container IP if available, otherwise fallback to localhost - if [ -n "$CONTAINER_IP" ]; then - response=$(curl -s --max-time 10 -w "HTTP_CODE:%{http_code}" http://$CONTAINER_IP:8000/$endpoint) - else - response=$(curl -s --max-time 10 -w "HTTP_CODE:%{http_code}" http://127.0.0.1:8080/$endpoint) + # Try multiple connection methods for reliability + response="" + + # Try docker exec first (most reliable in containerized CI) + response=$(docker exec ping-river-monitor-test curl -s --max-time 5 -w "HTTP_CODE:%{http_code}" http://127.0.0.1:8000/$endpoint 2>/dev/null || echo "EXEC_FAILED") + + # Fallback to container IP if exec fails + if [[ "$response" == "EXEC_FAILED" ]] && [ -n "$CONTAINER_IP" ]; then + response=$(curl -s --max-time 5 --connect-timeout 3 -w "HTTP_CODE:%{http_code}" http://$CONTAINER_IP:8000/$endpoint 2>/dev/null || echo "IP_FAILED") + fi + + # Final fallback to host networking + if [[ "$response" == "IP_FAILED" ]] || [[ "$response" == "EXEC_FAILED" ]]; then + response=$(curl -s --max-time 5 --connect-timeout 3 -w "HTTP_CODE:%{http_code}" http://127.0.0.1:8080/$endpoint 2>/dev/null || echo "ALL_FAILED") fi http_code=$(echo "$response" | grep -o "HTTP_CODE:[0-9]*" | cut -d: -f2)