ci(docker): add compose smoke script
This commit is contained in:
parent
032c2e7035
commit
cae5941374
@ -47,6 +47,9 @@ pnpm run smoke:local
|
|||||||
# Use an already-running backend or skip shared service checks when isolating product behavior.
|
# Use an already-running backend or skip shared service checks when isolating product behavior.
|
||||||
SMOKE_START_BACKEND=0 pnpm run smoke:local -- --no-start
|
SMOKE_START_BACKEND=0 pnpm run smoke:local -- --no-start
|
||||||
pnpm run smoke:local -- --skip-platform
|
pnpm run smoke:local -- --skip-platform
|
||||||
|
|
||||||
|
# Docker compose build/start/health smoke
|
||||||
|
pnpm run smoke:compose
|
||||||
```
|
```
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|||||||
@ -6,12 +6,12 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "4016:4016"
|
- "4016:4016"
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=${NODE_ENV:-development}
|
||||||
- PORT=4016
|
- PORT=4016
|
||||||
- HOST=0.0.0.0
|
- HOST=0.0.0.0
|
||||||
- PRODUCT_ID=notelett
|
- PRODUCT_ID=notelett
|
||||||
- SERVICE_NAME=notelett-backend
|
- SERVICE_NAME=notelett-backend
|
||||||
- JWT_SECRET=${JWT_SECRET:-dev-secret-change-me}
|
- JWT_SECRET=${JWT_SECRET:-dev-secret-change-me-at-least-32-characters}
|
||||||
- COSMOS_ENDPOINT=${COSMOS_ENDPOINT:-}
|
- COSMOS_ENDPOINT=${COSMOS_ENDPOINT:-}
|
||||||
- COSMOS_KEY=${COSMOS_KEY:-}
|
- COSMOS_KEY=${COSMOS_KEY:-}
|
||||||
- COSMOS_DATABASE=${COSMOS_DATABASE:-bytelyst}
|
- COSMOS_DATABASE=${COSMOS_DATABASE:-bytelyst}
|
||||||
@ -34,7 +34,7 @@ services:
|
|||||||
- LLM_EMBEDDING_MODEL=${LLM_EMBEDDING_MODEL:-text-embedding-3-small}
|
- LLM_EMBEDDING_MODEL=${LLM_EMBEDDING_MODEL:-text-embedding-3-small}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "--spider", "-q", "http://localhost:4016/health"]
|
test: ["CMD-SHELL", "node -e \"fetch('http://localhost:4016/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 3
|
retries: 3
|
||||||
@ -43,14 +43,17 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: web/Dockerfile
|
dockerfile: web/Dockerfile
|
||||||
|
args:
|
||||||
|
NEXT_PUBLIC_NOTES_API_URL: ${NEXT_PUBLIC_NOTES_API_URL:-http://localhost:4016/api}
|
||||||
|
NEXT_PUBLIC_PLATFORM_SERVICE_URL: ${NEXT_PUBLIC_PLATFORM_SERVICE_URL:-http://localhost:4003/api}
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3045"
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- NEXT_PUBLIC_PRODUCT_NAME=NoteLett
|
- NEXT_PUBLIC_PRODUCT_NAME=NoteLett
|
||||||
- NEXT_PUBLIC_PRODUCT_ID=notelett
|
- NEXT_PUBLIC_PRODUCT_ID=notelett
|
||||||
- NEXT_PUBLIC_NOTES_API_URL=http://backend:4016/api
|
- NEXT_PUBLIC_NOTES_API_URL=${NEXT_PUBLIC_NOTES_API_URL:-http://localhost:4016/api}
|
||||||
- NEXT_PUBLIC_PLATFORM_SERVICE_URL=${PLATFORM_SERVICE_URL:-http://localhost:4003}/api
|
- NEXT_PUBLIC_PLATFORM_SERVICE_URL=${NEXT_PUBLIC_PLATFORM_SERVICE_URL:-http://localhost:4003/api}
|
||||||
- NEXT_PUBLIC_EXTRACTION_SERVICE_URL=${EXTRACTION_SERVICE_URL:-http://localhost:4005}
|
- NEXT_PUBLIC_EXTRACTION_SERVICE_URL=${EXTRACTION_SERVICE_URL:-http://localhost:4005}
|
||||||
- NEXT_PUBLIC_MCP_SERVER_URL=${MCP_SERVER_URL:-http://localhost:4007}/api
|
- NEXT_PUBLIC_MCP_SERVER_URL=${MCP_SERVER_URL:-http://localhost:4007}/api
|
||||||
- NEXT_PUBLIC_DIAGNOSTICS_URL=${DIAGNOSTICS_URL:-http://localhost:3000}
|
- NEXT_PUBLIC_DIAGNOSTICS_URL=${DIAGNOSTICS_URL:-http://localhost:3000}
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
"test": "pnpm --filter @notelett/backend run test && pnpm --filter @notelett/web run test && pnpm --filter @notelett/mobile run test",
|
"test": "pnpm --filter @notelett/backend run test && pnpm --filter @notelett/web run test && pnpm --filter @notelett/mobile run test",
|
||||||
"build": "pnpm --filter @notelett/backend run build && pnpm --filter @notelett/web run build",
|
"build": "pnpm --filter @notelett/backend run build && pnpm --filter @notelett/web run build",
|
||||||
"smoke:local": "bash scripts/local-smoke.sh",
|
"smoke:local": "bash scripts/local-smoke.sh",
|
||||||
|
"smoke:compose": "bash scripts/compose-smoke.sh",
|
||||||
"verify": "pnpm run typecheck && pnpm run test && pnpm run build",
|
"verify": "pnpm run typecheck && pnpm run test && pnpm run build",
|
||||||
"prepare": "husky"
|
"prepare": "husky"
|
||||||
},
|
},
|
||||||
|
|||||||
65
scripts/compose-smoke.sh
Executable file
65
scripts/compose-smoke.sh
Executable file
@ -0,0 +1,65 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build and smoke-test the local Docker Compose stack.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
COMPOSE_CMD="${COMPOSE_CMD:-docker compose}"
|
||||||
|
BACKEND_URL="${BACKEND_URL:-http://localhost:4016}"
|
||||||
|
WEB_URL="${WEB_URL:-http://localhost:3000}"
|
||||||
|
JWT_SECRET="${JWT_SECRET:-dev-secret-change-me-at-least-32-characters}"
|
||||||
|
|
||||||
|
cd "$REPO_DIR"
|
||||||
|
|
||||||
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
|
echo "docker is required for compose smoke checks." >&2
|
||||||
|
exit 127
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
bash scripts/docker-prep.sh --restore >/dev/null 2>&1 || true
|
||||||
|
if [[ "${KEEP_COMPOSE:-0}" != "1" ]]; then
|
||||||
|
$COMPOSE_CMD down --remove-orphans >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
wait_for_url() {
|
||||||
|
local url="$1"
|
||||||
|
local label="$2"
|
||||||
|
local attempts="${3:-60}"
|
||||||
|
|
||||||
|
for attempt in $(seq 1 "$attempts"); do
|
||||||
|
if curl -fsS "$url" >/dev/null; then
|
||||||
|
echo "ok: $label"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
if [[ "$attempt" == "$attempts" ]]; then
|
||||||
|
echo "failed: $label did not respond at $url" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Preparing Docker build dependencies..."
|
||||||
|
bash scripts/docker-prep.sh
|
||||||
|
|
||||||
|
echo "Building backend and web images..."
|
||||||
|
$COMPOSE_CMD build backend web
|
||||||
|
|
||||||
|
echo "Starting compose stack..."
|
||||||
|
NODE_ENV=development \
|
||||||
|
DB_PROVIDER=memory \
|
||||||
|
JWT_SECRET="$JWT_SECRET" \
|
||||||
|
FIELD_ENCRYPT_ENABLED=false \
|
||||||
|
FEATURE_FLAGS_ENABLED=false \
|
||||||
|
TELEMETRY_ENABLED=false \
|
||||||
|
$COMPOSE_CMD up -d backend web
|
||||||
|
|
||||||
|
wait_for_url "$BACKEND_URL/health" "backend health"
|
||||||
|
wait_for_url "$BACKEND_URL/api/bootstrap" "backend bootstrap"
|
||||||
|
wait_for_url "$WEB_URL" "web root"
|
||||||
|
|
||||||
|
echo "Compose smoke passed."
|
||||||
Loading…
Reference in New Issue
Block a user