From 1fafaa1d03849fc058cce78c8af512c71ef6233b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?cls=5F=E5=AE=81=E6=B3=A2=E6=9C=AC=E6=9C=BA?= <908705107@qq.com> Date: Tue, 9 Jun 2026 11:32:34 +0800 Subject: [PATCH] Add non Docker deployment entrypoints --- .env.prod.example | 11 ++- .gitattributes | 6 ++ .gitignore | 3 +- docker-compose.prod.yml | 39 +++------ docker-compose.web-direct.yml | 34 +++----- docker-compose.yml | 51 +++++------- docker/nginx/conf.d/default.conf | 20 ++++- docker/web/Dockerfile | 35 ++++++++ docker/web/Dockerfile.direct | 11 +++ docker/web/index/.gitkeep | 1 + ops/ai-agent-admin.service | 21 +++++ ops/deploy-non-docker.sh | 106 ++++++++++++++++++++++++ ops/nginx-ai-agent-admin.locations.conf | 51 ++++++++++++ 13 files changed, 299 insertions(+), 90 deletions(-) create mode 100644 .gitattributes create mode 100644 docker/web/Dockerfile create mode 100644 docker/web/Dockerfile.direct create mode 100644 docker/web/index/.gitkeep create mode 100644 ops/ai-agent-admin.service create mode 100644 ops/deploy-non-docker.sh create mode 100644 ops/nginx-ai-agent-admin.locations.conf diff --git a/.env.prod.example b/.env.prod.example index 7ffde7a..55d67bb 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -1,5 +1,5 @@ # ========================================== -# ZQ Platform - 生产环境配置模板 +# AI Agent Admin - 生产环境配置模板 # 使用已有数据库和 Redis,不启动 postgres/redis 容器 # ========================================== # 使用方式: 复制此文件为 .env.prod,修改参数后运行: @@ -7,7 +7,7 @@ # ========================================== # 应用名称(也作为容器名/数据卷名/网络名的前缀,多实例部署时须不同) -APP_NAME=zq-platform +APP_NAME=ai-agent-admin # ========== 数据库配置 ========== # 数据库类型: postgresql / mysql / sqlserver @@ -17,7 +17,7 @@ DB_HOST=192.168.1.100 DB_PORT=5432 DB_USER=postgres DB_PASSWORD=your_strong_password -DB_NAME=zq_platform +DB_NAME=ai_agent_admin # ========== Redis 配置 ========== REDIS_HOST=192.168.1.100 @@ -39,13 +39,12 @@ FILE_STORAGE_LOCAL_PATH=/app/storage MINIO_ENDPOINT=192.168.1.100:9000 MINIO_ACCESS_KEY=minio_admin MINIO_SECRET_KEY=your_minio_secret -MINIO_BUCKET_NAME=zq-platform +MINIO_BUCKET_NAME=ai-agent-admin MINIO_SECURE=false # ========== 端口映射 ========== BACKEND_PORT_MAPPING=8000 WEB_PORT=80 -UNIAPP_PORT=90 # ========== 钉钉配置 ========== DINGTALK_REDIRECT_URI= @@ -57,4 +56,4 @@ WECOM_H5_REDIRECT_URI= # ========== 其他 ========== TIMEZONE=Asia/Shanghai -CACHE_PREFIX=zq-platform:prod: +CACHE_PREFIX=ai-agent-admin:prod: diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b405e5c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +*.sh text eol=lf +*.service text eol=lf +*.conf text eol=lf +*.yml text eol=lf +*.yaml text eol=lf +Dockerfile* text eol=lf diff --git a/.gitignore b/.gitignore index 56607bd..0aa0e63 100644 --- a/.gitignore +++ b/.gitignore @@ -177,8 +177,9 @@ node_modules # ai-agent-admin: exclude legacy generated bundles and removed heavy modules .ops-backups/ -docker/web/ docker/uniapp/ +docker/web/index/* +!docker/web/index/.gitkeep uniapp-zq/ web/apps/web-ele/src/components/screen-design/ web/apps/web-ele/src/components/form-design/ diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 91b7dfd..97d30f2 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,22 +1,22 @@ -name: ${APP_NAME:-zq-platform} +name: ${APP_NAME:-ai-agent-admin} services: backend: build: context: . dockerfile: docker/backend/Dockerfile - image: zq-platform-backend:latest - container_name: ${APP_NAME:-zq-platform}-backend + image: ai-agent-admin-backend:latest + container_name: ${APP_NAME:-ai-agent-admin}-backend restart: unless-stopped environment: ENV: prod - APP_NAME: ${APP_NAME:-zq-platform} + APP_NAME: ${APP_NAME:-ai-agent-admin} DB_TYPE: ${DB_TYPE:-postgresql} DB_HOST: ${DB_HOST:?请设置 DB_HOST 指向外部数据库地址} DB_PORT: ${DB_PORT:-5432} DB_USER: ${DB_USER:?请设置 DB_USER 数据库用户} DB_PASSWORD: ${DB_PASSWORD:?请设置 DB_PASSWORD 数据库密码} - DB_NAME: ${DB_NAME:-zq_platform} + DB_NAME: ${DB_NAME:-ai_agent_admin} REDIS_HOST: ${REDIS_HOST:?请设置 REDIS_HOST 指向外部 Redis 地址} REDIS_PORT: ${REDIS_PORT:-6379} REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123} @@ -32,7 +32,7 @@ services: MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-} MINIO_SECURE: ${MINIO_SECURE:-false} TIMEZONE: ${TIMEZONE:-Asia/Shanghai} - CACHE_PREFIX: ${CACHE_PREFIX:-zq-platform:prod:} + CACHE_PREFIX: ${CACHE_PREFIX:-ai-agent-admin:prod:} DINGTALK_REDIRECT_URI: ${DINGTALK_REDIRECT_URI:-} DINGTALK_H5_REDIRECT_URI: ${DINGTALK_H5_REDIRECT_URI:-} volumes: @@ -49,10 +49,11 @@ services: context: . dockerfile: docker/web/Dockerfile args: - VITE_GLOB_API_URL: /basic-api - VITE_APP_TITLE: ${APP_NAME:-zq-platform} - image: zq-platform-web:latest - container_name: ${APP_NAME:-zq-platform}-web + VITE_BASE: /ai-agent-admin/ + VITE_GLOB_API_URL: /ai-agent-admin/basic-api + VITE_APP_TITLE: ${APP_NAME:-AI Agent Admin} + image: ai-agent-admin-web:latest + container_name: ${APP_NAME:-ai-agent-admin}-web restart: unless-stopped depends_on: - backend @@ -61,25 +62,11 @@ services: networks: - zq-network - uniapp: - build: - context: . - dockerfile: docker/uniapp/Dockerfile - image: zq-platform-uniapp:latest - container_name: ${APP_NAME:-zq-platform}-uniapp - restart: unless-stopped - depends_on: - - backend - ports: - - "${UNIAPP_PORT:-90}:80" - networks: - - zq-network - volumes: backend_storage: - name: ${APP_NAME:-zq-platform}-backend-storage + name: ${APP_NAME:-ai-agent-admin}-backend-storage networks: zq-network: - name: ${APP_NAME:-zq-platform}-network + name: ${APP_NAME:-ai-agent-admin}-network driver: bridge diff --git a/docker-compose.web-direct.yml b/docker-compose.web-direct.yml index eb42799..a159202 100644 --- a/docker-compose.web-direct.yml +++ b/docker-compose.web-direct.yml @@ -1,22 +1,22 @@ -name: ${APP_NAME:-zq-platform} +name: ${APP_NAME:-ai-agent-admin} services: backend: build: context: . dockerfile: docker/backend/Dockerfile - image: zq-platform-backend:latest - container_name: ${APP_NAME:-zq-platform}-backend + image: ai-agent-admin-backend:latest + container_name: ${APP_NAME:-ai-agent-admin}-backend restart: unless-stopped environment: ENV: prod - APP_NAME: ${APP_NAME:-zq-platform} + APP_NAME: ${APP_NAME:-ai-agent-admin} DB_TYPE: ${DB_TYPE:-postgresql} DB_HOST: ${DB_HOST:?请设置 DB_HOST 指向外部数据库地址} DB_PORT: ${DB_PORT:-5432} DB_USER: ${DB_USER:?请设置 DB_USER 数据库用户} DB_PASSWORD: ${DB_PASSWORD:?请设置 DB_PASSWORD 数据库密码} - DB_NAME: ${DB_NAME:-zq_platform} + DB_NAME: ${DB_NAME:-ai_agent_admin} REDIS_HOST: ${REDIS_HOST:?请设置 REDIS_HOST 指向外部 Redis 地址} REDIS_PORT: ${REDIS_PORT:-6379} REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123} @@ -32,7 +32,7 @@ services: MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-} MINIO_SECURE: ${MINIO_SECURE:-false} TIMEZONE: ${TIMEZONE:-Asia/Shanghai} - CACHE_PREFIX: ${CACHE_PREFIX:-zq-platform:prod:} + CACHE_PREFIX: ${CACHE_PREFIX:-ai-agent-admin:prod:} DINGTALK_REDIRECT_URI: ${DINGTALK_REDIRECT_URI:-} DINGTALK_H5_REDIRECT_URI: ${DINGTALK_H5_REDIRECT_URI:-} volumes: @@ -48,8 +48,8 @@ services: build: context: . dockerfile: docker/web/Dockerfile.direct - image: zq-platform-web-direct:latest - container_name: ${APP_NAME:-zq-platform}-web + image: ai-agent-admin-web-direct:latest + container_name: ${APP_NAME:-ai-agent-admin}-web restart: unless-stopped depends_on: - backend @@ -58,25 +58,11 @@ services: networks: - zq-network - uniapp: - build: - context: . - dockerfile: docker/uniapp/Dockerfile - image: zq-platform-uniapp:latest - container_name: ${APP_NAME:-zq-platform}-uniapp - restart: unless-stopped - depends_on: - - backend - ports: - - "${UNIAPP_PORT:-90}:80" - networks: - - zq-network - volumes: backend_storage: - name: ${APP_NAME:-zq-platform}-backend-storage + name: ${APP_NAME:-ai-agent-admin}-backend-storage networks: zq-network: - name: ${APP_NAME:-zq-platform}-network + name: ${APP_NAME:-ai-agent-admin}-network driver: bridge diff --git a/docker-compose.yml b/docker-compose.yml index ebfabb6..8639764 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,18 @@ -name: ${APP_NAME:-zq-platform} +name: ${APP_NAME:-ai-agent-admin} services: postgres: image: postgres:16-alpine - container_name: ${APP_NAME:-zq-platform}-postgres + container_name: ${APP_NAME:-ai-agent-admin}-postgres restart: unless-stopped volumes: - postgres_data:/var/lib/postgresql/data environment: - POSTGRES_DB: ${DB_NAME:-zq_platform} + POSTGRES_DB: ${DB_NAME:-ai_agent_admin} POSTGRES_USER: ${DB_USER:-postgres} POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres} healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-zq_platform}"] + test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-ai_agent_admin}"] interval: 10s timeout: 5s retries: 5 @@ -24,7 +24,7 @@ services: redis: image: redis:7-alpine - container_name: ${APP_NAME:-zq-platform}-redis + container_name: ${APP_NAME:-ai-agent-admin}-redis restart: unless-stopped volumes: - redis_data:/data @@ -43,8 +43,8 @@ services: build: context: . dockerfile: docker/backend/Dockerfile - image: zq-platform-backend:latest - container_name: ${APP_NAME:-zq-platform}-backend + image: ai-agent-admin-backend:latest + container_name: ${APP_NAME:-ai-agent-admin}-backend restart: unless-stopped depends_on: postgres: @@ -53,13 +53,13 @@ services: condition: service_healthy environment: ENV: prod - APP_NAME: ${APP_NAME:-zq-platform} + APP_NAME: ${APP_NAME:-ai-agent-admin} DB_TYPE: postgresql DB_HOST: postgres DB_PORT: 5432 DB_USER: ${DB_USER:-postgres} DB_PASSWORD: ${DB_PASSWORD:-postgres} - DB_NAME: ${DB_NAME:-zq_platform} + DB_NAME: ${DB_NAME:-ai_agent_admin} REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123} @@ -75,7 +75,7 @@ services: MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-} MINIO_SECURE: ${MINIO_SECURE:-false} TIMEZONE: ${TIMEZONE:-Asia/Shanghai} - CACHE_PREFIX: ${CACHE_PREFIX:-zq-platform:prod:} + CACHE_PREFIX: ${CACHE_PREFIX:-ai-agent-admin:prod:} DINGTALK_REDIRECT_URI: ${DINGTALK_REDIRECT_URI:-} DINGTALK_H5_REDIRECT_URI: ${DINGTALK_H5_REDIRECT_URI:-} volumes: @@ -92,10 +92,11 @@ services: context: . dockerfile: docker/web/Dockerfile args: - VITE_GLOB_API_URL: /basic-api - VITE_APP_TITLE: ${APP_NAME:-zq-platform} - image: zq-platform-web:latest - container_name: ${APP_NAME:-zq-platform}-web + VITE_BASE: /ai-agent-admin/ + VITE_GLOB_API_URL: /ai-agent-admin/basic-api + VITE_APP_TITLE: ${APP_NAME:-AI Agent Admin} + image: ai-agent-admin-web:latest + container_name: ${APP_NAME:-ai-agent-admin}-web restart: unless-stopped depends_on: - backend @@ -104,29 +105,15 @@ services: networks: - zq-network - uniapp: - build: - context: . - dockerfile: docker/uniapp/Dockerfile - image: zq-platform-uniapp:latest - container_name: ${APP_NAME:-zq-platform}-uniapp - restart: unless-stopped - depends_on: - - backend - ports: - - "${UNIAPP_PORT:-90}:80" - networks: - - zq-network - volumes: postgres_data: - name: ${APP_NAME:-zq-platform}-postgres-data + name: ${APP_NAME:-ai-agent-admin}-postgres-data redis_data: - name: ${APP_NAME:-zq-platform}-redis-data + name: ${APP_NAME:-ai-agent-admin}-redis-data backend_storage: - name: ${APP_NAME:-zq-platform}-backend-storage + name: ${APP_NAME:-ai-agent-admin}-backend-storage networks: zq-network: - name: ${APP_NAME:-zq-platform}-network + name: ${APP_NAME:-ai-agent-admin}-network driver: bridge diff --git a/docker/nginx/conf.d/default.conf b/docker/nginx/conf.d/default.conf index 589cc64..979f21b 100644 --- a/docker/nginx/conf.d/default.conf +++ b/docker/nginx/conf.d/default.conf @@ -11,6 +11,18 @@ server { gzip_vary on; gzip_proxied any; + location /ai-agent-admin/basic-api/ { + rewrite ^/ai-agent-admin/basic-api/(.*) /$1 break; + proxy_pass http://backend:8000; + 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; + proxy_connect_timeout 60s; + proxy_read_timeout 60s; + proxy_send_timeout 60s; + } + location /basic-api/ { rewrite ^/basic-api/(.*) /$1 break; proxy_pass http://backend:8000; @@ -42,6 +54,12 @@ server { add_header Cache-Control "no-cache, no-store, must-revalidate"; } + location /ai-agent-admin/ { + try_files $uri $uri/ /ai-agent-admin/index.html; + expires -1; + add_header Cache-Control "no-cache, no-store, must-revalidate"; + } + location /assets/ { expires 1y; add_header Cache-Control "public, immutable"; @@ -53,7 +71,7 @@ server { log_not_found off; } - error_page 404 /index.html; + error_page 404 /ai-agent-admin/index.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; diff --git a/docker/web/Dockerfile b/docker/web/Dockerfile new file mode 100644 index 0000000..b6031ff --- /dev/null +++ b/docker/web/Dockerfile @@ -0,0 +1,35 @@ +FROM node:22-alpine AS builder + +WORKDIR /app + +ENV PNPM_HOME=/pnpm \ + PATH=/pnpm:$PATH \ + NODE_OPTIONS=--max-old-space-size=4096 + +RUN corepack enable + +COPY web/ ./ + +RUN pnpm install --frozen-lockfile + +ARG VITE_APP_TITLE=AI Agent Admin +ARG VITE_BASE=/ai-agent-admin/ +ARG VITE_GLOB_API_URL=/ai-agent-admin/basic-api + +ENV VITE_APP_TITLE=$VITE_APP_TITLE \ + VITE_BASE=$VITE_BASE \ + VITE_GLOB_API_URL=$VITE_GLOB_API_URL \ + VITE_COMPRESS=none \ + VITE_PWA=false + +RUN pnpm --filter @vben/web-ele build + +FROM nginx:1.27-alpine + +COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf +COPY docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf +COPY --from=builder /app/apps/web-ele/dist/ /usr/share/nginx/html/ai-agent-admin/ + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker/web/Dockerfile.direct b/docker/web/Dockerfile.direct new file mode 100644 index 0000000..eabe409 --- /dev/null +++ b/docker/web/Dockerfile.direct @@ -0,0 +1,11 @@ +FROM nginx:1.27-alpine + +COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf +COPY docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf +COPY docker/web/index/ /usr/share/nginx/html/ai-agent-admin/ + +RUN test -f /usr/share/nginx/html/ai-agent-admin/index.html + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker/web/index/.gitkeep b/docker/web/index/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/docker/web/index/.gitkeep @@ -0,0 +1 @@ + diff --git a/ops/ai-agent-admin.service b/ops/ai-agent-admin.service new file mode 100644 index 0000000..03f3424 --- /dev/null +++ b/ops/ai-agent-admin.service @@ -0,0 +1,21 @@ +[Unit] +Description=AI Agent Admin FastAPI +After=network.target + +[Service] +Type=simple +User=www-data +Group=www-data +WorkingDirectory=/opt/ai-agent-admin/current/backend-fastapi +Environment=ENV=prod +Environment=PYTHONPATH=/opt/ai-agent-admin/current/backend-fastapi +Environment=APP_HOST=127.0.0.1 +Environment=APP_PORT=8001 +EnvironmentFile=/opt/ai-agent-admin/current/backend-fastapi/env/prod.env +ExecStart=/opt/ai-agent-admin/current/backend-fastapi/.venv/bin/python -m uvicorn main:app --host 127.0.0.1 --port 8001 --workers 4 +Restart=always +RestartSec=5 +KillSignal=SIGINT + +[Install] +WantedBy=multi-user.target diff --git a/ops/deploy-non-docker.sh b/ops/deploy-non-docker.sh new file mode 100644 index 0000000..f06c6e1 --- /dev/null +++ b/ops/deploy-non-docker.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +set -euo pipefail + +APP_NAME="${APP_NAME:-ai-agent-admin}" +PROJECT_DIR="${PROJECT_DIR:-/opt/ai-agent-admin/current}" +BACKEND_DIR="${BACKEND_DIR:-${PROJECT_DIR}/backend-fastapi}" +WEB_DIST_DIR="${WEB_DIST_DIR:-${PROJECT_DIR}/web/apps/web-ele/dist}" +WEB_ROOT="${WEB_ROOT:-/var/www/ai-agent-admin}" +SERVICE_NAME="${SERVICE_NAME:-ai-agent-admin}" +PYTHON_BIN="${PYTHON_BIN:-python3}" +ENV_FILE="${ENV_FILE:-${BACKEND_DIR}/env/prod.env}" +BACKEND_PORT="${BACKEND_PORT:-8001}" +RUN_MIGRATIONS="${RUN_MIGRATIONS:-1}" +IMPORT_INIT_DATA="${IMPORT_INIT_DATA:-auto}" +BUILD_WEB="${BUILD_WEB:-0}" + +log() { + printf '[%s] %s\n' "${APP_NAME}" "$*" +} + +require_file() { + if [ ! -f "$1" ]; then + printf 'Missing required file: %s\n' "$1" >&2 + exit 1 + fi +} + +require_dir() { + if [ ! -d "$1" ]; then + printf 'Missing required directory: %s\n' "$1" >&2 + exit 1 + fi +} + +require_dir "${PROJECT_DIR}" +require_dir "${BACKEND_DIR}" +require_file "${ENV_FILE}" + +if [ "${BUILD_WEB}" = "1" ]; then + log "building web-ele" + (cd "${PROJECT_DIR}/web" && pnpm --filter @vben/web-ele build) +fi + +require_file "${WEB_DIST_DIR}/index.html" + +log "publishing web dist to ${WEB_ROOT}" +install -d "${WEB_ROOT}" +rsync -a --delete "${WEB_DIST_DIR}/" "${WEB_ROOT}/" + +log "preparing backend venv" +cd "${BACKEND_DIR}" +if [ ! -x ".venv/bin/python" ]; then + "${PYTHON_BIN}" -m venv .venv +fi + +# shellcheck source=/dev/null +. .venv/bin/activate +python -m pip install --upgrade pip +python -m pip install -r requirements.txt + +if [ "${RUN_MIGRATIONS}" = "1" ]; then + log "running alembic migrations" + ENV=prod python -m alembic upgrade head +fi + +if [ "${IMPORT_INIT_DATA}" = "auto" ]; then + USER_COUNT="$( + ENV=prod python - <<'PY' +import asyncio +from sqlalchemy import text +from app.database import AsyncSessionLocal + +async def main(): + try: + async with AsyncSessionLocal() as db: + result = await db.execute(text("SELECT COUNT(*) FROM core_user")) + print(result.scalar() or 0) + except Exception: + print(0) + +asyncio.run(main()) +PY + )" + if [ "${USER_COUNT}" = "0" ] && [ -f "db_init.json" ]; then + log "importing initial data" + ENV=prod python scripts/loaddata.py db_init.json + fi +fi + +log "restarting ${SERVICE_NAME}" +if command -v systemctl >/dev/null 2>&1; then + systemctl daemon-reload + systemctl restart "${SERVICE_NAME}" +fi + +if command -v nginx >/dev/null 2>&1; then + log "reloading nginx" + nginx -t + if command -v systemctl >/dev/null 2>&1; then + systemctl reload nginx + else + nginx -s reload + fi +fi + +log "done: backend port ${BACKEND_PORT}, web root ${WEB_ROOT}" diff --git a/ops/nginx-ai-agent-admin.locations.conf b/ops/nginx-ai-agent-admin.locations.conf new file mode 100644 index 0000000..29d2e23 --- /dev/null +++ b/ops/nginx-ai-agent-admin.locations.conf @@ -0,0 +1,51 @@ +location = /ai-agent-admin { + return 301 /ai-agent-admin/; +} + +location ^~ /ai-agent-admin/basic-api/ { + proxy_pass http://127.0.0.1:8001/; + 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; + proxy_connect_timeout 60s; + proxy_read_timeout 300s; + proxy_send_timeout 300s; +} + +location ^~ /basic-api/ { + proxy_pass http://127.0.0.1:8001/; + 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; + proxy_connect_timeout 60s; + proxy_read_timeout 300s; + proxy_send_timeout 300s; +} + +location ^~ /ws { + proxy_pass http://127.0.0.1:8001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + 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; + proxy_read_timeout 3600s; + proxy_send_timeout 3600s; +} + +location ^~ /ai-agent-admin/assets/ { + root /var/www; + expires 1y; + add_header Cache-Control "public, immutable"; +} + +location ^~ /ai-agent-admin/ { + root /var/www; + try_files $uri $uri/ /ai-agent-admin/index.html; + expires -1; + add_header Cache-Control "no-cache, no-store, must-revalidate"; +}