#!/usr/bin/env bash # Build the actual runtime and check HTTP behavior without external services. set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" IMAGE="vocero-api-smoke:$(date +%s)-$$" container_id="" cleanup() { if [ -n "$container_id" ]; then docker rm --force "$container_id" >/dev/null fi docker image rm "$IMAGE" >/dev/null 2>&1 || true } trap cleanup EXIT docker build --file "$ROOT_DIR/vocero-api/Dockerfile" --tag "$IMAGE" "$ROOT_DIR" container_id="$(docker run --detach --publish 127.0.0.1::7860 "$IMAGE")" port="$(docker port "$container_id" 7860/tcp)" ready=false for ((attempt = 0; attempt < 60; attempt++)); do if curl --noproxy '*' --silent --fail --max-time 1 "http://$port/api/config" >/dev/null; then ready=true break fi sleep 0.5 done if [ "$ready" != true ]; then docker logs "$container_id" exit 1 fi docker exec -i "$container_id" python - <<'PY' import json import urllib.error import urllib.request base = "http://127.0.0.1:7860" with urllib.request.urlopen(base + "/api/config") as response: assert json.load(response) == { "search": False, "lb": False, "allowDirect": True, "s2sUrl": "", "primaryPrompt": "", "reasoningType": "PROXY", "injectProfile": False, "debugPrompt": False, "startSessionMode": "", "theme": "", "apipilot": False, } for path in ["/docs", "/docs/README.md", "/openapi.json"]: with urllib.request.urlopen(base + path) as response: assert response.status == 200 try: urllib.request.urlopen(base + "/") except urllib.error.HTTPError as error: assert error.code == 404 else: raise AssertionError("The backend root must remain 404") print("Docker runtime smoke checks passed") PY