#!/bin/bash # Apollo Router 启动脚本 # # 1. 等待所有子图 /graphql 端点就绪 # 2. 使用 rover 组合 supergraph SDL # 3. 启动 apollo-router set -e SUBGRAPHS=( "iam:3002" "core-edu:3004" "content:3005" "msg:3007" "ai:3008" "data-ana:3006" ) echo "[apollo-router] Waiting for subgraphs to be ready..." wait_for_subgraph() { local name="$1" local host="$2" local port="$3" local max_retries=60 local retry=0 while [ $retry -lt $max_retries ]; do if curl -sf -o /dev/null "http://${host}:${port}/healthz" 2>/dev/null; then echo "[apollo-router] ${name} is ready (http://${host}:${port})" return 0 fi retry=$((retry + 1)) echo "[apollo-router] Waiting for ${name} at ${host}:${port} (attempt ${retry}/${max_retries})" sleep 3 done echo "[apollo-router] WARNING: ${name} not ready after ${max_retries} attempts, continuing anyway..." return 0 } for entry in "${SUBGRAPHS[@]}"; do name="${entry%%:*}" hostport="${entry#*:}" host="${hostport%%:*}" port="${hostport##*:}" wait_for_subgraph "$name" "$host" "$port" done # 组合 supergraph SDL echo "[apollo-router] Composing supergraph SDL..." export APOLLO_ELV2_LICENSE=accept max_compose_retries=5 compose_retry=0 while [ $compose_retry -lt $max_compose_retries ]; do compose_retry=$((compose_retry + 1)) if rover supergraph compose --config /dist/supergraph.yaml --output /tmp/supergraph.graphql 2>&1; then echo "[apollo-router] Supergraph composed successfully" break fi echo "[apollo-router] Compose attempt ${compose_retry}/${max_compose_retries} failed, retrying in 5s..." sleep 5 done if [ ! -f /tmp/supergraph.graphql ]; then echo "[apollo-router] ERROR: Failed to compose supergraph after ${max_compose_retries} attempts" exit 1 fi # PQ manifest 检查(v2.1 M3 安全加固) # 关联:portal-shell spec §4.2、§4.3 # - 生产模式(APOLLO_REQUIRE_PQ_MANIFEST=true)必须存在 manifest,否则启动失败 # - 开发模式(APOLLO_REQUIRE_PQ_MANIFEST=false)manifest 不存在时仅警告 MANIFEST_PATH="/etc/apollo-router/pq-manifest.json" REQUIRE_MANIFEST="${APOLLO_REQUIRE_PQ_MANIFEST:-false}" if [ "${REQUIRE_MANIFEST}" = "true" ]; then if [ ! -f "${MANIFEST_PATH}" ]; then echo "[apollo-router] ERROR: APOLLO_REQUIRE_PQ_MANIFEST=true but manifest not found at ${MANIFEST_PATH}" echo "[apollo-router] Run 'pnpm --filter @edu/portal-shell run generate-pq-manifest' to generate it." exit 1 fi QUERY_COUNT=$(grep -c '"' "${MANIFEST_PATH}" 2>/dev/null || echo "0") echo "[apollo-router] PQ manifest loaded (require_manifest=true): ${MANIFEST_PATH}" else if [ ! -f "${MANIFEST_PATH}" ]; then echo "[apollo-router] WARNING: PQ manifest not found at ${MANIFEST_PATH} (require_manifest=false, continuing)" echo "[apollo-router] APQ will accept hash-only requests but cannot resolve unknown hashes." else echo "[apollo-router] PQ manifest loaded (require_manifest=false): ${MANIFEST_PATH}" fi fi # 启动 router(router 二进制位于 /dist/router,由基础镜像 ghcr.io/apollographql/router 提供) echo "[apollo-router] Starting Apollo Router on port 3000..." exec /dist/router --config /dist/configuration.yaml --supergraph /tmp/supergraph.graphql --hot-reload