#!/usr/bin/env bash # AgentHub — Docker Smoke Test # Verifies that the Docker image builds and starts successfully with healthcheck passing. # # Usage: # ./scripts/smoke-test-docker.sh [image-tag] # # Example: # ./scripts/smoke-test-docker.sh registry.barodine.net/agenthub:dev # ./scripts/smoke-test-docker.sh agenthub:local set -euo pipefail IMAGE_TAG="${1:-registry.barodine.net/agenthub:dev}" CONTAINER_NAME="agenthub-smoke-test" TIMEOUT=30 echo "╔════════════════════════════════════════════════════╗" echo "║ AgentHub Docker Smoke Test ║" echo "╚════════════════════════════════════════════════════╝" echo "" echo "Image: ${IMAGE_TAG}" echo "" # Cleanup function cleanup() { echo "" echo "Cleaning up..." docker stop ${CONTAINER_NAME} 2>/dev/null || true docker rm ${CONTAINER_NAME} 2>/dev/null || true } trap cleanup EXIT # Check if compose stack is running (for DATABASE_URL) if ! docker compose -f compose.dev.yml ps postgres 2>/dev/null | grep -q Up; then echo "⚠️ Warning: compose.dev.yml not running. Starting services..." docker compose -f compose.dev.yml up -d postgres redis echo "Waiting for services to be ready..." sleep 5 fi # Get database connection from compose network COMPOSE_NETWORK=$(docker compose -f compose.dev.yml ps -q postgres | xargs docker inspect -f '{{range .NetworkSettings.Networks}}{{.NetworkName}}{{end}}' | head -1) POSTGRES_HOST=$(docker compose -f compose.dev.yml ps -q postgres | xargs docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' | head -1) REDIS_HOST=$(docker compose -f compose.dev.yml ps -q redis | xargs docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' | head -1) echo "[1/4] Starting container..." docker run -d --name ${CONTAINER_NAME} \ --network ${COMPOSE_NETWORK} \ -e DATABASE_URL="postgresql://agenthub:agenthub@${POSTGRES_HOST}:5432/agenthub" \ -e REDIS_URL="redis://${REDIS_HOST}:6379" \ -e JWT_SECRET="smoke-test-secret-minimum-32-chars-required-for-jwt" \ -e LOG_LEVEL=info \ -e NODE_ENV=production \ -p 3001:3000 \ ${IMAGE_TAG} echo "✅ Container started" echo "" echo "[2/4] Waiting for healthcheck to pass (timeout: ${TIMEOUT}s)..." elapsed=0 while [ $elapsed -lt $TIMEOUT ]; do health_status=$(docker inspect --format='{{.State.Health.Status}}' ${CONTAINER_NAME} 2>/dev/null || echo "unknown") if [ "$health_status" = "healthy" ]; then echo "✅ Healthcheck passed" break elif [ "$health_status" = "unhealthy" ]; then echo "❌ Healthcheck failed" docker logs ${CONTAINER_NAME} exit 1 fi sleep 2 elapsed=$((elapsed + 2)) echo " Status: ${health_status} (${elapsed}s / ${TIMEOUT}s)" done if [ $elapsed -ge $TIMEOUT ]; then echo "❌ Healthcheck timeout" docker logs ${CONTAINER_NAME} exit 1 fi echo "" echo "[3/4] Testing HTTP endpoint..." response=$(curl -sf http://localhost:3001/healthz || echo "FAILED") if [ "$response" = "FAILED" ]; then echo "❌ HTTP request failed" docker logs ${CONTAINER_NAME} exit 1 fi echo "✅ HTTP response: ${response}" echo "" echo "[4/4] Container logs (last 20 lines):" docker logs --tail 20 ${CONTAINER_NAME} echo "" echo "╔════════════════════════════════════════════════════╗" echo "║ ✅ Smoke test PASSED ║" echo "╚════════════════════════════════════════════════════╝"