Add non Docker deployment entrypoints

This commit is contained in:
2026-06-09 11:32:34 +08:00
parent fe0133edc4
commit 1fafaa1d03
13 changed files with 299 additions and 90 deletions
+5 -6
View File
@@ -1,5 +1,5 @@
# ========================================== # ==========================================
# ZQ Platform - 生产环境配置模板 # AI Agent Admin - 生产环境配置模板
# 使用已有数据库和 Redis,不启动 postgres/redis 容器 # 使用已有数据库和 Redis,不启动 postgres/redis 容器
# ========================================== # ==========================================
# 使用方式: 复制此文件为 .env.prod,修改参数后运行: # 使用方式: 复制此文件为 .env.prod,修改参数后运行:
@@ -7,7 +7,7 @@
# ========================================== # ==========================================
# 应用名称(也作为容器名/数据卷名/网络名的前缀,多实例部署时须不同) # 应用名称(也作为容器名/数据卷名/网络名的前缀,多实例部署时须不同)
APP_NAME=zq-platform APP_NAME=ai-agent-admin
# ========== 数据库配置 ========== # ========== 数据库配置 ==========
# 数据库类型: postgresql / mysql / sqlserver # 数据库类型: postgresql / mysql / sqlserver
@@ -17,7 +17,7 @@ DB_HOST=192.168.1.100
DB_PORT=5432 DB_PORT=5432
DB_USER=postgres DB_USER=postgres
DB_PASSWORD=your_strong_password DB_PASSWORD=your_strong_password
DB_NAME=zq_platform DB_NAME=ai_agent_admin
# ========== Redis 配置 ========== # ========== Redis 配置 ==========
REDIS_HOST=192.168.1.100 REDIS_HOST=192.168.1.100
@@ -39,13 +39,12 @@ FILE_STORAGE_LOCAL_PATH=/app/storage
MINIO_ENDPOINT=192.168.1.100:9000 MINIO_ENDPOINT=192.168.1.100:9000
MINIO_ACCESS_KEY=minio_admin MINIO_ACCESS_KEY=minio_admin
MINIO_SECRET_KEY=your_minio_secret MINIO_SECRET_KEY=your_minio_secret
MINIO_BUCKET_NAME=zq-platform MINIO_BUCKET_NAME=ai-agent-admin
MINIO_SECURE=false MINIO_SECURE=false
# ========== 端口映射 ========== # ========== 端口映射 ==========
BACKEND_PORT_MAPPING=8000 BACKEND_PORT_MAPPING=8000
WEB_PORT=80 WEB_PORT=80
UNIAPP_PORT=90
# ========== 钉钉配置 ========== # ========== 钉钉配置 ==========
DINGTALK_REDIRECT_URI= DINGTALK_REDIRECT_URI=
@@ -57,4 +56,4 @@ WECOM_H5_REDIRECT_URI=
# ========== 其他 ========== # ========== 其他 ==========
TIMEZONE=Asia/Shanghai TIMEZONE=Asia/Shanghai
CACHE_PREFIX=zq-platform:prod: CACHE_PREFIX=ai-agent-admin:prod:
+6
View File
@@ -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
+2 -1
View File
@@ -177,8 +177,9 @@ node_modules
# ai-agent-admin: exclude legacy generated bundles and removed heavy modules # ai-agent-admin: exclude legacy generated bundles and removed heavy modules
.ops-backups/ .ops-backups/
docker/web/
docker/uniapp/ docker/uniapp/
docker/web/index/*
!docker/web/index/.gitkeep
uniapp-zq/ uniapp-zq/
web/apps/web-ele/src/components/screen-design/ web/apps/web-ele/src/components/screen-design/
web/apps/web-ele/src/components/form-design/ web/apps/web-ele/src/components/form-design/
+13 -26
View File
@@ -1,22 +1,22 @@
name: ${APP_NAME:-zq-platform} name: ${APP_NAME:-ai-agent-admin}
services: services:
backend: backend:
build: build:
context: . context: .
dockerfile: docker/backend/Dockerfile dockerfile: docker/backend/Dockerfile
image: zq-platform-backend:latest image: ai-agent-admin-backend:latest
container_name: ${APP_NAME:-zq-platform}-backend container_name: ${APP_NAME:-ai-agent-admin}-backend
restart: unless-stopped restart: unless-stopped
environment: environment:
ENV: prod ENV: prod
APP_NAME: ${APP_NAME:-zq-platform} APP_NAME: ${APP_NAME:-ai-agent-admin}
DB_TYPE: ${DB_TYPE:-postgresql} DB_TYPE: ${DB_TYPE:-postgresql}
DB_HOST: ${DB_HOST:?请设置 DB_HOST 指向外部数据库地址} DB_HOST: ${DB_HOST:?请设置 DB_HOST 指向外部数据库地址}
DB_PORT: ${DB_PORT:-5432} DB_PORT: ${DB_PORT:-5432}
DB_USER: ${DB_USER:?请设置 DB_USER 数据库用户} DB_USER: ${DB_USER:?请设置 DB_USER 数据库用户}
DB_PASSWORD: ${DB_PASSWORD:?请设置 DB_PASSWORD 数据库密码} 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_HOST: ${REDIS_HOST:?请设置 REDIS_HOST 指向外部 Redis 地址}
REDIS_PORT: ${REDIS_PORT:-6379} REDIS_PORT: ${REDIS_PORT:-6379}
REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123} REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123}
@@ -32,7 +32,7 @@ services:
MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-} MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-}
MINIO_SECURE: ${MINIO_SECURE:-false} MINIO_SECURE: ${MINIO_SECURE:-false}
TIMEZONE: ${TIMEZONE:-Asia/Shanghai} 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_REDIRECT_URI: ${DINGTALK_REDIRECT_URI:-}
DINGTALK_H5_REDIRECT_URI: ${DINGTALK_H5_REDIRECT_URI:-} DINGTALK_H5_REDIRECT_URI: ${DINGTALK_H5_REDIRECT_URI:-}
volumes: volumes:
@@ -49,10 +49,11 @@ services:
context: . context: .
dockerfile: docker/web/Dockerfile dockerfile: docker/web/Dockerfile
args: args:
VITE_GLOB_API_URL: /basic-api VITE_BASE: /ai-agent-admin/
VITE_APP_TITLE: ${APP_NAME:-zq-platform} VITE_GLOB_API_URL: /ai-agent-admin/basic-api
image: zq-platform-web:latest VITE_APP_TITLE: ${APP_NAME:-AI Agent Admin}
container_name: ${APP_NAME:-zq-platform}-web image: ai-agent-admin-web:latest
container_name: ${APP_NAME:-ai-agent-admin}-web
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- backend - backend
@@ -61,25 +62,11 @@ services:
networks: networks:
- zq-network - 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: volumes:
backend_storage: backend_storage:
name: ${APP_NAME:-zq-platform}-backend-storage name: ${APP_NAME:-ai-agent-admin}-backend-storage
networks: networks:
zq-network: zq-network:
name: ${APP_NAME:-zq-platform}-network name: ${APP_NAME:-ai-agent-admin}-network
driver: bridge driver: bridge
+10 -24
View File
@@ -1,22 +1,22 @@
name: ${APP_NAME:-zq-platform} name: ${APP_NAME:-ai-agent-admin}
services: services:
backend: backend:
build: build:
context: . context: .
dockerfile: docker/backend/Dockerfile dockerfile: docker/backend/Dockerfile
image: zq-platform-backend:latest image: ai-agent-admin-backend:latest
container_name: ${APP_NAME:-zq-platform}-backend container_name: ${APP_NAME:-ai-agent-admin}-backend
restart: unless-stopped restart: unless-stopped
environment: environment:
ENV: prod ENV: prod
APP_NAME: ${APP_NAME:-zq-platform} APP_NAME: ${APP_NAME:-ai-agent-admin}
DB_TYPE: ${DB_TYPE:-postgresql} DB_TYPE: ${DB_TYPE:-postgresql}
DB_HOST: ${DB_HOST:?请设置 DB_HOST 指向外部数据库地址} DB_HOST: ${DB_HOST:?请设置 DB_HOST 指向外部数据库地址}
DB_PORT: ${DB_PORT:-5432} DB_PORT: ${DB_PORT:-5432}
DB_USER: ${DB_USER:?请设置 DB_USER 数据库用户} DB_USER: ${DB_USER:?请设置 DB_USER 数据库用户}
DB_PASSWORD: ${DB_PASSWORD:?请设置 DB_PASSWORD 数据库密码} 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_HOST: ${REDIS_HOST:?请设置 REDIS_HOST 指向外部 Redis 地址}
REDIS_PORT: ${REDIS_PORT:-6379} REDIS_PORT: ${REDIS_PORT:-6379}
REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123} REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123}
@@ -32,7 +32,7 @@ services:
MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-} MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-}
MINIO_SECURE: ${MINIO_SECURE:-false} MINIO_SECURE: ${MINIO_SECURE:-false}
TIMEZONE: ${TIMEZONE:-Asia/Shanghai} 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_REDIRECT_URI: ${DINGTALK_REDIRECT_URI:-}
DINGTALK_H5_REDIRECT_URI: ${DINGTALK_H5_REDIRECT_URI:-} DINGTALK_H5_REDIRECT_URI: ${DINGTALK_H5_REDIRECT_URI:-}
volumes: volumes:
@@ -48,8 +48,8 @@ services:
build: build:
context: . context: .
dockerfile: docker/web/Dockerfile.direct dockerfile: docker/web/Dockerfile.direct
image: zq-platform-web-direct:latest image: ai-agent-admin-web-direct:latest
container_name: ${APP_NAME:-zq-platform}-web container_name: ${APP_NAME:-ai-agent-admin}-web
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- backend - backend
@@ -58,25 +58,11 @@ services:
networks: networks:
- zq-network - 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: volumes:
backend_storage: backend_storage:
name: ${APP_NAME:-zq-platform}-backend-storage name: ${APP_NAME:-ai-agent-admin}-backend-storage
networks: networks:
zq-network: zq-network:
name: ${APP_NAME:-zq-platform}-network name: ${APP_NAME:-ai-agent-admin}-network
driver: bridge driver: bridge
+19 -32
View File
@@ -1,18 +1,18 @@
name: ${APP_NAME:-zq-platform} name: ${APP_NAME:-ai-agent-admin}
services: services:
postgres: postgres:
image: postgres:16-alpine image: postgres:16-alpine
container_name: ${APP_NAME:-zq-platform}-postgres container_name: ${APP_NAME:-ai-agent-admin}-postgres
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- postgres_data:/var/lib/postgresql/data - postgres_data:/var/lib/postgresql/data
environment: environment:
POSTGRES_DB: ${DB_NAME:-zq_platform} POSTGRES_DB: ${DB_NAME:-ai_agent_admin}
POSTGRES_USER: ${DB_USER:-postgres} POSTGRES_USER: ${DB_USER:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres} POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
healthcheck: 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 interval: 10s
timeout: 5s timeout: 5s
retries: 5 retries: 5
@@ -24,7 +24,7 @@ services:
redis: redis:
image: redis:7-alpine image: redis:7-alpine
container_name: ${APP_NAME:-zq-platform}-redis container_name: ${APP_NAME:-ai-agent-admin}-redis
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- redis_data:/data - redis_data:/data
@@ -43,8 +43,8 @@ services:
build: build:
context: . context: .
dockerfile: docker/backend/Dockerfile dockerfile: docker/backend/Dockerfile
image: zq-platform-backend:latest image: ai-agent-admin-backend:latest
container_name: ${APP_NAME:-zq-platform}-backend container_name: ${APP_NAME:-ai-agent-admin}-backend
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
postgres: postgres:
@@ -53,13 +53,13 @@ services:
condition: service_healthy condition: service_healthy
environment: environment:
ENV: prod ENV: prod
APP_NAME: ${APP_NAME:-zq-platform} APP_NAME: ${APP_NAME:-ai-agent-admin}
DB_TYPE: postgresql DB_TYPE: postgresql
DB_HOST: postgres DB_HOST: postgres
DB_PORT: 5432 DB_PORT: 5432
DB_USER: ${DB_USER:-postgres} DB_USER: ${DB_USER:-postgres}
DB_PASSWORD: ${DB_PASSWORD:-postgres} DB_PASSWORD: ${DB_PASSWORD:-postgres}
DB_NAME: ${DB_NAME:-zq_platform} DB_NAME: ${DB_NAME:-ai_agent_admin}
REDIS_HOST: redis REDIS_HOST: redis
REDIS_PORT: 6379 REDIS_PORT: 6379
REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123} REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123}
@@ -75,7 +75,7 @@ services:
MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-} MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-}
MINIO_SECURE: ${MINIO_SECURE:-false} MINIO_SECURE: ${MINIO_SECURE:-false}
TIMEZONE: ${TIMEZONE:-Asia/Shanghai} 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_REDIRECT_URI: ${DINGTALK_REDIRECT_URI:-}
DINGTALK_H5_REDIRECT_URI: ${DINGTALK_H5_REDIRECT_URI:-} DINGTALK_H5_REDIRECT_URI: ${DINGTALK_H5_REDIRECT_URI:-}
volumes: volumes:
@@ -92,10 +92,11 @@ services:
context: . context: .
dockerfile: docker/web/Dockerfile dockerfile: docker/web/Dockerfile
args: args:
VITE_GLOB_API_URL: /basic-api VITE_BASE: /ai-agent-admin/
VITE_APP_TITLE: ${APP_NAME:-zq-platform} VITE_GLOB_API_URL: /ai-agent-admin/basic-api
image: zq-platform-web:latest VITE_APP_TITLE: ${APP_NAME:-AI Agent Admin}
container_name: ${APP_NAME:-zq-platform}-web image: ai-agent-admin-web:latest
container_name: ${APP_NAME:-ai-agent-admin}-web
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- backend - backend
@@ -104,29 +105,15 @@ services:
networks: networks:
- zq-network - 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: volumes:
postgres_data: postgres_data:
name: ${APP_NAME:-zq-platform}-postgres-data name: ${APP_NAME:-ai-agent-admin}-postgres-data
redis_data: redis_data:
name: ${APP_NAME:-zq-platform}-redis-data name: ${APP_NAME:-ai-agent-admin}-redis-data
backend_storage: backend_storage:
name: ${APP_NAME:-zq-platform}-backend-storage name: ${APP_NAME:-ai-agent-admin}-backend-storage
networks: networks:
zq-network: zq-network:
name: ${APP_NAME:-zq-platform}-network name: ${APP_NAME:-ai-agent-admin}-network
driver: bridge driver: bridge
+19 -1
View File
@@ -11,6 +11,18 @@ server {
gzip_vary on; gzip_vary on;
gzip_proxied any; 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/ { location /basic-api/ {
rewrite ^/basic-api/(.*) /$1 break; rewrite ^/basic-api/(.*) /$1 break;
proxy_pass http://backend:8000; proxy_pass http://backend:8000;
@@ -42,6 +54,12 @@ server {
add_header Cache-Control "no-cache, no-store, must-revalidate"; 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/ { location /assets/ {
expires 1y; expires 1y;
add_header Cache-Control "public, immutable"; add_header Cache-Control "public, immutable";
@@ -53,7 +71,7 @@ server {
log_not_found off; 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; error_page 500 502 503 504 /50x.html;
location = /50x.html { location = /50x.html {
root /usr/share/nginx/html; root /usr/share/nginx/html;
+35
View File
@@ -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;"]
+11
View File
@@ -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;"]
+1
View File
@@ -0,0 +1 @@
+21
View File
@@ -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
+106
View File
@@ -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}"
+51
View File
@@ -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";
}