From d31c62d4e2385ff9b368f1f2f7978871ef9de05b Mon Sep 17 00:00:00 2001 From: Xiaoxia AI Date: Sat, 20 Jun 2026 19:02:48 +0800 Subject: [PATCH] fix(deploy): align deployment with split infrastructure --- .gitea/workflows/deploy.yml | 4 ++-- apps/api/app/core/storage.py | 4 ++++ infra/docker/compose.yml | 4 ++-- infra/docker/deploy-production.sh | 21 +++++++++++++++++++-- infra/docker/deploy-staging.sh | 21 +++++++++++++++++++-- infra/nginx/xiaoxia-saas.conf | 30 +++++++++++++++++++++++++++++- infra/scripts/deploy.sh | 4 ++-- requirements.txt | 2 +- 8 files changed, 78 insertions(+), 12 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 61e397ac1..a51c790ca 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -69,7 +69,7 @@ jobs: set -eu i=0 while [ "$i" -lt 30 ]; do - if wget -qO- http://127.0.0.1:8000/api/v1/health; then + if wget -qO- http://127.0.0.1:8000/health; then exit 0 fi i=$((i + 1)) @@ -139,7 +139,7 @@ jobs: set -eu i=0 while [ "$i" -lt 30 ]; do - if wget -qO- http://127.0.0.1:8000/api/v1/health; then + if wget -qO- http://127.0.0.1:8000/health; then exit 0 fi i=$((i + 1)) diff --git a/apps/api/app/core/storage.py b/apps/api/app/core/storage.py index 154213099..abdb7249d 100644 --- a/apps/api/app/core/storage.py +++ b/apps/api/app/core/storage.py @@ -131,6 +131,10 @@ class OSSStorageService: return self.bucket.object_exists(storage_key) +# 向后兼容的服务类名 +MinIOService = OSSStorageService + + _storage_service = None diff --git a/infra/docker/compose.yml b/infra/docker/compose.yml index 77063f821..aa138b4d9 100644 --- a/infra/docker/compose.yml +++ b/infra/docker/compose.yml @@ -17,7 +17,7 @@ services: networks: - xiaoxia-net healthcheck: - test: ["CMD", "wget", "--spider", "-q", "http://localhost:8000/api/v1/health"] + test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health', timeout=5)"] interval: 30s timeout: 10s retries: 3 @@ -49,7 +49,7 @@ services: networks: - xiaoxia-net healthcheck: - test: ["CMD", "wget", "--spider", "-q", "http://localhost:80"] + test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:80"] interval: 30s timeout: 5s retries: 3 diff --git a/infra/docker/deploy-production.sh b/infra/docker/deploy-production.sh index 68adbd68b..b5138b2e0 100644 --- a/infra/docker/deploy-production.sh +++ b/infra/docker/deploy-production.sh @@ -1,20 +1,37 @@ #!/bin/sh set -eu -# 容器内路径(通过 -v /:/host 映射) ROOT_DIR="/host/var/lib/xiaoxia-saas-production/repo" COMPOSE_DIR="$ROOT_DIR/infra/docker" ENV_FILE="/host/var/lib/xiaoxia-saas-production/.env" +ensure_container_running() { + name="$1" + if ! docker inspect "$name" >/dev/null 2>&1; then + echo "❌ Required infrastructure container not found: $name" + echo " Run infra/docker/infra.yml first before deploying applications." + exit 1 + fi + + state="$(docker inspect -f '{{.State.Status}}' "$name")" + if [ "$state" != "running" ]; then + echo "❌ Required infrastructure container is not running: $name ($state)" + exit 1 + fi +} + cd "$ROOT_DIR" cp "$ENV_FILE" "$ROOT_DIR/.env" mkdir -p "$ROOT_DIR/apps/web/public" [ -f "$ROOT_DIR/apps/web/public/.keep" ] || printf 'placeholder' > "$ROOT_DIR/apps/web/public/.keep" +ensure_container_running xiaoxia-postgres +ensure_container_running xiaoxia-redis + cd "$COMPOSE_DIR" WEB_PORT="${WEB_PORT:-3001}" export WEB_PORT docker compose build api worker web -docker compose up -d postgres redis api worker web +docker compose up -d api worker web docker compose ps diff --git a/infra/docker/deploy-staging.sh b/infra/docker/deploy-staging.sh index 795df5e5d..e2ec9a4ed 100644 --- a/infra/docker/deploy-staging.sh +++ b/infra/docker/deploy-staging.sh @@ -1,20 +1,37 @@ #!/bin/sh set -eu -# 容器内路径(通过 -v /:/host 映射) ROOT_DIR="/host/var/lib/xiaoxia-saas-staging/repo" COMPOSE_DIR="$ROOT_DIR/infra/docker" ENV_FILE="/host/var/lib/xiaoxia-saas-staging/.env" +ensure_container_running() { + name="$1" + if ! docker inspect "$name" >/dev/null 2>&1; then + echo "❌ Required infrastructure container not found: $name" + echo " Run infra/docker/infra.yml first before deploying applications." + exit 1 + fi + + state="$(docker inspect -f '{{.State.Status}}' "$name")" + if [ "$state" != "running" ]; then + echo "❌ Required infrastructure container is not running: $name ($state)" + exit 1 + fi +} + cd "$ROOT_DIR" cp "$ENV_FILE" "$ROOT_DIR/.env" mkdir -p "$ROOT_DIR/apps/web/public" [ -f "$ROOT_DIR/apps/web/public/.keep" ] || printf 'placeholder' > "$ROOT_DIR/apps/web/public/.keep" +ensure_container_running xiaoxia-postgres +ensure_container_running xiaoxia-redis + cd "$COMPOSE_DIR" WEB_PORT="${WEB_PORT:-3001}" export WEB_PORT docker compose build api worker web -docker compose up -d postgres redis api worker web +docker compose up -d api worker web docker compose ps diff --git a/infra/nginx/xiaoxia-saas.conf b/infra/nginx/xiaoxia-saas.conf index 1a5fa4d12..f5a29b327 100644 --- a/infra/nginx/xiaoxia-saas.conf +++ b/infra/nginx/xiaoxia-saas.conf @@ -24,7 +24,35 @@ server { # SaaS API location /api/ { - proxy_pass http://127.0.0.1:8000/api/; + proxy_pass http://127.0.0.1:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # API health and documentation + location = /health { + proxy_pass http://127.0.0.1:8000/health; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /docs { + proxy_pass http://127.0.0.1:8000/docs; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /openapi.json { + proxy_pass http://127.0.0.1:8000/openapi.json; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; diff --git a/infra/scripts/deploy.sh b/infra/scripts/deploy.sh index 00065a06a..eb09c6d83 100644 --- a/infra/scripts/deploy.sh +++ b/infra/scripts/deploy.sh @@ -15,7 +15,7 @@ docker compose up -d --no-deps api worker web # 4. 健康检查 echo "⏳ 等待服务启动..." for i in {1..30}; do - if docker exec xiaoxia-api-staging wget -q --spider http://localhost:8000/api/v1/health 2>/dev/null; then + if docker exec xiaoxia-api-staging wget -q --spider http://localhost:8000/health 2>/dev/null; then echo "✅ API 健康检查通过" break fi @@ -37,7 +37,7 @@ echo "✅ 部署完成!" echo "" echo "📍 服务访问地址:" echo " Web: https://api.xiaoxiajianji.com" -echo " API: https://api.xiaoxiajianji.com/api/v1/docs" +echo " API: https://api.xiaoxiajianji.com/docs" echo "" echo "📊 容器状态:" docker compose ps diff --git a/requirements.txt b/requirements.txt index 91d5eaee7..9c3357e23 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ pydantic-settings==2.6.0 # 数据库 psycopg2-binary==2.9.9 -psycopg==3.1.18 +psycopg[binary]==3.1.18 sqlalchemy==2.0.35 # 认证