Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
c3498bda76 | |||
4336e99e0c | |||
455259a852 |
@@ -185,18 +185,22 @@ jobs:
|
|||||||
|
|
||||||
- name: Deploy to production (Local Test)
|
- name: Deploy to production (Local Test)
|
||||||
run: |
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
echo "🚀 Testing ${{ needs.create-release.outputs.version }} deployment locally..."
|
echo "🚀 Testing ${{ needs.create-release.outputs.version }} deployment locally..."
|
||||||
|
|
||||||
|
# Create a dedicated network so we can resolve by container name
|
||||||
|
docker network create ci_net || true
|
||||||
|
|
||||||
# Pull the built image
|
# Pull the built image
|
||||||
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
|
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
|
||||||
|
|
||||||
# Stop any existing containers
|
# Stop & remove any existing container
|
||||||
docker stop ping-river-monitor-test || true
|
docker rm -f ping-river-monitor-test 2>/dev/null || true
|
||||||
docker rm ping-river-monitor-test || true
|
|
||||||
|
|
||||||
# Start the container for testing
|
# Start the container on the user-defined network
|
||||||
docker run -d \
|
docker run -d \
|
||||||
--name ping-river-monitor-test \
|
--name ping-river-monitor-test \
|
||||||
|
--network ci_net \
|
||||||
-p 8080:8000 \
|
-p 8080:8000 \
|
||||||
-e LOG_LEVEL=INFO \
|
-e LOG_LEVEL=INFO \
|
||||||
-e DB_TYPE=sqlite \
|
-e DB_TYPE=sqlite \
|
||||||
@@ -206,89 +210,73 @@ jobs:
|
|||||||
|
|
||||||
- name: Health check after deployment
|
- name: Health check after deployment
|
||||||
run: |
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
echo "⏳ Waiting for application to start..."
|
echo "⏳ Waiting for application to start..."
|
||||||
sleep 30
|
|
||||||
|
|
||||||
echo "🔍 Running health checks against local container..."
|
# Pull a curl-only image for probing (keeps your app image slim)
|
||||||
|
docker pull curlimages/curl:8.10.1
|
||||||
|
|
||||||
# Check if container is running
|
# Helper: curl via a sibling container on the SAME Docker network
|
||||||
docker ps | grep ping-river-monitor-test || echo "⚠️ Container not found in docker ps"
|
probe() {
|
||||||
|
local url="$1"
|
||||||
|
docker run --rm --network ci_net curlimages/curl:8.10.1 \
|
||||||
|
-sS --max-time 5 --connect-timeout 3 -w "HTTP_CODE:%{http_code}" "$url" || true
|
||||||
|
}
|
||||||
|
|
||||||
# Check container logs for any startup issues
|
# Wait for /health (up to ~3m 45s)
|
||||||
echo "📋 Recent container logs:"
|
|
||||||
docker logs --tail 10 ping-river-monitor-test || true
|
|
||||||
|
|
||||||
# Wait for the application to be ready with more robust checking
|
|
||||||
echo "🔍 Testing application readiness..."
|
|
||||||
for i in {1..15}; do
|
for i in {1..15}; do
|
||||||
echo "⏳ Attempt $i/15: Testing health endpoint..."
|
echo "🔍 Attempt $i/15: checking http://ping-river-monitor-test:8000/health"
|
||||||
|
resp="$(probe http://ping-river-monitor-test:8000/health)"
|
||||||
|
code="$(echo "$resp" | sed -n 's/.*HTTP_CODE:\([0-9]\+\).*/\1/p')"
|
||||||
|
body="$(echo "$resp" | sed 's/HTTP_CODE:[0-9]*$//')"
|
||||||
|
|
||||||
# Test health endpoint with container networking
|
echo "HTTP: ${code:-<none>} | Body: ${body:-<empty>}"
|
||||||
echo "Testing health endpoint..."
|
|
||||||
|
|
||||||
# Get the container's IP address for direct communication
|
if [ "${code:-}" = "200" ] && [ -n "${body:-}" ]; then
|
||||||
CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ping-river-monitor-test)
|
echo "✅ Health endpoint responding successfully"
|
||||||
echo "Container IP: $CONTAINER_IP"
|
break
|
||||||
|
|
||||||
# Test using container IP directly (port 8000 inside container)
|
|
||||||
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)
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
http_code=$(echo "$response" | grep -o "HTTP_CODE:[0-9]*" | cut -d: -f2)
|
echo "❌ Not ready yet. Showing recent logs…"
|
||||||
response_body=$(echo "$response" | sed 's/HTTP_CODE:[0-9]*$//')
|
docker logs --tail 20 ping-river-monitor-test || true
|
||||||
|
sleep 15
|
||||||
|
|
||||||
echo "HTTP Code: $http_code"
|
if [ "$i" -eq 15 ]; then
|
||||||
echo "Response Body: $response_body"
|
echo "❌ Health never reached 200. Failing."
|
||||||
|
exit 1
|
||||||
if [ "$http_code" = "200" ] && [ -n "$response_body" ]; then
|
|
||||||
echo "✅ Health endpoint responding successfully!"
|
|
||||||
break
|
|
||||||
else
|
|
||||||
echo "❌ Health check failed (HTTP: $http_code), waiting 15 seconds..."
|
|
||||||
# Show what's happening with the container
|
|
||||||
echo "Container status:"
|
|
||||||
docker ps | grep ping-river-monitor-test || echo "Container not found"
|
|
||||||
echo "Recent container logs:"
|
|
||||||
docker logs --tail 5 ping-river-monitor-test || true
|
|
||||||
sleep 15
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Test API endpoints with container networking
|
echo "🧪 Testing API endpoints…"
|
||||||
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")
|
endpoints=("health" "docs" "stations" "metrics")
|
||||||
for endpoint in "${endpoints[@]}"; do
|
for ep in "${endpoints[@]}"; do
|
||||||
echo "Testing /$endpoint..."
|
url="http://ping-river-monitor-test:8000/$ep"
|
||||||
|
resp="$(probe "$url")"
|
||||||
|
code="$(echo "$resp" | sed -n 's/.*HTTP_CODE:\([0-9]\+\).*/\1/p')"
|
||||||
|
|
||||||
# Use container IP if available, otherwise fallback to localhost
|
if [ "${code:-}" = "200" ]; then
|
||||||
if [ -n "$CONTAINER_IP" ]; then
|
echo "✅ /$ep: OK"
|
||||||
response=$(curl -s --max-time 10 -w "HTTP_CODE:%{http_code}" http://$CONTAINER_IP:8000/$endpoint)
|
|
||||||
else
|
else
|
||||||
response=$(curl -s --max-time 10 -w "HTTP_CODE:%{http_code}" http://127.0.0.1:8080/$endpoint)
|
echo "❌ /$ep: FAILED (HTTP ${code:-<none>})"
|
||||||
fi
|
echo "Response: $(echo "$resp" | sed 's/HTTP_CODE:[0-9]*$//')"
|
||||||
|
|
||||||
http_code=$(echo "$response" | grep -o "HTTP_CODE:[0-9]*" | cut -d: -f2)
|
|
||||||
|
|
||||||
if [ "$http_code" = "200" ]; then
|
|
||||||
echo "✅ /$endpoint: OK (HTTP $http_code)"
|
|
||||||
else
|
|
||||||
echo "❌ /$endpoint: FAILED (HTTP $http_code)"
|
|
||||||
echo "Response: $(echo "$response" | sed 's/HTTP_CODE:[0-9]*$//')"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "✅ All health checks passed!"
|
echo "✅ All health checks passed!"
|
||||||
|
|
||||||
|
- name: (Fallback) Probe via host-published port
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
# In case you also want to verify the host-published port from inside the job container:
|
||||||
|
HOST_GATEWAY="$(ip route | awk '/default/ {print $3}')"
|
||||||
|
echo "🔎 Host gateway is $HOST_GATEWAY — probing http://$HOST_GATEWAY:8080/health"
|
||||||
|
docker run --rm curlimages/curl:8.10.1 \
|
||||||
|
-sS --max-time 5 --connect-timeout 3 -w "HTTP_CODE:%{http_code}\n" \
|
||||||
|
"http://$HOST_GATEWAY:8080/health" || true
|
||||||
|
|
||||||
|
|
||||||
- name: Container logs and cleanup
|
- name: Container logs and cleanup
|
||||||
if: always()
|
if: always()
|
||||||
run: |
|
run: |
|
||||||
|
Reference in New Issue
Block a user