test: add robust Docker build+run test script with multi-arch support
Replaces inline docker:test script with scripts/docker-test.sh that: - Detects and reports architecture (x86_64/arm64) - Polls health endpoint with configurable timeout (60s) - Verifies home page, health/live, health/ready endpoints - Tests WebSocket endpoint reachability - Proper cleanup on exit via trap - Supports --skip-build flag for CI caching Co-authored-by: ajnart <49837342+ajnart@users.noreply.github.com>
This commit is contained in:
1 parent
5a5f1062ce
commit
a508fd1806
2 files changed
+131
-1
No files matched your search
+2
-1
@@ -18,7 +18,8 @@
|
||||
"dev": "turbo dev --parallel",
|
||||
"docker:dev": "docker compose -f ./development/development.docker-compose.yml up",
|
||||
"docker:build": "docker build -t homarr:test .",
|
||||
"docker:test": "docker build -t homarr:test . && docker run --rm -d --name homarr-test -p 7575:7575 homarr:test && echo 'Waiting for container to start...' && sleep 15 && (curl -sf http://localhost:7575 > /dev/null && echo '✅ Docker container is running and responding on port 7575' || echo '❌ Docker container failed health check') ; docker logs homarr-test 2>&1 | tail -30 ; docker stop homarr-test",
|
||||
"docker:test": "bash scripts/docker-test.sh",
|
||||
"docker:test:skip-build": "bash scripts/docker-test.sh --skip-build",
|
||||
"format": "turbo format --continue -- --cache --cache-location node_modules/.cache/.prettiercache",
|
||||
"format:fix": "turbo format --continue -- --write --cache --cache-location node_modules/.cache/.prettiercache",
|
||||
"lint": "turbo lint --continue -- --cache --cache-location node_modules/.cache/.eslintcache",
|
||||
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env bash
|
||||
# Docker build + run integration test
|
||||
# Tests that the Docker image builds and starts successfully on the current architecture.
|
||||
# Works on both x86_64 and arm64 without requiring multi-platform builders.
|
||||
#
|
||||
# Usage: ./scripts/docker-test.sh [--skip-build]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE_NAME="homarr:test"
|
||||
CONTAINER_NAME="homarr-docker-test"
|
||||
PORT=7575
|
||||
HEALTH_ENDPOINT="/api/health/ready"
|
||||
MAX_WAIT=60
|
||||
POLL_INTERVAL=3
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
cleanup() {
|
||||
if docker ps -q --filter "name=${CONTAINER_NAME}" | grep -q .; then
|
||||
echo -e "${YELLOW}Cleaning up container...${NC}"
|
||||
docker stop "${CONTAINER_NAME}" 2>/dev/null || true
|
||||
fi
|
||||
docker rm -f "${CONTAINER_NAME}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
# Detect architecture
|
||||
ARCH=$(uname -m)
|
||||
echo "🏗️ Architecture: ${ARCH}"
|
||||
|
||||
# Step 1: Build
|
||||
if [ "${1:-}" != "--skip-build" ]; then
|
||||
echo "🔨 Building Docker image..."
|
||||
docker build -t "${IMAGE_NAME}" . || {
|
||||
echo -e "${RED}❌ Docker build failed${NC}"
|
||||
exit 1
|
||||
}
|
||||
echo -e "${GREEN}✅ Docker build succeeded${NC}"
|
||||
else
|
||||
echo "⏭️ Skipping build (--skip-build)"
|
||||
fi
|
||||
|
||||
# Step 2: Start container
|
||||
echo "🚀 Starting container..."
|
||||
cleanup
|
||||
docker run --rm -d \
|
||||
--name "${CONTAINER_NAME}" \
|
||||
-p "${PORT}:7575" \
|
||||
-e SECRET_ENCRYPTION_KEY="$(head -c 32 /dev/urandom | xxd -p | tr -d '\n')" \
|
||||
"${IMAGE_NAME}"
|
||||
|
||||
# Step 3: Wait for health endpoint
|
||||
echo "⏳ Waiting for health endpoint (max ${MAX_WAIT}s)..."
|
||||
ELAPSED=0
|
||||
while [ $ELAPSED -lt $MAX_WAIT ]; do
|
||||
if curl -sf "http://localhost:${PORT}${HEALTH_ENDPOINT}" > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✅ Health check passed after ${ELAPSED}s${NC}"
|
||||
break
|
||||
fi
|
||||
sleep $POLL_INTERVAL
|
||||
ELAPSED=$((ELAPSED + POLL_INTERVAL))
|
||||
done
|
||||
|
||||
if [ $ELAPSED -ge $MAX_WAIT ]; then
|
||||
echo -e "${RED}❌ Health check failed after ${MAX_WAIT}s${NC}"
|
||||
echo "--- Container logs ---"
|
||||
docker logs "${CONTAINER_NAME}" 2>&1 | tail -50
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 4: Verify key endpoints
|
||||
echo "🔍 Verifying endpoints..."
|
||||
|
||||
# Home page
|
||||
HOME_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${PORT}/")
|
||||
if [ "$HOME_STATUS" = "200" ]; then
|
||||
echo -e "${GREEN} ✅ Home page: ${HOME_STATUS}${NC}"
|
||||
else
|
||||
echo -e "${RED} ❌ Home page: ${HOME_STATUS}${NC}"
|
||||
docker logs "${CONTAINER_NAME}" 2>&1 | tail -30
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Health live
|
||||
LIVE_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${PORT}/api/health/live")
|
||||
if [ "$LIVE_STATUS" = "200" ]; then
|
||||
echo -e "${GREEN} ✅ Health live: ${LIVE_STATUS}${NC}"
|
||||
else
|
||||
echo -e "${RED} ❌ Health live: ${LIVE_STATUS}${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Health ready
|
||||
READY_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${PORT}/api/health/ready")
|
||||
if [ "$READY_STATUS" = "200" ]; then
|
||||
echo -e "${GREEN} ✅ Health ready: ${READY_STATUS}${NC}"
|
||||
else
|
||||
echo -e "${RED} ❌ Health ready: ${READY_STATUS}${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 5: Verify WebSocket upgrade is possible (should get 426 without proper headers, or 101 with them)
|
||||
WS_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-H "Upgrade: websocket" \
|
||||
-H "Connection: Upgrade" \
|
||||
-H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
|
||||
-H "Sec-WebSocket-Version: 13" \
|
||||
"http://localhost:${PORT}/websockets" 2>/dev/null || echo "000")
|
||||
if [ "$WS_STATUS" = "101" ] || [ "$WS_STATUS" = "426" ] || [ "$WS_STATUS" = "400" ]; then
|
||||
echo -e "${GREEN} ✅ WebSocket endpoint reachable: ${WS_STATUS}${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} ⚠️ WebSocket endpoint status: ${WS_STATUS} (may be expected behind nginx)${NC}"
|
||||
fi
|
||||
|
||||
# Step 6: Print container info
|
||||
echo ""
|
||||
echo "📊 Container info:"
|
||||
docker inspect "${CONTAINER_NAME}" --format=' Image: {{.Config.Image}}' 2>/dev/null || true
|
||||
docker inspect "${CONTAINER_NAME}" --format=' Platform: {{.Platform}}' 2>/dev/null || true
|
||||
echo " Architecture: ${ARCH}"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ All Docker tests passed!${NC}"
|
||||
Reference in new issue
Block a user