Files
ai-platform/docs/deployment.md
T

7.0 KiB
Raw Blame History

AI Platform 打包部署指南

项目概况

项目 说明
项目名称 ai-platform
前端框架 React 18 + TypeScript + Vite 8
UI 库 Ant Design 5 + Tailwind CSS 3
构建产物 静态文件(dist/),由 nginx 提供服务
容器化 Docker 多阶段构建(builder → nginx:alpine)
部署端口 8901
后端代理 http://host.docker.internal:8000(可运行时覆盖)

目录结构要点

ai-platform/
├── Dockerfile          # 多阶段构建:node:20-alpine 构建 → nginx:alpine 运行
├── nginx.conf          # nginx 配置模板(支持 ${BACKEND_URL} 环境变量替换)
├── .dockerignore       # 排除 node_modules / dist / .git / *.md 等
├── package.json        # build 脚本:tsc -b && vite build
├── vite.config.ts      # 开发代理配置(/api/v1, /health, /bexapi, /iam-api)
├── index.html          # 入口 HTML
├── src/                # 源码
├── public/             # 静态资源
└── docs/               # 文档(本文件所在目录)

Docker 镜像构建

Dockerfile 构建流程

  1. Stage 1 — builder(node:20-alpine)

    • 复制 package.json + package-lock.json,执行 npm install
    • 复制全部源码,执行 npm run build(即 tsc -b && vite build)
    • 产物输出到 /app/dist
  2. Stage 2 — 运行时(nginx:alpine)

    • 将 builder 阶段的 /app/dist 复制到 /usr/share/nginx/html
    • 复制 nginx.conf 到 /etc/nginx/templates/default.conf.template(nginx 入口脚本会通过 envsubst 替换其中的 ${BACKEND_URL})
    • 默认环境变量 BACKEND_URL=http://host.docker.internal:8000
    • 暴露端口 8901

构建命令

sudo docker build -t ai-platform:1.0.0 .

构建过程利用了 Docker 缓存层:如果 package.json / package-lock.json 未变,npm install 层会命中缓存,仅重新执行源码复制和构建。

容器部署

启动命令

sudo docker run -d \
  --name ai-platform \
  -p 8901:8901 \
  --add-host=host.docker.internal:host-gateway \
  -e BACKEND_URL=http://host.docker.internal:8000 \
  ai-platform:1.0.0

参数说明

参数 说明
-d 后台运行
--name ai-platform 容器名称
-p 8901:8901 宿主机 8901 端口映射到容器 8901
--add-host=host.docker.internal:host-gateway 必须添加,否则 nginx 启动时无法解析 host.docker.internal,容器会立即退出(exit code 1)
-e BACKEND_URL=... 后端 API 地址,运行时可覆盖。默认 http://host.docker.internal:8000

踩坑记录:Docker 29.x 版本中,host.docker.internal 不会自动解析,必须通过 --add-host=host.docker.internal:host-gateway 显式添加。如果不加此参数,nginx 启动报错:host not found in upstream "host.docker.internal",容器退出码为 1。

重新部署(完整流程)

# 1. 构建新镜像
sudo docker build -t ai-platform:1.0.0 .

# 2. 停止并移除旧容器
sudo docker stop ai-platform
sudo docker rm ai-platform

# 3. 启动新容器
sudo docker run -d \
  --name ai-platform \
  -p 8901:8901 \
  --add-host=host.docker.internal:host-gateway \
  -e BACKEND_URL=http://host.docker.internal:8000 \
  ai-platform:1.0.0

验证部署

# 检查容器运行状态
sudo docker ps --filter "name=ai-platform"

# 从容器内部验证 nginx 响应
sudo docker exec ai-platform curl -s -o /dev/null -w "HTTP %{http_code}" http://localhost:8901/
# 预期输出:HTTP 200

# 查看页面内容
sudo docker exec ai-platform curl -s http://localhost:8901/

# 查看 nginx 日志
sudo docker logs ai-platform

nginx 配置说明

nginx.conf 作为模板文件放在 /etc/nginx/templates/default.conf.template,nginx 容器入口脚本会自动用 envsubst 将 ${BACKEND_URL} 替换为环境变量值,输出到 /etc/nginx/conf.d/default.conf。

路由规则

路径 代理目标 说明
/api/v1/ ${BACKEND_URL}/api/v1/ 后端 API,支持 SSE 长连接(关闭 buffering,300s 超时)
/health ${BACKEND_URL}/health 健康检查
/bexapi/ https://bexell-scheduling.dongsk.top/api/ Bexell 排程 API
/iam-api/ https://iam.digiwincloud.com.cn/ 鼎捷云 IAM 登录服务
/ try_files $uri $uri/ /index.html SPA 路由 fallback
/assets/ 本地静态文件 长缓存 1 年,Cache-Control: public, immutable
*.svg/png/jpg/... 本地静态文件 缓存 30 天

开发环境 vs 生产环境代理对照

开发时由 Vite dev server 代理(vite.config.ts),生产时由 nginx 代理(nginx.conf),两者路径需保持一致:

路径 Vite target nginx proxy_pass
/api/v1 http://localhost:8000 ${BACKEND_URL}/api/v1/
/health http://localhost:8000 ${BACKEND_URL}/health
/bexapi https://bexell-scheduling.dongsk.top(rewrite → /api) https://bexell-scheduling.dongsk.top/api/
/iam-api https://iam.digiwincloud.com.cn(rewrite → 去前缀) https://iam.digiwincloud.com.cn/

常见问题排查

容器启动后立即退出(exit code 1)

原因:nginx 无法解析 host.docker.internal。

解决:启动时添加 --add-host=host.docker.internal:host-gateway。

验证:sudo docker logs ai-platform 查看是否有 host not found in upstream 错误。

构建时 TypeScript 编译失败

npm run build 先执行 tsc -b 类型检查,类型错误会导致构建中断。需修复所有 TS 错误后重新构建。

构建产物体积过大

当前主 chunk 约 1.9MB(gzip 后 581KB),Vite 会输出警告。如需优化:

  • 使用动态 import() 对路由模块做懒加载(代码分割)
  • 在 vite.config.ts 中配置 build.rollupOptions.output.manualChunks 手动分包
  • 调整 build.chunkSizeWarningLimit 提高警告阈值(仅消除警告,不减小体积)

端口被占用

# 查看占用 8901 端口的进程
sudo lsof -i :8901

# 停止旧容器后释放端口
sudo docker stop ai-platform

快速部署脚本

将以下内容保存为 deploy.sh 即可一键重新打包部署:

#!/bin/bash
set -e

IMAGE_NAME="ai-platform:1.0.0"
CONTAINER_NAME="ai-platform"
PORT=8901
BACKEND_URL="${BACKEND_URL:-http://host.docker.internal:8000}"

echo ">>> 构建镜像..."
sudo docker build -t "$IMAGE_NAME" .

echo ">>> 停止旧容器..."
sudo docker stop "$CONTAINER_NAME" 2>/dev/null || true
sudo docker rm "$CONTAINER_NAME" 2>/dev/null || true

echo ">>> 启动新容器..."
sudo docker run -d \
  --name "$CONTAINER_NAME" \
  -p "$PORT:8901" \
  --add-host=host.docker.internal:host-gateway \
  -e BACKEND_URL="$BACKEND_URL" \
  "$IMAGE_NAME"

echo ">>> 验证..."
sleep 2
sudo docker exec "$CONTAINER_NAME" curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost:8901/

echo ">>> 部署完成: http://localhost:$PORT"