website-scripts/deploy-ai-readme.md

5.9 KiB
Raw Permalink Blame History

deploy-ai.sh — tlyq.ai 站点部署脚本

概述

deploy-ai.sh 将本地代码部署到 tlyq.ai 云服务器txjpIP: 43.133.38.210)。采用"源码上传 → 服务器构建"模式,本地不做生产构建。

核心流程:打包源码 → 上传至 txjp → 服务器 npm install + npm run build → 容器重启生效

用法

bash scripts/deploy-ai.sh [选项]
选项 说明
无参数 自动检测:初次构建 or 增量更新(源码快照比对)
--force 强制完整构建(跳过快照比对)
--restart 仅重启容器(跳过构建)
--init 强制初次完整构建

站点选择

脚本启动后显示交互式菜单:

编号 站点 容器 构建方式
1 www.tlyq.ai Next.js output: 'export' 静态站点
2 cloud.tlyq.ai 纯静态 HTML
3 token.tlyq.ai 纯静态 HTML
4 issue.tlyq.ai issue-ai Next.js standaloneDocker
5 assets.tlyq.ai assets-ai Next.js standaloneDocker
6 oa.tlyq.ai oa-ai Next.js standaloneDocker

部署流程

通用步骤

  1. 链接替换localhost → 正式域名www/cloud/token 站点OA 站点额外替换内部 API 地址)
  2. 快照比对:计算本地源码 MD5与服务器上次快照对比无变化则跳过构建
  3. 打包上传tar 打包(排除 node_modules.next.envscp 上传至 txjp
  4. 解压同步rsync 同步源码到目标目录
  5. 依赖安装:服务器 npm install --prefer-offline
  6. 环境变量:写入生产环境所需的环境变量到 .env
  7. 构建:服务器 npm run build
  8. 清理:删除 Alpine musl 残留sharp、swc
  9. 重启容器docker compose up -d + docker compose restart
  10. 快照保存:保存本次源码 MD5 用于下次比对

issue-ai 专属

  • 构建前写入 ASSETS_API_URL=http://assets-ai:3000/api
  • 构建前写入 NEXT_PUBLIC_ASSETS_URL=https://assets.tlyq.ai
  • 部署后自动验证 issue→assets API 连通性(见下方)

assets-ai 专属

  • 构建前写入 NEXT_PUBLIC_ISSUE_URL=https://issue.tlyq.ai/tickets
  • 构建前写入 ISSUE_API_URL=http://issue-ai:3000/api

OA 专属

  • 替换三类 URL前端导航卡片localhost → 生产域名)、服务端内部 APIlocalhost → 容器名)、退出登录重定向

部署后验证

部署后 API 连通性检查

部署 issue-ai 和 assets-ai 后自动执行双向连通性检查,均带 重试机制3 次、间隔 10s应对同时部署两个站点时目标容器暂不可达的情况。

部署站点 检查方向 使用 Key 目标 URL
issue-ai issue → assets ASSETS_API_KEY ASSETS_API_URL/assets?pageSize=1
assets-ai assets → issue ISSUE_API_KEY ISSUE_API_URL/tickets?pageSize=1

流程:

  1. 将连通性检查脚本发送到 txjp 宿主机
  2. docker cp 到对应容器内
  3. 容器内 Node.js 发起 HTTP 请求,失败自动重试(最多 3 次,间隔 10s
  4. 返回 200 → 通过;全部重试仍失败 → 部署失败退出

错误输出示例

[✗] issue→assets API 连通性检查失败!请检查 ASSETS_API_KEY 是否在 assets-ai 中注册
  连接失败: HTTP 401 (第1次)
  10s 后重试...
  连通失败: HTTP 401 (第2次)
  已达最大重试次数

排除文件

打包时排除以下目录和文件,不上传到服务器:

类别 排除项
依赖 node_modules
构建产物 .nextoutdata
环境配置 .env.env.local.env.development.env.production
版本控制 .git
文档 docs
报告 reports/*.docx
macOS ._*

部署后服务器上的 .env.local / .env.development / .env.production 会被自动删除,防止覆盖 .env 中的生产配置。

源码快照机制

脚本计算本地源码文件的组合 MD5保存到服务器的 /tmp/.snapshot.{site}.md5。下次部署时比对,若无变化则跳过构建仅重启容器。--force 可绕过此机制。

快照包含:所有源码文件(排除 node_modules.nextoutdatareportsdocs.env*.git)。

故障排查

构建失败

# 查看服务器构建日志
ssh txjp "tail -100 /tmp/build_output.txt"

容器启动失败

ssh txjp "docker logs {container}"

连通性检查失败

# 手动验证 issue→assets 连通性
ssh txjp "docker exec issue-ai sh -c 'cd /app && NODE_PATH=/app/node_modules node -e \"
  const http = require(\\\"http\\\");
  const url = process.env.ASSETS_API_URL + \\\"/assets?pageSize=1\\\";
  const key = process.env.ASSETS_API_KEY || \\\"\\\";
  http.get(url, {headers:{\\\"Authorization\\\":\\\"Bearer \\\"+key}}, (res) => {
    console.log(\\\"status:\\\", res.statusCode);
    process.exit(res.statusCode === 200 ? 0 : 1);
  }).on(\\\"error\\\", (e) => { console.error(e.message); process.exit(1); });
\"'"

# 确认 assets-ai 的 api_keys 表中是否有对应的 key
ssh txjp "docker exec assets-ai node -e \"
  const db = require('better-sqlite3')('/app/data/assets.db');
  const rows = db.prepare('SELECT id, name, is_active FROM api_keys').all();
  rows.forEach(r => console.log(JSON.stringify(r)));
\""

注意事项

  • 跨容器凭据:禁止在代码或配置中硬编码另一服务的密码,通过运行时读取源容器环境变量获取
  • 共享 JWT 密钥:所有 .tlyq.ai 子站点的 JWT_SECRETCOOKIE_DOMAIN 必须一致
  • 日期时区:系统统一 UTC+8禁止使用 toISOString()datetime('now')
  • nginx 重载:容器重启后需 docker restart nginx-ai 清除 DNS 缓存
  • 新增 npm 依赖:需重建 Docker 镜像(docker compose build --no-cache),因为容器内 /app/node_modules/ 来自镜像构建时