diff --git a/CLAUDE.md b/CLAUDE.md index bb4af47..ed8f95f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -231,35 +231,34 @@ ssh root@192.168.58.20 "cat /root/youyidian-3d/.env 2>/dev/null || echo 'No .env ## 部署 -项目使用 **远程构建部署** 方式,通过 PowerShell 脚本: +当前默认使用 **Git 增量部署**,统一通过 `scripts/git-incremental-deploy.ps1` 执行: ```powershell +# 预检 +.\scripts\git-incremental-deploy.ps1 -DryRun + # 部署到生产环境 -.\deploy-remote-build.ps1 +.\scripts\git-incremental-deploy.ps1 # 部署到影子环境 -.\deploy-remote-build.ps1 -Target shadow - -# 强制重新构建(无缓存) -.\deploy-remote-build.ps1 -NoCache - -# 深度清理构建缓存(默认保留缓存以加快构建) -.\deploy-remote-build.ps1 -AggressiveBuildCacheCleanup +.\scripts\git-incremental-deploy.ps1 -Target shadow ``` -**部署流程:** -1. 本地打包代码(排除 node_modules、.next、.git) -2. 上传到构建服务器 (192.168.42.134) -3. 在构建服务器上构建 Docker 镜像 -4. 推送到本地镜像仓库 (192.168.42.134:5000) -5. 拉取到生产服务器 (192.168.58.20) -6. 在端口 4320(生产)或 5320(影子)启动容器 +**当前部署流程:** +1. 源码先提交并推送到 Git 仓库 +2. 构建服务器 (192.168.42.134) 增量拉取指定提交 +3. 构建服务器构建 Docker 镜像并推送到本地镜像仓库 (192.168.42.134:5000) +4. 生产服务器 (192.168.58.20) 拉取指定提交镜像 +5. 替换正式容器或影子容器 +6. 检查 `/api/health`,失败时默认尝试回滚旧镜像 -**部署脚本优化(2026-05-05):** -- 默认保留构建缓存,加快小改动的构建速度 -- 打包完整性校验:SHA256 哈希验证 -- Alpine 镜像源:使用清华源 `https://mirrors.tuna.tsinghua.edu.cn/alpine` -- 临时文件处理:避免 `tar: .: file changed as we read it` 错误 +`deploy-remote-build.ps1` 属于本地历史脚本名,仅作为识别应急资料使用,不是仓库交付入口,也不再作为默认部署入口。旧的“本机打包源码 -> 上传到构建机”链路不再作为当前标准口径。 + +详细部署规范见: + +- `docs/Git增量部署方案.md` +- `docs/部署规范.md` +- `docs/部署脚本安全说明.md` ## 架构 diff --git a/README.md b/README.md index 266e6b5..85fd009 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,23 @@ npm run prisma:studio ## 部署说明 +### 当前标准部署 + +当前线上默认使用 Git 增量部署: + +```powershell +.\scripts\git-incremental-deploy.ps1 -DryRun +.\scripts\git-incremental-deploy.ps1 +``` + +部署链路是:源码推送到 Git -> 构建机增量拉取并构建镜像 -> 生产机拉取镜像并替换应用容器。旧的 `deploy-remote-build.ps1` 属于本地历史脚本名,只作为识别应急资料使用,不是仓库交付入口,也不再作为默认推荐方式。 + +详细说明见: + +- `docs/Git增量部署方案.md` +- `docs/部署规范.md` +- `docs/部署脚本安全说明.md` + ### 本地或单机生产启动 ```bash @@ -264,8 +281,10 @@ npm run start ## 相关文档 - `docs/NETWORK_TOPOLOGY.md`:当前网络拓扑与故障排查 +- `docs/部署规范.md`:当前部署规范 +- `docs/Git增量部署方案.md`:Git 增量部署方案 +- `docs/生产存储桶接入信息.md`:当前 MinIO / uploads 存储事实 - `docs/CODEX_MULTI_AGENTS.md`:项目内 Codex 团队协作规则 -- `部署前安全检查清单.md`:上线前检查项 - `docs/外部接口文档.md`:当前对外接口说明 ## 说明 diff --git a/build-base-image.ps1 b/build-base-image.ps1 index 16ad6fa..910599f 100644 --- a/build-base-image.ps1 +++ b/build-base-image.ps1 @@ -1,6 +1,7 @@ # 由壹点3D素材 - 构建基础镜像脚本 # 功能:一次性构建包含所有依赖的基础镜像 # 用途:当依赖变化时运行,后续部署直接使用此镜像 +# 状态:旧构建缓存方案,不是当前 Git 增量部署的默认前置步骤 param( [string]$BuildServerIP = '192.168.42.134', diff --git a/docker-compose.shadow.yml b/docker-compose.shadow.yml index 3f7a57f..e90c4a0 100644 --- a/docker-compose.shadow.yml +++ b/docker-compose.shadow.yml @@ -1,3 +1,6 @@ +# 当前影子环境发布不使用本文件作为入口。 +# 影子发布以 scripts/git-incremental-deploy.ps1 -Target shadow 为准;本文件仅作本地/单机/基础环境参考。 +# 不要按此文件推断当前线上影子容器启动参数、uploads 挂载或健康检查。 version: '3.8' services: diff --git a/docker-compose.yml b/docker-compose.yml index 35a7aee..ada4c50 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,6 @@ +# 当前生产发布不使用本文件作为入口。 +# 生产发布以 scripts/git-incremental-deploy.ps1 为准;本文件仅作本地/单机/基础环境参考。 +# 不要按此文件推断当前线上容器启动参数、uploads 挂载或健康检查。 version: '3.8' services: diff --git a/docs/AI生图平台桶缓存落地对接清单.md b/docs/AI生图平台桶缓存落地对接清单.md deleted file mode 100644 index 6309fa0..0000000 --- a/docs/AI生图平台桶缓存落地对接清单.md +++ /dev/null @@ -1,335 +0,0 @@ -# AI 生图平台桶缓存落地对接清单 - -> 交付对象:AI 生图平台负责人 -> 当前主接口域名:`https://sc.jiansun.vip` -> 当前资源主域名:`https://s3.jiansun.vip` -> 历史旧资源域名:`https://s3.yydd.ai`(不再作为默认入口) -> 文档时间:`2026-04-29` -> 当前状态:`180.97.215.57` 读缓存入口已停用,本文保留对接口径和历史方案说明。 - -## 1. 这次要做的事情 - -原计划把新入口服务器 `180.97.215.57` 上独立数据盘中的 `180G` 空间,用作 AI 生图平台相关资源的**读取缓存**。该入口现在已经停用,不再作为正式资源入口或联调目标。 - -当前目标调整为: - -- 对外资源域名继续统一使用 `https://s3.jiansun.vip` -- 展示型图片继续优先写入 `/gongxiangpan/public-display/` -- 排障和联调优先检查 `180.97.221.140 -> FRP -> 192.168.58.20:9000` 链路 - -## 2. 这次不会变的东西 - -下面这些默认都**不变**: - -- 桶本体位置不变,真实存储仍在生产机 `192.168.58.20:9000` -- AI 生图平台的接口入口仍然是 `https://sc.jiansun.vip` -- 对外资源主域名仍然是 `https://s3.jiansun.vip` -- 历史旧资源域名 `https://s3.yydd.ai` 不再作为默认对接地址 -- 不迁桶,上传链路不因 `180.97.215.57` 停用而变化 - -一句话说清楚: - -**`180.97.215.57` 读缓存入口已经停用,但桶没有搬走,正式资源域名仍然是 `s3.jiansun.vip`。** - -## 3. 当前已经确认的事实 - -当前资源入口链路是: - -```text -s3.jiansun.vip - -> 180.97.221.140 - -> nginx - -> 127.0.0.1:2323 - -> FRP - -> 192.168.58.20:9000 -``` - -历史缓存盘配置曾经是: - -- 缓存目录:`/data/nginx-cache/s3` -- 缓存上限:`180g` -- 旧入口机资源盘:`/data`,总容量约 `200G` -- 当前不再把这层缓存作为正式链路门禁 - -`2026-03-18` 实测真实桶链路时,使用了一个约 `145MB` 的真实桶对象做下载测试: - -- 直回源 `127.0.0.1:29000`:约 `23.2 MB/s` -- 走 `https://s3.jiansun.vip` 第一次请求:`X-Cache-Status: MISS`,约 `22.7 MB/s` -- 同一个 URL 第二次请求:`X-Cache-Status: HIT`,约 `63.2 MB/s` - -这些历史结果只说明旧缓存方案曾经可用: - -- 首次访问主要受回源链路影响 -- 命中缓存后,速度会明显提升 - -基于当前入口调整,需要明确 3 个结论: - -- `180.97.215.57` 读缓存方案已经停用 -- `s3.jiansun.vip` 仍是唯一正式资源域名 -- 后续验证重点是 `180.97.221.140` 入口、FRP 和 MinIO 回源,而不是旧缓存命中率 - -## 4. 我还需要 AI 生图平台这边提供什么 - -为了让 AI 生图平台稳定使用正式资源链路,还需要下面这些信息。 - -### 4.1 需要确认的资源范围 - -请提供: - -- AI 生图平台当前实际会读取的资源类型 -- 这些资源对应的 URL 样例 -- 最常访问的路径前缀 - -最好直接给: - -- 近 3 天最常访问的 20 个资源 URL 样例 -- 主要路径前缀清单 - -例如是否主要集中在: - -- 生图输入参考图 -- 生图结果图 -- 放大图、变体图、蒙版图、压缩包等固定路径前缀 - -### 4.2 需要确认是否只使用一个主资源域名 - -这个点非常关键。 - -请确认: - -- AI 生图平台后续是否统一只读 `https://s3.jiansun.vip` -- 历史旧资源域名 `https://s3.yydd.ai` 是否已从日常默认调用中完全移除 - -推荐口径: - -- 主用:`https://s3.jiansun.vip` -- 历史旧域名:`https://s3.yydd.ai`(仅用于识别历史链接) - -如果旧域名和新域名长期同时对外使用,那么**同一份内容就可能同时出现两个公网 URL**。 - -### 4.3 需要确认文件是否“同 key 覆盖” - -这个点决定缓存能不能放心加大。 - -请确认: - -- 同一张图后续会不会“覆盖原来的对象 key” -- 还是每次生成新图都使用新文件名 / 新路径 - -最推荐的方式是: - -- **新内容永远用新 key** - -比如: - -- `image-20260318-001.png` -- `image-20260318-002.png` - -不推荐的方式是: - -- 总是写回同一个 URL - -比如始终覆盖: - -- `latest.png` - -原因很简单: - -- 如果同一个 URL 对应的文件内容被覆盖了,缓存里可能暂时还是旧版本 -- 这样就会出现“URL 没变,但内容短时间还是旧图”的情况 - -### 4.4 需要确认时效要求 - -请确认: - -- 图片更新后,允许多久内出现旧图 -- 删除后,是否允许短时间还能访问 -- 是否存在“必须秒级生效”的路径 - -如果某些资源要求非常高的实时性,就不能和普通静态资源用完全同一套缓存策略。 - -### 4.5 需要确认流量规模 - -请提供一个大致量级即可,不需要特别精确。 - -需要知道: - -- 峰值并发大概多少 -- 每分钟 / 每小时大概多少请求 -- 热门图片是否会被大量重复读取 -- 单张图通常多大 -- 是否有明显的突发高峰时段 - -### 4.6 需要一批联调样本 - -请提供: - -- 5 到 10 个真实可访问的 AI 生图平台资源 URL -- 最好覆盖“结果图 / 参考图 / 较大文件”几类 - -这样我可以直接按真实资源做灰度验证,而不是拿不相关对象代替。 - -### 4.7 这次不需要 AI 生图平台配合改的内容 - -为了避免沟通误差,这里也明确一下当前**不要求**你们先改的东西: - -- 不要求先改接口域名,接口仍然走 `https://sc.jiansun.vip` -- 不要求先迁桶,桶本体仍然在 `192.168.58.20:9000` -- 不要求先切到 `s3.yydd.ai` -- 不要求先改上传链路 - -这次优先要拿到的是“真实读流量信息”,不是让业务先大改。 - -## 5. 对正常使用有没有影响 - -正常情况下,**对用户是无感的**。 - -前提是满足下面两个条件: - -- 对外主资源域名统一使用 `https://s3.jiansun.vip` -- 资源尽量使用“新内容新 key”的方式,不要反复覆盖同一个 URL - -只要做到这两点,链路效果就是: - -- 统一从 `s3.jiansun.vip` 进入 -- 通过当前正式入口回源到生产 MinIO -- 用户看到的还是同一个公网 URL - -## 6. 会不会出现“同一张图两个 URL” - -### 情况 1:旧缓存本身 - -**不会,但该方案已经停用。** - -缓存不会凭空再生成一个给用户使用的新 URL。 - -用户访问的仍然是原来的公网地址,比如: - -```text -https://s3.jiansun.vip/xxx.png -``` - -旧缓存只是入口服务器内部把这个 URL 对应的内容存到磁盘里。 - -也就是说: - -- 对用户看到的 URL 不变 -- 对程序调用的 URL 不变 -- 只是旧入口机内部多了一份缓存文件 - -### 情况 2:两个域名同时都在用 - -**会。** - -如果下面两个地址同时长期对外使用: - -- `https://s3.jiansun.vip/xxx.png` -- 历史旧链接:`https://s3.yydd.ai/xxx.png` - -那么从“公网 URL”角度看,就是两条 URL 指向了同一份内容。 - -所以当前建议非常明确: - -- `s3.jiansun.vip` 主用 -- `s3.yydd.ai` 不再作为默认入口 - -不要两个一起作为默认入口使用。 - -## 7. 会不会出现“缓存里一张图,桶里又是另一个 URL” - -从用户角度看,**不会多出一个可见 URL**。 - -但有一个需要特别注意的现实问题: - -### 如果同一个 URL 被反复覆盖内容 - -那么就可能出现: - -- 桶里已经是新图 -- 缓存里短时间还是旧图 - -这时候不是“两个 URL”,而是: - -- **同一个 URL,在不同时间点可能先返回旧内容,再返回新内容** - -这也是为什么我强烈建议: - -- 新图使用新 key -- 不要反复覆盖同一个对象地址 - -如果业务上确实必须覆盖同一个 URL,那就必须额外做: - -- 清缓存机制 -- 或单独降低这类路径的缓存时间 - -## 8. 推荐的最终口径 - -建议 AI 生图平台后续按下面这套规则执行: - -### 域名规则 - -- 正式资源域名:`https://s3.jiansun.vip` -- 历史旧域名:`https://s3.yydd.ai`(仅识别,不再默认使用) - -### URL 规则 - -- 对外只认主域名,不混用两个资源域名 -- 新内容尽量使用新 key,不覆盖老 key - -### 链路规则 - -- 把 AI 生图平台的热点读流量优先收敛到 `s3.jiansun.vip` -- 当前正式入口为 `180.97.221.140` -- `180.97.215.57` 不再作为正式资源入口或缓存入口 - -## 9. 现在就可以推进的下一步 - -如果 AI 生图平台负责人能补齐下面 4 项,我就可以继续往下收口: - -1. 确认主用资源域名是否统一为 `s3.jiansun.vip` -2. 提供 AI 生图平台真实会读取的路径前缀或 URL 样例 -3. 明确是否存在“同 key 覆盖” -4. 提供一组真实联调 URL 用于灰度测试 - -拿到这些信息后,我这边会继续做: - -1. 按真实热点路径确认是否需要“分路径缓存策略” -2. 区分哪些资源适合长缓存,哪些资源要短缓存 -3. 如果存在“同 key 覆盖”,评估是否需要补清缓存机制 -4. 用真实 URL 做灰度验证,再决定是否正式放量 - -## 10. 建议负责人直接按下面模板回复 - -为了节省来回沟通时间,建议 AI 生图平台负责人直接按这个格式回: - -```text -1. 主用资源域名: - 例如:统一使用 https://s3.jiansun.vip - -2. 历史旧域名是否已停止默认调用: - 例如:是,`https://s3.yydd.ai` 不再作为默认入口 - -3. 主要读取的资源类型: - 例如:生图结果图、参考图、放大图、变体图、压缩包 - -4. 主要路径前缀或 URL 样例: - 例如:/gongxiangpan/ai-output/... 或 /gongxiangpan/ai-input/... - -5. 是否存在同 key 覆盖: - 例如:有 / 没有 - -6. 时效要求: - 例如:更新后允许 5 分钟内旧图;某些路径要求秒级生效 - -7. 流量规模: - 例如:高峰每分钟约多少次读取,热门图片是否会被重复访问 - -8. 联调样本: - 例如:提供 5 到 10 个真实可访问 URL -``` - ---- - -如果只要一句最短版本,可以直接转给对方: - -**这次不是迁桶;`180.97.215.57` 读缓存入口已停用,正式资源域名仍然是 `s3.jiansun.vip`,当前应通过 `180.97.221.140` 入口回源到 `192.168.58.20:9000`。要继续推进,需要 AI 生图平台确认主用域名、真实热点路径、是否会覆盖同一 URL、以及给一组联调样本。** diff --git a/docs/AI生图平台第一层桶缓存落地方案.md b/docs/AI生图平台第一层桶缓存落地方案.md index 5d191ab..ccd59ee 100644 --- a/docs/AI生图平台第一层桶缓存落地方案.md +++ b/docs/AI生图平台第一层桶缓存落地方案.md @@ -1,8 +1,8 @@ # AI 生图平台第一层桶缓存落地方案 -> 更新时间:2026-04-29 +> 更新时间:2026-05-07 > 当前正式资源域名:`https://s3.jiansun.vip` -> 当前正式入口机:`180.97.221.140` +> 当前正式入口机:`103.118.245.6` > 已停用缓存入口机:`180.97.215.57` > 当前桶本体:`192.168.58.20:9000` @@ -21,7 +21,7 @@ AI 生图平台不再沿用“整个 `/uploads/` 都进长缓存”的口径, ```text AI 生图平台 -> https://s3.jiansun.vip/gongxiangpan/public-display/... - -> 180.97.221.140 + -> 103.118.245.6 -> nginx -> 127.0.0.1:2323 -> FRP @@ -32,6 +32,7 @@ AI 生图平台 ### 2.2 关于旧缓存入口 - `180.97.215.57` 已停用,不再作为 `s3.jiansun.vip` 的正式链路。 +- `180.97.221.140` 是历史入口,不再作为当前默认排障入口。 - 旧的 `180G` nginx 磁盘缓存方案只保留历史记录,不再作为联调或排障门禁。 ## 3. 为什么改成新前缀 @@ -68,8 +69,10 @@ AI 生图平台 - 展示图对象优先写入 `/gongxiangpan/public-display/` - `uploads` 保留为历史混合区,不作为默认展示资源路径 +- 源文件 / ZIP / PSD / 视频源等下载型对象继续落在生产机 uploads:`/mnt/PoolOne/apps/youyidian-3d/uploads` +- `s3.1080p.hk/jsxiangche` 只保留极少数老素材兼容,不作为新素材或新预览写入目标 - 当前不再以 `X-Cache-Status` 作为正式验证标准 -- 当前优先验证 `s3.jiansun.vip -> 180.97.221.140 -> 192.168.58.20:9000` 是否可达 +- 当前优先验证 `s3.jiansun.vip -> 103.118.245.6 -> 192.168.58.20:9000` 是否可达 ## 6. 历史验证结果 @@ -120,4 +123,4 @@ AI 生图平台后续如果要对接正式展示图,统一按下面这个口 AI 生图平台现在的第一层桶缓存口径是: -**新生成的展示型图片统一写到 `s3.jiansun.vip` 的 `/gongxiangpan/public-display/`,当前正式入口收敛到 `180.97.221.140`;`180.97.215.57` 缓存入口已停用,历史 `/uploads/` 继续可访问,但不再作为默认展示路径。** +**新生成的展示型图片统一写到 `s3.jiansun.vip` 的 `/gongxiangpan/public-display/`,当前正式入口收敛到 `103.118.245.6`;`180.97.215.57` 缓存入口已停用,历史 `/uploads/` 继续可访问,但不再作为默认展示路径。** diff --git a/docs/AI生图白底图以及详情页面接口文档.md b/docs/AI生图白底图以及详情页面接口文档.md index f873962..1205eae 100644 --- a/docs/AI生图白底图以及详情页面接口文档.md +++ b/docs/AI生图白底图以及详情页面接口文档.md @@ -1,6 +1,6 @@ # AI 生图平台素材接口文档 -> 用途:AI 生图平台统一通过同一条接口,查询 `标准模型白底图` 或 `任务-详情整套预览下载链接` +> 用途:AI 生图平台统一通过同一条接口,查询 `标准模型白底图` 或 `任务-详情整套预览直链` > 当前主域名:`https://sc.jiansun.vip` > 当前资源主域名:`https://s3.jiansun.vip` > 历史旧资源域名:`https://s3.yydd.ai`(仅用于识别历史链接,不再作为对接口径) @@ -18,8 +18,9 @@ ### 1.1 当前网络口径 - 接口查询、鉴权和下载 token 入口统一使用 `https://sc.jiansun.vip` -- `white-background` 分支里返回的 `previewUrl`,当前默认也是 `https://sc.jiansun.vip/uploads/...` +- `white-background` 分支里返回的 `previewUrl`,新预览默认走 `https://s3.jiansun.vip/gongxiangpan/public-display/white-background/...` - `task-detail` 分支返回的预览图直链,当前默认资源域名使用 `https://s3.jiansun.vip` +- `/uploads/...` 只作为源文件下载、内网访问或少量历史预览兼容路径,不作为新预览默认路径 - 历史旧资源域名 `https://s3.yydd.ai` 不再作为默认对接口径 返回统一格式: @@ -137,7 +138,7 @@ X-API-Key: your-api-key "label": "左前45°", "fileName": "TEXT001452-旗舰店-左前45°.webp", "fileSize": 123456, - "previewUrl": "https://sc.jiansun.vip/uploads/skus/484bd047-c956-48cf-a0f4-401f696aef8d/white-background/sku-id-1/preview/TEXT001452-%E6%97%97%E8%88%B0%E5%BA%97-%E5%B7%A6%E5%89%8D45%C2%B0.webp", + "previewUrl": "https://s3.jiansun.vip/gongxiangpan/public-display/white-background/484bd047-c956-48cf-a0f4-401f696aef8d/sku-id-1/TEXT001452-leftFront45.webp", "downloadUrl": "https://sc.jiansun.vip/api/external/download?token=xxx" }, { @@ -145,7 +146,7 @@ X-API-Key: your-api-key "label": "右前45°", "fileName": "TEXT001452-旗舰店-右前45°.webp", "fileSize": 123456, - "previewUrl": "https://sc.jiansun.vip/uploads/skus/484bd047-c956-48cf-a0f4-401f696aef8d/white-background/sku-id-1/preview/TEXT001452-%E6%97%97%E8%88%B0%E5%BA%97-%E5%8F%B3%E5%89%8D45%C2%B0.webp", + "previewUrl": "https://s3.jiansun.vip/gongxiangpan/public-display/white-background/484bd047-c956-48cf-a0f4-401f696aef8d/sku-id-1/TEXT001452-rightFront45.webp", "downloadUrl": "https://sc.jiansun.vip/api/external/download?token=yyy" } ], @@ -155,7 +156,7 @@ X-API-Key: your-api-key "label": "其他图片1", "fileName": "01-detail-1.webp", "fileSize": 123456, - "previewUrl": "https://sc.jiansun.vip/uploads/skus/484bd047-c956-48cf-a0f4-401f696aef8d/white-background/sku-id-1/preview/other/01-detail-1.webp", + "previewUrl": "https://s3.jiansun.vip/gongxiangpan/public-display/white-background/484bd047-c956-48cf-a0f4-401f696aef8d/sku-id-1/other/01-detail-1.webp", "downloadUrl": "https://sc.jiansun.vip/api/external/download?token=zzz" } ] @@ -192,7 +193,7 @@ X-API-Key: your-api-key - `previewUrl` 是预览专用小图,优先给页面展示或 AI 平台取图使用。 - `downloadUrl` 是原图下载链接,当前仍走 token 下载接口。 - 对于后续新上传白底图,正式存储和下载格式统一为 `image/webp`,并保留透明通道。 -- 历史白底图如果还没有派生预览图,`previewUrl` 会临时回退到原图路径。 +- 历史白底图如果还没有派生预览图,`previewUrl` 可能临时回退到原图路径或 `/uploads/...` 兼容路径。 固定角度顺序固定为: @@ -246,7 +247,7 @@ X-API-Key: your-api-key "hasWhiteBackground": true, "whiteBackgroundCount": 2, "previewImage": { - "previewUrl": "https://sc.jiansun.vip/uploads/skus/484bd047-c956-48cf-a0f4-401f696aef8d/white-background/sku-id-1/preview/TEXT001452-%E6%97%97%E8%88%B0%E5%BA%97-%E5%8F%B3%E5%89%8D45%C2%B0.webp", + "previewUrl": "https://s3.jiansun.vip/gongxiangpan/public-display/white-background/484bd047-c956-48cf-a0f4-401f696aef8d/sku-id-1/TEXT001452-rightFront45.webp", "downloadUrl": "https://sc.jiansun.vip/api/external/download?token=xxx", "fileName": "TEXT001452-旗舰店-右前45°.webp", "fileSize": 123456 @@ -348,18 +349,18 @@ X-API-Key: your-api-key "isFullSet": true, "downloadUrls": { "main": [ - "https://s3.jiansun.vip/gongxiangpan/preview/main-1.jpg" + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/main/main-1.webp" ], "sku": [ - "https://s3.jiansun.vip/gongxiangpan/preview/sku-1.jpg" + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/sku/sku-1.webp" ], "detail": [ - "https://s3.jiansun.vip/gongxiangpan/preview/detail-1.jpg" + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/detail/detail-1.webp" ], "all": [ - "https://s3.jiansun.vip/gongxiangpan/preview/main-1.jpg", - "https://s3.jiansun.vip/gongxiangpan/preview/sku-1.jpg", - "https://s3.jiansun.vip/gongxiangpan/preview/detail-1.jpg" + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/main/main-1.webp", + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/sku/sku-1.webp", + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/detail/detail-1.webp" ] } } @@ -410,18 +411,18 @@ X-API-Key: your-api-key "isFullSet": true, "downloadUrls": { "main": [ - "https://s3.jiansun.vip/gongxiangpan/preview/main-1.jpg" + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/main/main-1.webp" ], "sku": [ - "https://s3.jiansun.vip/gongxiangpan/preview/sku-1.jpg" + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/sku/sku-1.webp" ], "detail": [ - "https://s3.jiansun.vip/gongxiangpan/preview/detail-1.jpg" + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/detail/detail-1.webp" ], "all": [ - "https://s3.jiansun.vip/gongxiangpan/preview/main-1.jpg", - "https://s3.jiansun.vip/gongxiangpan/preview/sku-1.jpg", - "https://s3.jiansun.vip/gongxiangpan/preview/detail-1.jpg" + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/main/main-1.webp", + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/sku/sku-1.webp", + "https://s3.jiansun.vip/gongxiangpan/public-display/task-detail/material-2/detail/detail-1.webp" ] } } @@ -500,6 +501,7 @@ GET https://sc.jiansun.vip/api/external/download?token=xxx 补充说明: - 当前默认回包中的预览图资源域名为 `https://s3.jiansun.vip` +- 新任务详情预览路径默认位于 `/gongxiangpan/public-display/task-detail/...` - 历史旧资源域名 `https://s3.yydd.ai` 不再作为当前默认对接地址 ## 6. 错误码 diff --git a/docs/Git增量部署方案.md b/docs/Git增量部署方案.md index 2d887b7..ebd51f9 100644 --- a/docs/Git增量部署方案.md +++ b/docs/Git增量部署方案.md @@ -32,6 +32,18 @@ - 正式容器:`youyidian-3d-material` - 正式端口:`4320` +## 首次运行前准备 + +本脚本由维护人员执行,不要求普通用户手动运行。首次在一台新维护机上运行前,需要确认: + +- 本机可用 PowerShell 5.1+。 +- 本机已安装 PuTTY 工具,`plink.exe` 和 `pscp.exe` 可在 PATH 中找到,或位于 `C:\Program Files\PuTTY\`。 +- 本机能访问构建机 `192.168.42.134`。 +- 构建机能访问 Git 仓库和生产机 `192.168.58.20`。 +- 构建机本地 Registry 端口 `5000` 可用。 +- 已通过环境变量或参数提供构建机密码:`BUILD_SERVER_PASSWORD` 或 `-BuildServerPassword`。 +- 私有 Git 仓库认证通过 `GIT_DEPLOY_USERNAME` / `GIT_DEPLOY_PASSWORD`,或 `GIT_AUTH_HEADER` 提供;不要把密码写进仓库 URL。 + ## 安全边界 - 不从本机上传源码压缩包。 diff --git a/docs/外部接口文档.md b/docs/外部接口文档.md index da459a3..9bc4bde 100644 --- a/docs/外部接口文档.md +++ b/docs/外部接口文档.md @@ -161,8 +161,8 @@ X-API-Key: your-api-key-here "main": [ { "id": "asset-uuid-1", - "url": "https://s3.jiansun.vip/...", - "fileName": "主图1.jpg", + "url": "uploads/materials/YYD-001_张三_天猫旗舰店_main.zip", + "fileName": "YYD-001_张三_天猫旗舰店_main.zip", "fileSize": 1024000, "sortOrder": 0 } @@ -170,8 +170,8 @@ X-API-Key: your-api-key-here "sku": [ { "id": "asset-uuid-2", - "url": "https://s3.jiansun.vip/...", - "fileName": "SKU白色.jpg", + "url": "uploads/materials/YYD-001_张三_天猫旗舰店_sku.zip", + "fileName": "YYD-001_张三_天猫旗舰店_sku.zip", "fileSize": 512000, "sortOrder": 1 } @@ -179,8 +179,8 @@ X-API-Key: your-api-key-here "detail": [ { "id": "asset-uuid-3", - "url": "https://s3.jiansun.vip/...", - "fileName": "详情1.jpg", + "url": "uploads/materials/YYD-001_张三_天猫旗舰店_detail.zip", + "fileName": "YYD-001_张三_天猫旗舰店_detail.zip", "fileSize": 2048000, "sortOrder": 0 } @@ -188,7 +188,7 @@ X-API-Key: your-api-key-here "psd": [ { "id": "asset-uuid-5", - "url": "uploads/product-package/xxx/psd/psd-xxx.psd", + "url": "uploads/materials/psd-source.psd", "fileName": "源文件1.psd", "fileSize": 52428800, "sortOrder": 0 @@ -249,7 +249,7 @@ X-API-Key: your-api-key-here | sceneName | string | 场景类别;`任务-其他` 固定返回 `通用` | | isFullSet | boolean | 是否整套;当前按素材类型和资产情况自动判定 | | status | string | 状态:completed/fetched | -| assets | object | **仅 `任务-详情` 类型**:资产分类对象(包含 `main`、`sku`、`detail`、`psd`) | +| assets | object | **仅 `任务-详情` 类型**:分类 ZIP / PSD 资产对象(包含 `main`、`sku`、`detail`、`psd`) | | files | array | **仅非 `任务-详情` 类型**:文件列表(统一结构) | | downloadUrl | string | **仅 `任务-详情`**:兼容字段,值与 `downloadUrls.all` 相同 | | downloadUrls.all | string | **所有类型**:全部文件下载链接 | @@ -341,12 +341,14 @@ curl -X GET \ **资产对象字段说明(任务-详情)** +`/api/external/product-assets` 返回的 `assets.main` / `assets.sku` / `assets.detail` 是分类 ZIP 资产,不是单张预览图列表。`assets.psd` 是 PSD 源文件资产。任务-详情预览直链请使用 `/api/external/standard-model-white-background?resourceType=task-detail` 获取。 + 每个资产对象包含以下字段: | 字段 | 类型 | 说明 | |-----|------|------| | id | string | 资产唯一标识符 | -| url | string | 资源URL(S3地址或本地路径,仅用于预览) | +| url | string | 分类 ZIP / PSD 的存储路径,外部下载优先使用 `downloadUrls.all` | | fileName | string | 文件名 | | fileSize | number | 文件大小(字节) | | sortOrder | number | 排序序号(主图 / SKU 图 / 详情图 / PSD 均会显式返回) | @@ -518,7 +520,7 @@ X-API-Key: your-api-key-here 供 AI 生图平台统一通过同一条接口查询: - `标准模型白底图` -- `任务-详情整套预览下载链接` +- `任务-详情整套预览直链` 主接口: @@ -529,8 +531,9 @@ GET /api/external/standard-model-white-background 当前网络口径: - 接口查询与下载 token 统一走 `https://sc.jiansun.vip` -- `white-background` 分支的 `previewUrl` 默认走 `https://sc.jiansun.vip/uploads/...` +- `white-background` 分支的 `previewUrl` 新预览默认走 `https://s3.jiansun.vip/gongxiangpan/public-display/white-background/...` - `task-detail` 分支里返回的预览图直链,当前默认资源域名是 `https://s3.jiansun.vip` +- `/uploads/...` 只作为源文件下载、内网访问或少量历史预览兼容路径,不作为新预览默认路径 - 历史旧资源域名 `https://s3.yydd.ai` 不再作为对接口径 **请求头** @@ -843,7 +846,7 @@ AI 生图平台的详细字段说明、完整响应示例、错误码和 cURL ### 打包下载说明 -- `任务-详情` 的 `downloadUrls.all` 包含:主图 + SKU 图 + 详情图(**不含 PSD**) +- `任务-详情` 的 `downloadUrls.all` 包含:主图分类 ZIP + SKU 分类 ZIP + 详情分类 ZIP(**不含 PSD**) - 当前 `任务-详情` 接口不再返回 `downloadUrls.psd` - 当前 `任务-详情` 接口也不再给每个 asset 返回单独 `downloadUrl` - ZIP 文件内按文件夹分类:`main/`、`sku/`、`detail/` diff --git a/docs/生产存储桶接入信息.md b/docs/生产存储桶接入信息.md index 1511676..205c067 100644 --- a/docs/生产存储桶接入信息.md +++ b/docs/生产存储桶接入信息.md @@ -1,199 +1,144 @@ # 生产存储桶接入信息 -适用范围:本文记录当前线上 `MinIO(对象存储)` / `S3(对象存储兼容接口)` 的已确认接入信息,供其它项目接入同一个生产存储桶时参考。 +> 更新时间:2026-05-07 +> 本文记录当前素材平台的 MinIO / S3 / uploads 存储事实。 -最后核对时间:`2026-04-14` -核对方式:生产服务器只读核对 + 生产应用容器环境变量核对 + 宿主机挂载路径核对 +## 1. 当前结论 -## 1. 已确认的生产接入信息 +- 新素材预览 / 展示文件:写入生产 MinIO 新桶路径,公开 URL 统一为 `https://s3.jiansun.vip/gongxiangpan/public-display/...`。 +- 源文件 / 下载型文件:写入生产服务器 uploads 目录:`/mnt/PoolOne/apps/youyidian-3d/uploads`。 +- 旧 `1080p.hk` 桶:只用于极少数老素材兼容,不作为新素材写入目标。 +- `/gongxiangpan/uploads/` 是历史混合区,不再作为新展示资源的默认路径。 -### 1.1 存储服务 +## 2. 生产 MinIO 信息 -- 存储服务:`MinIO(对象存储服务)` +- 存储服务:`MinIO` - 生产服务器:`192.168.58.20` - API 端口:`9000` - 控制台端口:`9001` -- 线上应用容器:`youyidian-3d-material` - 存储服务容器:`minio` +- 线上应用容器:`youyidian-3d-material` -### 1.2 S3 兼容接入参数 - -- `S3_ENDPOINT(对象存储接口地址)`:`http://192.168.58.20:9000` -- `S3_BUCKET(桶名)`:`gongxiangpan` -- `S3_REGION(区域)`:`us-east-1` -- `S3_ENABLE_PATH_STYLE(路径风格访问)`:`1` -- `S3_SET_ACL(上传后写 public-read)`:`1` -- `S3_PREVIEW_URL_EXPIRE_IN(预览链接过期秒数)`:`7200` - -### 1.3 对外访问域名 - -- `S3_PUBLIC_DOMAIN(公开访问域名)`:`https://s3.jiansun.vip/gongxiangpan` - -当前项目最终对象 URL(访问地址)规则: - -```text -https://s3.jiansun.vip/gongxiangpan/<前缀><文件名> -``` - -例如当前项目使用的前缀是: - -- `S3_FILE_PATH(对象前缀)`:`由壹点AI/` - -所以当前项目上传出来的对象通常长这样: - -```text -https://s3.jiansun.vip/gongxiangpan/由壹点AI/<文件名> -``` - -## 2. 宿主机真实挂载路径 - -### 2.1 MinIO 数据目录 - -- 宿主机数据路径:`/mnt/tank/apps/minio/data` -- 容器内路径:`/data` - -### 2.2 MinIO 配置目录 - -- 宿主机配置路径:`/mnt/tank/apps/minio/config` -- 容器内路径:`/root/.minio` - -### 2.3 当前项目本地上传目录 - -这个不是存储桶,但很多视频源文件会先落这里: - -- 宿主机路径:`/mnt/PoolOne/apps/youyidian-3d/uploads` -- 容器内路径:`/app/uploads` - -## 3. 新项目接入时建议怎么用 - -### 3.1 可以共用什么 - -新项目如果要共用这一个生产桶,可以共用这些固定信息: - -- `S3_ENDPOINT` -- `S3_BUCKET` -- `S3_REGION` -- `S3_PUBLIC_DOMAIN` -- `path-style(路径风格)` - -### 3.2 不建议直接共用什么 - -下面两项不建议直接原样复用: - -- 当前项目的 `S3_FILE_PATH(对象前缀)` -- 当前项目正在使用的长期访问密钥 - -原因很直接: - -1. 如果多个项目共用同一个前缀,文件名一旦撞上,后面排查和清理会很乱。 -2. 如果多个项目长期共用同一套生产密钥,任何一个项目泄露,整个生产桶都会一起暴露。 - -### 3.3 推荐接法 - -新项目建议这样配: +应用实际接入参数: ```env S3_ENDPOINT=http://192.168.58.20:9000 S3_BUCKET=gongxiangpan S3_REGION=us-east-1 -S3_ENABLE_PATH_STYLE=1 S3_PUBLIC_DOMAIN=https://s3.jiansun.vip/gongxiangpan -S3_FILE_PATH=<新项目自己的前缀>/ ``` -例如: +代码固定行为: -```env -S3_FILE_PATH=新项目名/ +- S3 客户端使用 path-style 访问,代码里固定 `forcePathStyle: true`。 +- 上传对象默认设置 `public-read` ACL,代码里固定处理。 +- `S3_PUBLIC_DOMAIN` 用来拼出公开访问地址。 + +下面这些不是当前代码必须读取的部署变量,不要再作为新项目接入必填项传播: + +- `S3_ENABLE_PATH_STYLE` +- `S3_SET_ACL` +- `S3_PREVIEW_URL_EXPIRE_IN` + +## 3. 对象路径规则 + +### 3.1 新预览 / 展示资源 + +正式路径: + +```text +https://s3.jiansun.vip/gongxiangpan/public-display/... ``` -或者: +常见前缀: -```env -S3_FILE_PATH=业务线A/新项目名/ +```text +public-display/materials/... +public-display/task-detail/... +public-display/white-background/... +public-display/certificate-report/... ``` -## 4. 密钥处理建议 +这些资源用于页面展示、AI 平台预览、钉钉返回地址和外部接口展示直链。 -风险等级:`高` +### 3.2 默认 S3 业务前缀 -当前生产环境里确实存在可用的 `Access Key(访问密钥)` / `Secret Key(私钥)`,但本文不直接记录明文。 +生产环境仍可能存在默认业务前缀: -不建议: +```text +由壹点AI/ +``` -- 直接把 `MinIO Root(管理员根账号)` 给业务项目使用 -- 让多个项目长期共用同一套生产访问密钥 +它主要用于旧逻辑或非 `public-display` 的对象,不代表新素材展示图默认落点。 -建议: +## 4. uploads 目录规则 -1. 给每个新项目单独发一套对象存储访问密钥 -2. 至少给每个项目分独立前缀 -3. 如果条件允许,进一步按项目拆权限策略 +生产 uploads 目录: -## 5. 如果必须核对线上实际配置 +```text +/mnt/PoolOne/apps/youyidian-3d/uploads +``` -### 5.1 看当前应用实际在用的 S3 配置 +容器内路径: + +```text +/app/uploads +``` + +当前会落在这里的内容包括: + +- 素材源文件 +- ZIP / PSD / PDF 等下载型文件 +- 视频源文件 +- 音频源文件 +- 分片上传合并后的最终文件 +- 上传过程中的临时文件 + +对外访问时,代码会根据场景返回: + +- 内网:可能返回 `/uploads/...` 或内网 MinIO / 生产机地址。 +- 外网:通常通过 `/api/uploads/...` 或带 token 的下载接口流式返回。 + +不要把 uploads 理解成“少量视频临时区”。它是当前生产源文件和下载型文件的核心落点。 + +## 5. 历史兼容 + +### 5.1 旧 `1080p.hk` 桶 + +`s3.1080p.hk/jsxiangche` 只保留给极少数老素材兼容。新素材、批量新录入素材、后续上传素材都不应继续写入旧桶。 + +### 5.2 旧资源域名 + +`s3.yydd.ai` 不再作为默认对接口径,只用于识别历史链接。 + +### 5.3 历史混合区 + +`/gongxiangpan/uploads/` 保留历史兼容,不再作为新展示图默认路径。 + +## 6. 只读核对命令 + +核对应用环境变量: ```powershell -ssh root@192.168.58.20 "docker exec youyidian-3d-material sh -lc 'env'" +ssh root@192.168.58.20 "docker exec youyidian-3d-material sh -lc 'env | grep -E \"^(S3_|UPLOAD_DIR|APP_PUBLIC_URL|NEXTAUTH_URL)\"'" ``` -然后重点看: - -- `S3_ENDPOINT` -- `S3_BUCKET` -- `S3_REGION` -- `S3_PUBLIC_DOMAIN` -- `S3_FILE_PATH` -- `S3_ACCESS_KEY_ID` -- `S3_SECRET_ACCESS_KEY` - -### 5.2 看 MinIO 挂载 +核对 MinIO 挂载: ```powershell ssh root@192.168.58.20 "docker inspect minio --format '{{json .Mounts}}'" ``` -### 5.3 看 MinIO 本机配置文件 +核对 uploads 目录: ```powershell -ssh root@192.168.58.20 "sed -n '1,200p' /mnt/tank/apps/minio/config/minio.env" +ssh root@192.168.58.20 "ls -la /mnt/PoolOne/apps/youyidian-3d/uploads | head -20" ``` -## 6. 当前结论 +核对资源域名解析: -- 生产对象存储实例可以复用 -- 生产桶名已经确认是 `gongxiangpan` -- 公开访问域名已经确认是 `https://s3.jiansun.vip/gongxiangpan` -- 当前项目对象前缀是 `由壹点AI/` -- 其它项目如果接入,建议“共用桶,不共用前缀,不共用长期密钥” +```powershell +Resolve-DnsName s3.jiansun.vip +``` -## 7. 另一个项目临时接入说明 - -已确认另一个项目使用下面这套固定配置: - -- `S3_ENDPOINT=http://192.168.58.20:9000` -- `S3_BUCKET=gongxiangpan` -- `S3_REGION=us-east-1` -- `S3_ENABLE_PATH_STYLE=1` -- `S3_PUBLIC_DOMAIN=https://s3.jiansun.vip/gongxiangpan` -- `S3_FILE_PATH=3danzhuang/furniture-3d-system/` - -风险等级:`高` - -说明: - -- 另一个项目当前要求的是“先能接上生产桶” -- 目前本项目已经掌握现有生产项目使用中的对象存储访问密钥 -- 但把明文密钥直接写进仓库文档不安全,后续极易被提交扩散 - -因此实际可用的临时接入环境变量,已单独写入本地忽略文件: - -- [`.env.furniture-3d-system.local`](/D:/AI%20Code/gongxiangp2/.env.furniture-3d-system.local) - -这份文件可直接给另一个项目参考或落到新服务器。 - -不建议长期这样复用当前生产项目密钥。更稳的最终方案仍然是: - -1. 给另一个项目单独创建一套 `Access Key / Secret Key(访问密钥 / 密钥)` -2. 继续保留它自己的对象前缀 `3danzhuang/furniture-3d-system/` +当前资源域名应解析到正式入口 `103.118.245.6`,再经入口机 nginx / FRP 回源到 `192.168.58.20:9000`。 diff --git a/docs/素材库平台预览缓存方案.md b/docs/素材库平台预览缓存方案.md index 679f99b..b49e0ba 100644 --- a/docs/素材库平台预览缓存方案.md +++ b/docs/素材库平台预览缓存方案.md @@ -1,13 +1,15 @@ # 素材库平台预览缓存方案 -> 更新时间:2026-04-29 +> 更新时间:2026-05-07 > 状态:`180.97.215.57` 缓存入口已停用,本文保留历史方案和当前展示资源口径。 ## 1. 当前口径 -- 资源入口:`s3.jiansun.vip -> 180.97.221.140` +- 资源入口:`s3.jiansun.vip -> 103.118.245.6` - 桶本体:`192.168.58.20:9000` - 已停用缓存入口:`180.97.215.57` +- 历史入口:`180.97.221.140` 不再作为当前默认排障入口 +- 旧桶兼容:`s3.1080p.hk/jsxiangche` 只保留给极少数老素材,不作为新素材写入目标 - 旧缓存目录:`/data/nginx-cache/s3`,不再作为当前正式链路门禁 - 旧缓存上限:`180g`,只作为历史记录保留 @@ -47,12 +49,13 @@ - 视频大文件 - 压缩包 - 源文件下载 +- 生产机 uploads 源文件目录:`/mnt/PoolOne/apps/youyidian-3d/uploads` ## 4. 历史缓存策略 - 下面规则属于 `180.97.215.57` 缓存方案的历史记录。 - 当前正式链路不再用 `X-Cache-Status` 作为排障门禁。 -- 当前优先验证 `s3.jiansun.vip -> 180.97.221.140 -> 192.168.58.20:9000` 是否可达。 +- 当前优先验证 `s3.jiansun.vip -> 103.118.245.6 -> 192.168.58.20:9000` 是否可达。 ## 5. 历史验证结果 @@ -82,4 +85,4 @@ - 以后只要是“页面上要展示给人看”的成品图,就优先写 `public-display` - 只要是“下载型、源文件型、大对象”,就不要硬塞进展示资源口径 - 对外说明时,统一写 `s3.jiansun.vip`,不要再把 `s3.yydd.ai` 当正式入口 -- 排障时不要再默认检查 `180.97.215.57`,先检查 `180.97.221.140` 入口和 FRP 回源链路 +- 排障时不要再默认检查 `180.97.215.57` 或 `180.97.221.140`,先检查 `103.118.245.6` 入口和 FRP 回源链路 diff --git a/docs/统一流量访问规则.md b/docs/统一流量访问规则.md index f9c638e..b07ca79 100644 --- a/docs/统一流量访问规则.md +++ b/docs/统一流量访问规则.md @@ -1,6 +1,6 @@ # 统一流量访问规则 -> 更新时间:2026-04-29 +> 更新时间:2026-05-07 > 目标:统一正式入口、展示资源口径和内外网分工,减少历史残留带来的分流与误判。 ## 1. 统一原则 @@ -9,6 +9,8 @@ - 服务端访问 MinIO 继续走内网 `192.168.58.20:9000`。 - 展示型图片统一写入 `/gongxiangpan/public-display/`。 - `/gongxiangpan/uploads/` 保留为混合区,不再默认承担展示资源职责。 +- 源文件 / 下载型文件默认落在生产机 uploads:`/mnt/PoolOne/apps/youyidian-3d/uploads`。 +- `1080p.hk` 旧桶只用于极少数老素材兼容,不作为新素材写入目标。 - `180.97.215.57` 已停用,不再作为正式资源入口或缓存入口。 ## 2. 正式入口 @@ -17,6 +19,7 @@ | --- | --- | --- | | 主站 | `https://sc.jiansun.vip` | 唯一正式主站入口 | | 资源 / S3 | `https://s3.jiansun.vip` | 唯一正式资源入口 | +| 当前公网入口机 | `103.118.245.6` | 主站和资源域名当前都解析到这台入口机 | | 内网生产机 | `192.168.58.20` | 只给服务端和内网运维链路使用 | ## 3. 访问规则 @@ -37,6 +40,7 @@ - 正式访问口径同样优先走正式域名 - 只有诊断、运维或服务端内部访问,才直接使用内网地址 +- 媒体资源返回值会按代码做内外网改写;内网请求仍可能拿到 `SERVER_IP:MINIO_API_PORT`、`/uploads/...` 或 `/api/uploads/...` 这类内网/本机链路。 ## 4. 写入规则 @@ -46,7 +50,7 @@ | 任务-详情预览 | `/gongxiangpan/public-display/task-detail/...` | 是 | | 通用预览 / 展示图 | `/gongxiangpan/public-display/materials/...` | 是 | | 历史混合对象 | `/gongxiangpan/uploads/...` | 否,默认不按展示缓存处理 | -| 压缩包 / 视频源文件 / 大下载对象 | 原业务路径 | 否 | +| 压缩包 / 视频源文件 / 大下载对象 | 生产机 uploads 目录 | 否 | ## 5. 展示资源规则 @@ -99,5 +103,5 @@ 1. 是主站慢,还是资源图慢。 2. 如果是资源图慢,先看链接是不是 `s3.jiansun.vip`。 3. 再看路径是不是 `/gongxiangpan/public-display/`。 -4. 再看 `s3.jiansun.vip` 是否解析到当前正式入口 `180.97.221.140`。 -5. 最后再看 `180.97.221.140 -> 127.0.0.1:2323 -> 192.168.58.20:9000` 回源链路。 +4. 再看 `s3.jiansun.vip` 是否解析到当前正式入口 `103.118.245.6`。 +5. 最后再看 `103.118.245.6 -> 127.0.0.1:2323 -> 192.168.58.20:9000` 回源链路。 diff --git a/docs/部署脚本安全说明.md b/docs/部署脚本安全说明.md index 39ce7b7..3dab806 100644 --- a/docs/部署脚本安全说明.md +++ b/docs/部署脚本安全说明.md @@ -1,255 +1,181 @@ # 部署脚本安全说明 -## ⚠️ 重要提示 +> 更新时间:2026-05-07 +> 当前默认部署脚本:`scripts/git-incremental-deploy.ps1` -所有部署脚本都经过严格设计,确保**绝对不会**删除或修改生产服务器上的任何文件和目录。 +## 1. 当前结论 ---- +当前 Git 增量部署脚本只负责同步源码、构建镜像、推送镜像、替换应用容器和清理 Docker 无用资源。它不直接改业务数据,不直接操作数据库,不直接操作 MinIO 桶,也不清理生产 uploads 目录。 -## 🔒 安全保证 +普通上传、下载、转码等业务写入仍由应用运行时完成,不属于部署脚本的文件操作。 -### 1. uploads 目录保护 +## 2. uploads 目录边界 -**绝对不会**对 `/mnt/PoolOne/apps/youyidian-3d/uploads` 目录进行任何修改操作: +生产 uploads 目录: -- ✅ **只挂载,不修改**:`-v /mnt/PoolOne/apps/youyidian-3d/uploads:/app/uploads` -- ✅ **容器内只读访问**:容器只能读取 uploads 目录中的文件 -- ✅ **不执行任何删除命令**:脚本中没有 `rm`、`rmdir`、`delete` 等针对 uploads 的操作 +```text +/mnt/PoolOne/apps/youyidian-3d/uploads +``` -### 2. 数据库保护 +容器挂载: -**绝对不会**对数据库进行任何操作: - -- ❌ **不执行任何 SQL 命令**:没有 `psql`、`DROP`、`DELETE`、`UPDATE`、`INSERT`、`TRUNCATE` -- ❌ **不操作数据库容器**:不会 `docker stop`、`docker rm`、`docker exec` 数据库容器 -- ❌ **不执行数据库迁移**:没有 `prisma migrate`、`prisma db push` -- ✅ **只通过环境变量连接**:应用容器通过 `DATABASE_URL` 连接数据库(只读/写业务数据) - -**数据库容器**: -- `gongxiangpan-postgres-1`(PostgreSQL)- **不会被操作** -- 数据库文件:`/var/lib/postgresql/data`(在容器内)- **不会被访问** - -### 3. 存储桶保护 - -**绝对不会**对 MinIO 存储桶进行任何操作: - -- ❌ **不执行任何 S3 命令**:没有 `aws s3`、`mc`(MinIO Client) -- ❌ **不操作 MinIO 容器**:不会 `docker stop`、`docker rm`、`docker exec` MinIO 容器 -- ❌ **不删除任何对象**:没有 `s3 rm`、`mc rm` -- ✅ **只通过环境变量连接**:应用容器通过 `S3_ENDPOINT`、`S3_BUCKET` 连接存储桶(只读/写业务数据) - -**MinIO 容器**: -- `minio`(MinIO 存储服务)- **不会被操作** -- 存储桶:`gongxiangpan`(Bucket)- **不会被操作** -- 存储路径:`由壹点AI/`(前缀)- **不会被操作** - -### 2. 临时文件管理 - -所有临时文件都存放在 `/tmp/` 目录: - -- 镜像 tar 文件:`/tmp/youyidian-3d-material-latest.tar` -- 部署完成后自动清理 - -### 3. Docker 资源清理 - -只清理 Docker 相关资源,不涉及文件系统: - -- ✅ 清理旧镜像(`docker image prune`) -- ✅ 清理未使用的容器(`docker container prune`) -- ✅ 清理未使用的网络(`docker network prune`) -- ✅ 清理构建缓存(`docker builder prune`) -- ❌ **不清理任何文件目录** - ---- - -## 📋 脚本安全检查清单 - -### setup-build-server.ps1(配置构建机) - -**操作范围**:只在构建机(192.168.42.134)上操作 - -| 操作 | 说明 | 安全性 | -|------|------|--------| -| 安装 Docker Compose | 下载到 `/usr/local/bin/docker-compose` | ✅ 安全 | -| 创建 Registry 目录 | `/opt/docker-registry` | ✅ 安全 | -| 启动 Registry 容器 | Docker 容器,不涉及文件系统 | ✅ 安全 | - -**不涉及生产服务器**:此脚本只配置构建机,不会连接生产服务器。 - ---- - -### setup-production-server.ps1(配置生产服务器) - -**操作范围**:只修改 Docker 配置,不涉及任何文件目录 - -| 操作 | 说明 | 安全性 | -|------|------|--------| -| 备份 Docker 配置 | `/etc/docker/daemon.json` → `/etc/docker/daemon.json.backup.*` | ✅ 安全 | -| 修改 Docker 配置 | 添加 `insecure-registries` 配置 | ✅ 安全 | -| 重启 Docker 服务 | `systemctl restart docker` | ✅ 安全(容器自动重启)| -| 验证配置 | 测试连接 Registry | ✅ 安全 | - -**不涉及文件系统**: -- ❌ 不修改 uploads 目录 -- ❌ 不修改任何应用文件 -- ❌ 不删除任何数据 - -**重启影响**: -- Docker 服务重启时间:约 5-10 秒 -- 所有容器自动重启(`restart: always`) -- 服务短暂中断后自动恢复 - ---- - -### deploy-build-server.ps1(部署脚本) - -**操作范围**:构建镜像 → 传输镜像 → 启动容器 - -| 步骤 | 操作 | 涉及目录 | 安全性 | -|------|------|----------|--------| -| 1. 同步代码 | 打包代码上传到构建机 | `/opt/youyidian-3d-build` | ✅ 安全(构建机) | -| 2. 构建镜像 | 在构建机上构建 Docker 镜像 | Docker 镜像层 | ✅ 安全 | -| 3. 推送镜像 | 推送到构建机 Registry | `/opt/docker-registry/data` | ✅ 安全(构建机) | -| 4. 拉取镜像 | 生产服务器从 Registry 拉取 | Docker 镜像层 | ✅ 安全 | -| 5. 启动容器 | 停止旧容器,启动新容器 | 无 | ✅ 安全 | -| 6. 清理资源 | 清理 Docker 资源 | 无 | ✅ 安全 | - -**uploads 目录处理**: ```bash -v /mnt/PoolOne/apps/youyidian-3d/uploads:/app/uploads ``` -- ✅ **只挂载**:将宿主机目录挂载到容器内 -- ✅ **只读访问**:容器只能读取文件,不能修改 -- ✅ **不执行任何删除操作** -**临时文件**: -- 构建机:`/opt/youyidian-3d-build/*`(代码临时目录) -- 生产服务器:`/tmp/youyidian-3d-material-latest.tar`(镜像临时文件) -- 部署完成后自动清理 +部署脚本的边界: -**清理操作**: -- ✅ 清理 Docker 镜像(`docker image prune`) -- ✅ 清理 Docker 容器(`docker container prune`) -- ✅ 清理 Docker 网络(`docker network prune`) -- ✅ 清理构建缓存(`docker builder prune`) -- ❌ **不清理任何文件目录** -- ❌ **不清理 uploads 目录** -- ❌ **不清理应用数据** +- 只检查该目录是否存在。 +- 只把该目录挂载进应用容器。 +- 不对该目录执行 `rm`、`mv`、`cp`、`find -delete` 或清空操作。 +- 不改变该目录内已有源文件、视频文件、压缩包和上传临时数据。 ---- +需要注意:容器内应用对 `/app/uploads` 不是只读挂载。上传、下载、转码和清理临时上传会按业务逻辑读写这个目录,这和部署脚本本身的操作边界是两件事。 -## 🔍 与现有脚本对比 +## 3. 数据库边界 -### deploy-local-build.ps1(现有脚本) +部署脚本不会执行下面操作: -```powershell -# 启动容器命令 -docker run -d --name $containerName \ - -p $port:3000 \ - -v /mnt/PoolOne/apps/youyidian-3d/uploads:/app/uploads \ - --env-file /mnt/PoolOne/apps/youyidian-3d/$envFile \ - -e DISABLE_CACHE=true \ - -e DEPLOYMENT_VERSION=$deploymentVersion \ - -e DOWNLOAD_TOKEN_SECRET=$downloadTokenSecret \ - $ImageName:$ImageTag +- 不执行 SQL。 +- 不运行 Prisma migrate / db push。 +- 不停止、不删除 PostgreSQL 容器。 +- 不进入数据库容器执行命令。 + +部署后应用容器会通过生产 `.env` 中的 `DATABASE_URL` 正常连接数据库,这是业务运行必需行为。 + +## 4. MinIO / S3 边界 + +部署脚本不会执行下面操作: + +- 不执行 `aws s3` 或 `mc` 命令。 +- 不停止、不删除 MinIO 容器。 +- 不删除桶对象。 +- 不迁移桶数据。 + +部署后应用容器会通过 `S3_ENDPOINT`、`S3_BUCKET`、`S3_PUBLIC_DOMAIN` 等环境变量正常访问对象存储,这是业务运行必需行为。 + +当前素材存储口径: + +- 新素材预览 / 展示文件:写入新 MinIO 桶,公开 URL 统一为 `https://s3.jiansun.vip/gongxiangpan/public-display/...`。 +- 旧 `1080p.hk` 桶:只用于极少数老素材兼容,不作为新素材写入目标。 +- 源文件 / 下载型文件:落在生产机 uploads 目录,即 `/mnt/PoolOne/apps/youyidian-3d/uploads`。 + +## 5. 构建机操作范围 + +构建机:`192.168.42.134` + +Git 增量部署脚本会在构建机上使用下面目录作为 Git 工作区: + +```text +/root/youyidian-3d-git-build ``` -### deploy-build-server.ps1(新脚本) +脚本会在这个 Git 工作区内执行: + +- `git fetch --prune` +- `git reset --hard` +- `git clean -fdx` +- `docker build` +- `docker push` + +这些清理只针对构建机上的 Git 工作区和 Docker 虚拟资源,不涉及生产机 uploads、数据库或 MinIO 数据目录。 + +## 6. 生产机操作范围 + +生产机:`192.168.58.20` + +脚本会在生产机上执行: + +- 拉取构建机 Registry 中的应用镜像。 +- 停止并删除旧应用容器。 +- 用新镜像启动新应用容器。 +- 调用 `http://127.0.0.1:4320/api/health` 或影子环境健康检查。 +- 健康检查失败时,默认尝试用旧镜像回滚应用容器。 + +脚本只操作应用容器: + +- 正式:`youyidian-3d-material` +- 影子:`youyidian-3d-shadow` + +不会操作: + +- PostgreSQL 容器 +- Redis 容器 +- MinIO 容器 +- FRP 容器或服务 +- uploads 目录内容 + +## 7. 清理策略 + +默认清理内容: + +- 构建机悬空镜像。 +- 生产机 6 小时前的旧镜像。 +- 生产机 6 小时前的未使用容器。 + +默认不会清理: + +- uploads 目录。 +- MinIO 数据目录。 +- PostgreSQL 数据目录。 +- Docker volume。 +- 当前运行中的应用容器和镜像。 +- Docker build cache。 + +只有显式传入 `-AggressiveBuildCacheCleanup` 时,脚本才会额外清理较旧构建缓存。这个选项仍然只作用于 Docker 构建缓存,不作用于业务文件。 + +## 8. DryRun 安全性 + +DryRun 命令: ```powershell -# 启动容器命令(完全相同) -docker run -d --name $containerName \ - -p $port:3000 \ - -v /mnt/PoolOne/apps/youyidian-3d/uploads:/app/uploads \ - --env-file /mnt/PoolOne/apps/youyidian-3d/$envFile \ - -e DISABLE_CACHE=true \ - -e DEPLOYMENT_VERSION=$deploymentVersion \ - -e DOWNLOAD_TOKEN_SECRET=$downloadTokenSecret \ - $ImageName:$ImageTag +.\scripts\git-incremental-deploy.ps1 -DryRun ``` -**结论**:新脚本的容器启动命令与现有脚本**完全相同**,安全性一致。 +DryRun 只验证: ---- +- 构建机 SSH 可达。 +- 构建机能读取 Git 仓库。 +- 构建机能连接生产机。 +- 构建机 Registry 可用。 -## ✅ 安全承诺 +DryRun 不会: -### 绝对不会操作的资源 +- 同步代码到构建目录。 +- 构建镜像。 +- 推送镜像。 +- 停止或重启生产容器。 +- 修改业务文件。 -1. ❌ **uploads 目录**:`/mnt/PoolOne/apps/youyidian-3d/uploads` - - 不删除 - - 不修改 - - 不移动 - - 只挂载(只读访问) +## 9. 旧脚本说明 -2. ❌ **数据库**: - - 不执行任何 SQL 命令 - - 不操作数据库容器(`gongxiangpan-postgres-1`) - - 不执行数据库迁移 - - 只通过应用连接(业务读写) +旧版 `deploy-remote-build.ps1`、`deploy-local-build.ps1`、`deploy-public-build.ps1` 这类 `deploy-*.ps1` 属于本地历史脚本名,受 `.gitignore` 保护,不作为仓库交付入口。它们对应的“本机打包源码上传到构建机”、本地构建、公网穿透构建等链路,只作为识别历史资料使用。历史文档中提到的镜像 tar 临时文件、`deploy-build-server.ps1`、`deploy-local-build.ps1` 对比口径,不再代表当前默认部署链路。 -3. ❌ **存储桶**: - - 不执行任何 S3/MinIO 命令 - - 不操作 MinIO 容器(`minio`) - - 不删除任何对象 - - 只通过应用连接(业务读写) +当前默认链路不再把镜像 tar 文件复制到生产机,而是由生产机直接从构建机 Registry 拉取提交标签镜像。 -4. ❌ **其他容器**: - - 不操作 Redis 容器(`youyidian-3d-redis-shadow`) - - 不操作 frp 容器(`frpc-minio`) - - 只操作应用容器(`youyidian-3d-material`、`youyidian-3d-shadow`) +## 10. 出问题时怎么查 -### 只操作的资源 +查看应用日志: -1. ✅ **Docker 镜像**:清理旧镜像(虚拟资源) -2. ✅ **Docker 容器**:停止/启动应用容器 -3. ✅ **Docker 网络**:清理未使用的网络(虚拟资源) -4. ✅ **Docker 缓存**:清理构建缓存(虚拟资源) -5. ✅ **临时文件**:`/tmp/` 目录中的镜像 tar 文件 +```bash +ssh root@192.168.58.20 'docker logs --tail 120 youyidian-3d-material' +``` -### 操作日志 +检查健康接口: -所有操作都有详细的日志输出,可以追溯每一步操作。 +```bash +ssh root@192.168.58.20 'curl -fsS http://127.0.0.1:4320/api/health' +``` ---- +检查 uploads 目录是否还在: -## 🚨 如果出现问题 +```bash +ssh root@192.168.58.20 'ls -la /mnt/PoolOne/apps/youyidian-3d/uploads | head -20' +``` -### 回滚方案 +检查 Docker 镜像和容器: -1. **容器启动失败**: - ```bash - # 查看日志 - ssh root@192.168.58.20 'docker logs youyidian-3d-material' - - # 重启容器 - ssh root@192.168.58.20 'docker restart youyidian-3d-material' - ``` - -2. **Docker 配置问题**: - ```bash - # 恢复备份 - ssh root@192.168.58.20 'cp /etc/docker/daemon.json.backup.* /etc/docker/daemon.json' - ssh root@192.168.58.20 'systemctl restart docker' - ``` - -3. **uploads 目录检查**: - ```bash - # 检查目录是否存在 - ssh root@192.168.58.20 'ls -la /mnt/PoolOne/apps/youyidian-3d/uploads | head -20' - - # 检查文件数量 - ssh root@192.168.58.20 'find /mnt/PoolOne/apps/youyidian-3d/uploads -type f | wc -l' - ``` - ---- - -## 📞 联系方式 - -如有任何安全疑问,请立即停止操作并联系开发团队。 - ---- - -**文档版本**:v1.0 -**更新时间**:2025-01-17 -**维护人员**:开发团队 +```bash +ssh root@192.168.58.20 'docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"' +ssh root@192.168.58.20 'docker images | grep youyidian-3d-material' +``` diff --git a/docs/部署规范.md b/docs/部署规范.md index acb9e46..d528f99 100644 --- a/docs/部署规范.md +++ b/docs/部署规范.md @@ -1,221 +1,200 @@ # 部署规范 -## ⚠️ 重要声明 +> 更新时间:2026-05-07 +> 当前默认部署方式:`scripts/git-incremental-deploy.ps1` -**本项目强制使用 `deploy-remote-build.ps1` 脚本进行部署,除非项目负责人明确要求使用其他方式。** +## 1. 当前标准部署方式 ---- +本项目当前以 **Git 增量部署** 作为默认发布链路。源码先推送到 Git 仓库,构建机只从 Git 拉取增量代码并构建镜像,生产服务器只拉取镜像并替换应用容器。 -## 标准部署方式 - -### `deploy-remote-build.ps1` ⚡ **唯一推荐** - -**专用构建机部署方案** - 保护本地 SSD,提高构建效率 - -**架构**: -``` -你的电脑(内网) - ↓ SSH (192.168.42.134) - ↓ 传输代码(1-5MB) - ↓ -构建机 192.168.42.134 - ├─ Docker Registry (端口 5000) - ├─ Registry UI (端口 5001) - └─ 构建镜像(~180MB) - ↓ - ↓ 内网传输镜像 - ↓ -生产服务器 192.168.58.20 - └─ 部署容器 +```text +本机提交并推送源码到 Git + -> 构建机 git fetch / reset 到指定提交 + -> 构建机 docker build,复用 Docker / Next 缓存 + -> 构建机推送 production- 和 production-latest 镜像 + -> 生产机拉取指定提交镜像 + -> 停旧应用容器,启动新应用容器 + -> 检查 /api/health,失败时默认尝试回滚旧镜像 ``` -**核心优势**: -1. **保护本地 SSD**:构建过程在远程服务器,不占用本地磁盘 -2. **构建速度快**:Ubuntu 服务器性能强,构建速度比 Windows Docker Desktop 快 -3. **可视化管理**:Web UI 查看所有镜像版本(http://192.168.42.134:5001) -4. **自动清理**:保持构建机干净整洁 -5. **内网高速**:镜像传输走内网,速度快(1Gbps) - -**使用方法**: -```powershell -# 在项目根目录执行 - -# 部署到正式系统(端口 4320) -.\deploy-remote-build.ps1 - -# 部署到影子系统(端口 5320) -.\deploy-remote-build.ps1 -Target shadow - -# 跳过代码同步(代码已在构建机上) -.\deploy-remote-build.ps1 -SkipSync - -# 跳过镜像构建(镜像已存在) -.\deploy-remote-build.ps1 -SkipBuild - -# 不使用构建缓存(彻底重新构建) -.\deploy-remote-build.ps1 -NoCache - -# 保留旧镜像(不自动清理) -.\deploy-remote-build.ps1 -KeepOldImages -``` - -**参数说明**: -- `-Target`: 部署目标,`production`(正式系统,端口4320)或 `shadow`(影子系统,端口5320) -- `-BuildServerIP`: 构建机 IP(默认:192.168.42.134) -- `-ProdServerIP`: 生产服务器 IP(默认:192.168.58.20) -- `-SkipSync`: 跳过代码同步 -- `-SkipBuild`: 跳过镜像构建 -- `-NoCache`: 不使用构建缓存 -- `-KeepOldImages`: 保留旧镜像 - -**时间消耗**(每次部署): -- 代码打包:5-10秒 -- 代码上传:10-30秒(1-5MB) -- 镜像构建:1-3分钟(首次更长) -- 镜像推送到 Registry:10-20秒 -- 镜像拉取到生产服务器:30-60秒(180MB,内网 1Gbps) -- 容器启动:10-20秒 -- **总计**:2-5分钟/次 - ---- - -## 🚫 其他部署方式(不推荐) - -以下部署方式仅供参考,**不推荐使用**,除非项目负责人明确要求: - -### `deploy-local-build.ps1` ❌ -**本地构建部署** - 会在本地产生大量 Docker 缓存,磨损 SSD - -**问题**: -- 本地构建占用大量磁盘空间(~2GB) -- SSD 磨损严重(频繁读写) -- 构建速度慢(Windows Docker Desktop 性能差) -- 上传镜像慢(~180MB 通过网络) - -### `deploy-public-build.ps1` ⚠️ -**公网穿透部署** - 仅在特殊情况下使用(外网访问生产环境) - -**用途**:从公网访问生产环境进行部署(非常规操作) - -### `deploy-git-build.ps1` ⚠️ -**Git 工作流部署** - 需要配置 Git 仓库,复杂度高 - -**问题**: -- 需要配置 Git 仓库 -- 流程复杂(本地提交 → 推送 → 服务器拉取 → 构建) -- 不适合快速迭代 - ---- - -## Registry UI 使用 - -浏览器访问:`http://192.168.42.134:5001` - -**功能**: -- 查看镜像列表 -- 查看镜像标签(版本) -- 查看镜像详情(大小、创建时间、层信息) -- 删除不需要的镜像 - -**镜像命名规范**: -``` -youyidian-3d-material:latest # 最新版本 -youyidian-3d-material:20260126-1430 # 带时间戳的版本 -youyidian-3d-material:v1.0.0 # 带版本号的版本 -``` - ---- - -## 清理策略 - -### 自动清理(脚本默认行为) - -1. **构建机**: - - 清理 6 小时前的构建缓存 - - 清理悬空镜像(dangling images) - - 保留最近使用的基础镜像 - -2. **生产服务器**: - - 清理 6 小时前的旧镜像 - - 清理未使用的容器 - - 保留当前运行的容器和镜像 - -### 手动清理 - -```bash -# SSH 登录构建机 -ssh root@192.168.42.134 - -# 清理所有未使用的资源(谨慎使用) -docker system prune -af --volumes - -# 清理构建缓存(保留 5GB) -docker builder prune -af --filter "until=24h" - -# 清理悬空镜像 -docker image prune -f - -# 查看磁盘使用情况 -docker system df -df -h -``` - ---- - -## 故障排查 - -### 构建机连接失败 +脚本路径: ```powershell -# 测试网络连接 -ping 192.168.42.134 - -# 测试 SSH 连接 -ssh root@192.168.42.134 +.\scripts\git-incremental-deploy.ps1 ``` -### Registry 无法访问 +默认参数: + +- Git 仓库:`http://git.1080p.hk/lunanting/gongxiangp2.git` +- 分支:`main` +- 构建机:`192.168.42.134` +- 生产机:`192.168.58.20` +- 正式容器:`youyidian-3d-material` +- 正式端口:`4320` +- 影子容器:`youyidian-3d-shadow` +- 影子端口:`5320` + +正式部署由维护人员执行,不要求普通用户手动运行。 + +## 2. 常用命令 + +### 2.1 运行前准备 + +维护机需要具备: + +- PowerShell 5.1+。 +- PuTTY 工具:`plink.exe`、`pscp.exe`。 +- 构建机 SSH 凭据,通过 `BUILD_SERVER_PASSWORD` 或 `-BuildServerPassword` 提供。 +- Git 仓库认证,通过 `GIT_DEPLOY_USERNAME` / `GIT_DEPLOY_PASSWORD` 或 `GIT_AUTH_HEADER` 提供。 + +不要把 Git 密码写进仓库 URL,也不要把临时部署密码写入文档或提交到仓库。 + +### 2.2 部署命令 + +正式部署前先做 DryRun: + +```powershell +.\scripts\git-incremental-deploy.ps1 -DryRun +``` + +部署正式环境: + +```powershell +.\scripts\git-incremental-deploy.ps1 +``` + +部署影子环境: + +```powershell +.\scripts\git-incremental-deploy.ps1 -Target shadow +``` + +部署指定提交: + +```powershell +.\scripts\git-incremental-deploy.ps1 -Commit +``` + +必要时彻底重新构建: + +```powershell +.\scripts\git-incremental-deploy.ps1 -NoCache +``` + +## 3. 参数说明 + +- `-Target`:部署目标,`production` 或 `shadow`。 +- `-RepoUrl`:Git 仓库地址,默认使用 `lunanting/gongxiangp2`。 +- `-Branch`:部署分支,默认 `main`。 +- `-Commit`:指定提交;为空时部署目标分支最新提交。 +- `-DryRun`:只做连通性与依赖预检,不构建、不推镜像、不重启容器。 +- `-NoCache`:Docker 构建不使用缓存。 +- `-KeepOldImages`:跳过自动 Docker 镜像清理。 +- `-AggressiveBuildCacheCleanup`:额外清理较旧构建缓存;默认不启用。 +- `-SkipBuild` / `-SkipPush` / `-SkipDeploy`:只用于排障,不作为常规发布方式。 + +## 4. 安全边界 + +- 不从本机上传源码压缩包。 +- 不在生产机上执行 `npm install` 或 `next build`。 +- 不修改生产机 `.env` 文件。 +- 不删除、不移动、不覆盖生产机 uploads 目录内容。 +- 不直接操作 PostgreSQL、Redis 或 MinIO 容器。 +- 生产机只替换应用容器,并保留 `/mnt/PoolOne/apps/youyidian-3d/uploads:/app/uploads` 挂载。 +- 新容器健康检查失败时,脚本默认用旧镜像回滚应用容器。 + +详细安全说明见:[部署脚本安全说明](./部署脚本安全说明.md)。 + +## 5. 镜像标签 + +每次部署生成确定提交标签和移动标签: + +```text +production- # 正式环境确定版本 +production-latest # 正式环境最新版本 +shadow- # 影子环境确定版本 +shadow-latest # 影子环境最新版本 +``` + +Registry UI: + +```text +http://192.168.42.134:5001 +``` + +## 6. 清理策略 + +脚本默认只清理 Docker 虚拟资源,不清理业务文件目录。 + +构建机: + +- 清理悬空镜像。 +- 默认保留 Docker build cache,保证增量构建速度。 +- 只有传入 `-AggressiveBuildCacheCleanup` 时,才额外清理较旧构建缓存。 + +生产服务器: + +- 清理 6 小时前的旧镜像。 +- 清理 6 小时前的未使用容器。 +- 保留当前运行的应用容器、uploads 挂载目录、数据库和 MinIO 数据。 + +## 7. 历史脚本口径 + +### 本地历史脚本名 + +`deploy-remote-build.ps1`、`deploy-local-build.ps1`、`deploy-public-build.ps1` 这类 `deploy-*.ps1` 属于本地历史脚本名,受 `.gitignore` 保护,不作为仓库交付入口。 + +它们对应的是旧的“本机打包代码并上传到构建机”或“本地 / 公网穿透构建”链路,只能用于识别历史资料,不再是当前默认方式。 + +旧链路: + +```text +本地电脑打包源码 + -> SSH 上传源码压缩包到构建机 + -> 构建机构建镜像 + -> 推送 Registry + -> 生产机拉取镜像并替换容器 +``` + +### `deploy-git-build.ps1` + +历史 Git 部署脚本已被 `scripts/git-incremental-deploy.ps1` 替代。后续涉及 Git 增量部署时,只看新脚本和 [Git 增量部署方案](./Git增量部署方案.md)。 + +## 8. 故障排查顺序 + +### DryRun 失败 + +优先检查: + +- 构建机 SSH 是否可达。 +- 构建机能否读取 Git 仓库。 +- 构建机能否 SSH 到生产服务器。 +- 构建机本地 Registry 是否可用。 + +### Git 同步失败 + +优先检查: + +- Git 仓库地址是否正确。 +- Git 凭据是否正确。 +- `main` 分支是否已经推送最新代码。 + +### 生产容器启动失败 + +优先检查: ```bash -# 检查 Registry 状态 -ssh root@192.168.42.134 -cd /opt/docker-registry -docker-compose ps - -# 查看 Registry 日志 -docker-compose logs -f registry - -# 重启 Registry -docker-compose restart +ssh root@192.168.58.20 'docker logs --tail 120 youyidian-3d-material' +ssh root@192.168.58.20 'curl -fsS http://127.0.0.1:4320/api/health' ``` -### 镜像推送失败 +### uploads 目录检查 ```bash -# 检查 Registry 配置 -docker info | grep Registry - -# 手动推送测试 -docker tag youyidian-3d-material:latest localhost:5000/youyidian-3d-material:latest -docker push localhost:5000/youyidian-3d-material:latest +ssh root@192.168.58.20 'ls -la /mnt/PoolOne/apps/youyidian-3d/uploads | head -20' ``` -### 生产服务器拉取失败 +## 9. 版本历史 -```bash -# 检查 insecure-registry 配置 -ssh root@192.168.58.20 -docker info | grep -A 5 "Insecure Registries" - -# 测试连接 -curl http://192.168.42.134:5000/v2/_catalog - -# 手动拉取测试 -docker pull 192.168.42.134:5000/youyidian-3d-material:latest -``` - ---- - -## 版本历史 - -- **v1.0** (2026-01-26): 初始版本,强制使用 `deploy-remote-build.ps1` 部署 +- **v2.0** (2026-05-07): 默认部署方式切换为 `scripts/git-incremental-deploy.ps1`。 +- **v1.0** (2026-01-26): 旧版远程构建机脚本规范,现已降级为应急回退资料。 diff --git a/docs/钉钉素材库接口对接文档.md b/docs/钉钉素材库接口对接文档.md index 297b3f2..65d4427 100644 --- a/docs/钉钉素材库接口对接文档.md +++ b/docs/钉钉素材库接口对接文档.md @@ -2,13 +2,13 @@ ## 1. 对接目标 -钉钉流程填写以下 5 个字段后,调用素材库接口判断是否有符合条件的素材: +钉钉流程调用素材库接口判断是否有符合条件的素材。当前生产接口只要求 `SPU` 必填,其它筛选字段都是选填。 -- 需求类型 -- 品牌 -- 场景类别 -- 产品类别 -- SPU +- SPU(必填) +- 需求类型(选填) +- 品牌(选填) +- 场景类别(选填) +- 产品类别(选填) 返回规则: @@ -71,7 +71,7 @@ X-API-Key: 5073534d7a59babbc45397a8eac5943b 钉钉负责人配置时要注意: - `apiKey` 是固定参数,不要做成表单字段 -- 普通用户只需要填写或选择:需求类型、品牌、场景类别、产品类别、SPU +- 普通用户只需要填写 `SPU`;需求类型、品牌、场景类别、产品类别可作为选填筛选条件 - 如果钉钉侧有“连接器公共请求头”或“固定请求头”配置,也可以把 `X-API-Key` 配在那里 - 如果没有固定请求头能力,就直接使用本文档里的 `?apiKey=...` 地址 @@ -137,7 +137,7 @@ X-API-Key: 5073534d7a59babbc45397a8eac5943b ### 5.1 用途 -用户选择完 5 个字段后,调用这个接口判断有没有素材。 +用户填写 `SPU` 后即可调用这个接口判断有没有素材。其它字段如果传入,会作为附加筛选条件;不传则只按 SPU 查询。 ### 5.2 请求信息 @@ -158,16 +158,16 @@ X-API-Key: 5073534d7a59babbc45397a8eac5943b 请求参数: - `apiKey`:固定鉴权密钥,由钉钉负责人固定配置,不给普通用户填写 -- `requirementType`:需求类型 -- `brand`:品牌(实际是店铺) -- `sceneCategory`:场景类别 -- `productCategory`:产品类别 -- `spu`:SPU +- `spu`:SPU,必填 +- `requirementType`:需求类型,选填 +- `brand`:品牌(实际是店铺),选填 +- `sceneCategory`:场景类别,选填 +- `productCategory`:产品类别,选填 ### 5.3 请求示例 ```http -GET https://sc.jiansun.vip/api/external/dingtalk-material-match?apiKey=5073534d7a59babbc45397a8eac5943b&requirementType=任务-详情&brand=顾家家居&sceneCategory=客厅&productCategory=沙发&spu=SPU001 +GET https://sc.jiansun.vip/api/external/dingtalk-material-match?apiKey=5073534d7a59babbc45397a8eac5943b&spu=SPU001 ``` --- @@ -187,7 +187,7 @@ GET https://sc.jiansun.vip/api/external/dingtalk-material-match?apiKey=5073534d7 "brand": "顾家家居", "sceneCategory": "客厅", "productCategory": "沙发", - "address": "https://sc.jiansun.vip/uploads/previews/spu001.jpg", + "address": "https://s3.jiansun.vip/gongxiangpan/public-display/materials/preview-spu001.webp", "materialId": "material-1", "updatedAt": "2026-04-30T08:00:00.000Z" } @@ -228,10 +228,10 @@ GET https://sc.jiansun.vip/api/external/dingtalk-material-match?apiKey=5073534d7 推荐按以下顺序接入: -1. 先调用“下拉选项接口” -2. 用返回结果生成钉钉表单下拉 -3. 用户选择完 5 个字段后 -4. 再调用“素材匹配接口” +1. 钉钉流程固定配置 `apiKey` +2. 用户填写必填 `SPU` +3. 如需缩小范围,再选择需求类型、品牌、场景类别、产品类别 +4. 调用“素材匹配接口” 5. 根据 `matched` 和 `address` 做后续流程判断 --- @@ -239,7 +239,9 @@ GET https://sc.jiansun.vip/api/external/dingtalk-material-match?apiKey=5073534d7 ## 8. 注意事项 - `SPU` 为必填 -- 其余字段建议全部走下拉,不要手输 +- 其余字段均为选填;如果要使用,建议走下拉,不要手输 +- 新素材预览地址默认是 `https://s3.jiansun.vip/gongxiangpan/public-display/...` +- 只有少量历史兼容数据才可能返回 `/uploads/...` 或旧资源域名 - “品牌”不是独立品牌库字段,实际对应店铺 - “需求类型”不是自由文本,实际对应素材类型 - 如果接口返回 `INVALID_API_KEY`,说明 `apiKey` 参数或 `X-API-Key` 请求头没有正确配置 diff --git a/scripts/README.md b/scripts/README.md index e8714bc..3e2d1ff 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -1,148 +1,104 @@ # 脚本说明 -## ⚠️ 重要声明 +> 更新时间:2026-05-07 +> 部署相关脚本以 `scripts/git-incremental-deploy.ps1` 为当前默认口径。 -**本项目强制使用 `deploy-remote-build.ps1` 脚本进行部署**,除非项目负责人明确要求使用其他方式。 +详细说明: -**详细说明**:[部署规范](../docs/部署规范.md) +- [部署规范](../docs/部署规范.md) +- [Git 增量部署方案](../docs/Git增量部署方案.md) +- [部署脚本安全说明](../docs/部署脚本安全说明.md) ---- +## 1. 核心部署脚本 -## 核心部署脚本 +### `scripts/git-incremental-deploy.ps1` ⭐⭐⭐ 当前推荐 -### `scripts/git-incremental-deploy.ps1` ⭐⭐⭐ **Git 增量部署** - -**新推荐方向**:以 Git 仓库为唯一源码入口,构建机增量拉取源码并构建镜像,生产服务器只拉取镜像并替换容器。 +以 Git 仓库为唯一源码入口,构建机增量拉取源码并构建镜像,生产服务器只拉取镜像并替换容器。 特点: -- 不从本机上传源码压缩包 -- 构建机执行 `git fetch/reset` -- Docker 构建继续复用缓存 -- 镜像按提交打标签,便于回滚 -- 生产机不构建源码,只拉镜像运行 -- 默认失败时尝试回滚旧镜像 + +- 不从本机上传源码压缩包。 +- 构建机执行 `git fetch/reset`。 +- Docker 构建继续复用缓存。 +- 镜像按提交打标签,便于回滚。 +- 生产机不构建源码,只拉镜像运行。 +- 默认失败时尝试回滚旧镜像。 +- 默认清理 Docker 无用镜像/容器,保留构建缓存。 + +运行前准备: + +- 本机可用 PowerShell 5.1+。 +- 本机已安装 PuTTY,`plink.exe` 和 `pscp.exe` 可用。 +- 构建机密码通过 `BUILD_SERVER_PASSWORD` 或 `-BuildServerPassword` 提供。 +- Git 认证通过 `GIT_DEPLOY_USERNAME` / `GIT_DEPLOY_PASSWORD` 或 `GIT_AUTH_HEADER` 提供。 预检: + ```powershell .\scripts\git-incremental-deploy.ps1 -DryRun ``` +正式环境: + +```powershell +.\scripts\git-incremental-deploy.ps1 +``` + +影子环境: + +```powershell +.\scripts\git-incremental-deploy.ps1 -Target shadow +``` + +部署指定提交: + +```powershell +.\scripts\git-incremental-deploy.ps1 -Commit +``` + 正式部署由维护人员执行,不要求普通用户手动运行。 -### `deploy-remote-build.ps1` ⭐⭐⭐ **唯一推荐** -**专用构建机部署脚本** - 保护本地 SSD,提高构建效率 +## 2. 历史部署脚本 -**文件位置**:项目根目录(`deploy-remote-build.ps1`) +### `deploy-*.ps1` 本地历史脚本名 -**架构流程**: -``` -本地电脑 → SSH 上传代码(1-5MB) → 构建机(192.168.42.134) → 构建镜像 → 推送到Registry → 生产服务器拉取 → 启动容器 -``` +根目录 `deploy-*.ps1` 属于本地历史脚本名,受 `.gitignore` 保护,不作为仓库交付入口。 -**核心优势**: -1. 保护本地 SSD(构建在远程) -2. 构建速度快(Linux 原生) -3. 可视化管理(Registry UI: http://192.168.42.134:5001) -4. 镜像版本管理 -5. 内网高速传输(1Gbps) +曾经出现过的旧链路包括: -**使用方式:** -```powershell -# 在项目根目录执行 -# 部署到正式系统(端口 4320) -.\deploy-remote-build.ps1 +- `deploy-remote-build.ps1`:本机打包源码并上传到构建机。 +- `deploy-local-build.ps1`:本地构建部署。 +- `deploy-public-build.ps1`:公网穿透部署。 -# 部署到影子系统(端口 5320) -.\deploy-remote-build.ps1 -Target shadow +这些名字只用于识别历史资料,不再作为当前推荐方式。 -# 跳过代码同步 -.\deploy-remote-build.ps1 -SkipSync +### `deploy-git-build.ps1` ⚠️ 已替代 -# 跳过镜像构建 -.\deploy-remote-build.ps1 -SkipBuild +旧 Git 工作流脚本已被 `scripts/git-incremental-deploy.ps1` 替代。后续 Git 增量部署只看新脚本。 -# 不使用构建缓存 -.\deploy-remote-build.ps1 -NoCache +## 3. 旧缓存脚本 -# 保留旧镜像 -.\deploy-remote-build.ps1 -KeepOldImages -``` +下面这些脚本属于早期构建缓存方案,不是当前 Git 增量部署的默认前置步骤: -**参数说明:** -- `-Target`: 部署目标,`production`(正式系统,端口4320)或 `shadow`(影子系统,端口5320) -- `-BuildServerIP`: 构建机 IP(默认:192.168.42.134) -- `-ProdServerIP`: 生产服务器 IP(默认:192.168.58.20) -- `-SkipSync`: 跳过代码同步 -- `-SkipBuild`: 跳过镜像构建 -- `-NoCache`: 不使用构建缓存 -- `-KeepOldImages`: 保留旧镜像 +- `setup-build-cache.ps1` +- `build-base-image.ps1` +- `scripts/manage-build-cache.ps1` ---- +只有在明确要维护旧缓存方案时才参考它们。当前常规部署优先使用构建机上的 Docker / Next 缓存,不再传播 `save-base-images.ps1`、`load-base-images.ps1`、`save-npm-packages.ps1` 这类已不存在的脚本名。 -## 🚫 其他部署方式(不推荐) +## 4. 数据库迁移脚本 -以下脚本仅作为参考,**不推荐使用**,除非项目负责人明确要求: +### `scripts/execute-migration.ps1` -### `deploy-local-build.ps1` ❌ -**本地构建部署** - 会在本地产生大量 Docker 缓存,磨损 SSD +历史一次性迁移工具,只针对 `20251206000000_add_soft_delete_and_favorites` 这一个迁移,不是通用生产迁移入口。 -**问题**: -- 本地构建占用大量磁盘空间(~2GB) -- SSD 磨损严重(频繁读写) -- 构建速度慢(Windows Docker Desktop 性能差) -- 上传镜像慢(~180MB 通过网络) +高风险要求: -### `deploy-git-build.ps1` ⚠️ -**Git 工作流部署** - 需要配置 Git 仓库,复杂度高 +- 先确认该迁移在生产库尚未执行。 +- 先确认生产库备份可用。 +- 不在用户高峰期执行。 +- 不把它当作普通部署流程的一部分。 -**问题**: -- 需要配置 Git 仓库 -- 流程复杂(本地提交 → 推送 → 服务器拉取 → 构建) -- 不适合快速迭代 - -### `deploy-public-build.ps1` ⚠️ -**公网穿透部署** - 仅在特殊情况下使用(外网访问生产环境) - -**用途**:从公网访问生产环境进行部署(非常规操作) - ---- - -**⚠️ 再次提醒**:请使用 `deploy-remote-build.ps1` 进行部署,除非项目负责人明确要求其他方式。 - ---- - -## 基础镜像管理 - -### `save-base-images.ps1` -下载并保存基础镜像到本地缓存 -```powershell -.\save-base-images.ps1 -``` - -### `load-base-images.ps1` -从本地加载基础镜像(部署脚本会自动调用) -```powershell -.\load-base-images.ps1 -``` - -### `save-npm-packages.ps1`(可选) -缓存 npm 包到本地(网络不稳定时使用) -```powershell -.\save-npm-packages.ps1 -``` - -## 数据库迁移脚本 - -### `execute-migration.ps1` -在生产库上执行数据库迁移(Windows PowerShell) -```powershell -.\execute-migration.ps1 -``` - -### `execute-migration.sh` -在生产库上执行数据库迁移(Linux/Mac) -```bash -chmod +x execute-migration.sh -./execute-migration.sh -``` +### `scripts/execute-migration.sh` +Linux / macOS 版本的一次性迁移工具,适用范围同上。 diff --git a/scripts/execute-migration.ps1 b/scripts/execute-migration.ps1 index fe8905c..ca07a66 100644 --- a/scripts/execute-migration.ps1 +++ b/scripts/execute-migration.ps1 @@ -1,5 +1,6 @@ -# 生产库迁移执行脚本 -# 用途:在生产库上执行数据库迁移,添加 deletedAt、收藏、日志等新表和字段 +# 历史一次性生产库迁移执行脚本 +# 用途:只针对 20251206000000_add_soft_delete_and_favorites 迁移 +# 状态:不是通用生产迁移入口,不属于当前 Git 增量部署流程 # 注意:执行前请确保已备份生产库! param( diff --git a/scripts/execute-migration.sh b/scripts/execute-migration.sh index 108b88b..38495a8 100644 --- a/scripts/execute-migration.sh +++ b/scripts/execute-migration.sh @@ -1,7 +1,8 @@ #!/bin/bash -# 生产库迁移执行脚本(Linux/Mac 版本) -# 用途:在生产库上执行数据库迁移 +# 历史一次性生产库迁移执行脚本(Linux/Mac 版本) +# 用途:只针对 20251206000000_add_soft_delete_and_favorites 迁移 +# 状态:不是通用生产迁移入口,不属于当前 Git 增量部署流程 set -e diff --git a/scripts/manage-build-cache.ps1 b/scripts/manage-build-cache.ps1 index 818b17d..225e960 100644 --- a/scripts/manage-build-cache.ps1 +++ b/scripts/manage-build-cache.ps1 @@ -1,5 +1,6 @@ # 构建缓存管理脚本 # 功能:保存和恢复 node_modules 缓存,加速 Docker 构建 +# 状态:旧构建缓存方案,不是当前 Git 增量部署的默认前置步骤 param( [ValidateSet('save', 'check', 'clean')] diff --git a/scripts/update-docker-cache.ps1 b/scripts/update-docker-cache.ps1 deleted file mode 100644 index 2cda0fe..0000000 --- a/scripts/update-docker-cache.ps1 +++ /dev/null @@ -1,43 +0,0 @@ -# 更新 Docker 构建缓存 -# 用途:更新 npm-packages.tgz 缓存,加速后续构建 - -Write-Host "🔄 更新 Docker 构建缓存" -ForegroundColor Cyan -Write-Host "" - -# 检查 node_modules 是否存在 -if (-not (Test-Path "node_modules")) { - Write-Host "❌ node_modules 不存在,请先运行 npm install" -ForegroundColor Red - exit 1 -} - -# 创建缓存目录 -if (-not (Test-Path ".docker-cache")) { - New-Item -ItemType Directory -Path ".docker-cache" | Out-Null -} - -# 打包 node_modules -Write-Host "📦 正在打包 node_modules..." -ForegroundColor Yellow -$tarFile = ".docker-cache/npm-packages.tgz" - -# 使用 tar 命令打包(Windows 10+ 自带) -tar -czf $tarFile node_modules - -if (Test-Path $tarFile) { - $fileSize = (Get-Item $tarFile).Length / 1MB - Write-Host "✅ 缓存已更新:$([Math]::Round($fileSize, 2)) MB" -ForegroundColor Green - - # 更新缓存信息 - $cacheInfo = @{ - "created" = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") - "size_mb" = [Math]::Round($fileSize, 2) - "node_version" = (node -v) - "npm_version" = (npm -v) - } - $cacheInfo | ConvertTo-Json | Out-File ".docker-cache/cache-info.json" -Encoding UTF8 - - Write-Host "" - Write-Host "💡 提示:下次构建镜像时会使用此缓存,速度会快很多" -ForegroundColor Cyan -} else { - Write-Host "❌ 打包失败" -ForegroundColor Red - exit 1 -} diff --git a/setup-build-cache.ps1 b/setup-build-cache.ps1 index 70b5771..99253c8 100644 --- a/setup-build-cache.ps1 +++ b/setup-build-cache.ps1 @@ -1,5 +1,6 @@ # 由壹点3D素材 - 构建机缓存初始化脚本 # 功能:一次性准备所有缓存文件,后续构建直接使用,零解压、零网络 +# 状态:旧构建缓存方案,不是当前 Git 增量部署的默认前置步骤 param( [string]$BuildServerIP = '192.168.42.134', diff --git a/setup-build-server.ps1 b/setup-build-server.ps1 index 58b6e24..e15c514 100644 --- a/setup-build-server.ps1 +++ b/setup-build-server.ps1 @@ -316,8 +316,9 @@ EOFCONFIG Write-Info "1. 在浏览器访问 Registry UI:http://$BuildServerIP`:5001" Write-Info "2. 配置生产服务器(运行下面的命令):" Write-Host " .\setup-production-server.ps1" -ForegroundColor Yellow - Write-Info "3. 测试部署:" - Write-Host " .\deploy-build-server.ps1 -Target shadow" -ForegroundColor Yellow + Write-Info "3. 测试 Git 增量部署:" + Write-Host " .\scripts\git-incremental-deploy.ps1 -DryRun" -ForegroundColor Yellow + Write-Host " .\scripts\git-incremental-deploy.ps1 -Target shadow" -ForegroundColor Yellow Write-Host "" } diff --git a/setup-production-server.ps1 b/setup-production-server.ps1 index d197385..61023ff 100644 --- a/setup-production-server.ps1 +++ b/setup-production-server.ps1 @@ -300,10 +300,12 @@ EOFCONFIG Write-Host "" Write-Host "🎯 下一步操作" -ForegroundColor Magenta Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan - Write-Info "1. 测试部署到影子系统:" - Write-Host " .\deploy-build-server.ps1 -Target shadow" -ForegroundColor Yellow - Write-Info "2. 如果测试成功,部署到正式系统:" - Write-Host " .\deploy-build-server.ps1 -Target production" -ForegroundColor Yellow + Write-Info "1. 先做 Git 增量部署预检:" + Write-Host " .\scripts\git-incremental-deploy.ps1 -DryRun" -ForegroundColor Yellow + Write-Info "2. 测试部署到影子系统:" + Write-Host " .\scripts\git-incremental-deploy.ps1 -Target shadow" -ForegroundColor Yellow + Write-Info "3. 如果测试成功,部署到正式系统:" + Write-Host " .\scripts\git-incremental-deploy.ps1" -ForegroundColor Yellow Write-Host "" } diff --git a/部署前安全检查清单.md b/部署前安全检查清单.md deleted file mode 100644 index 1fe3dbe..0000000 --- a/部署前安全检查清单.md +++ /dev/null @@ -1,197 +0,0 @@ -# 部署前安全检查清单 - -## ✅ 运行脚本前请确认 - -### 1. 构建机配置(setup-build-server.ps1) - -**操作范围**:只在构建机(192.168.42.134) - -- [ ] 确认目标服务器是构建机:`192.168.42.134` -- [ ] 确认不会连接生产服务器 -- [ ] 确认只安装 Docker Compose 和 Registry -- [ ] 确认不会操作任何数据 - -**安全保证**: -- ✅ 不会连接生产服务器 -- ✅ 不会操作数据库 -- ✅ 不会操作存储桶 -- ✅ 不会操作 uploads 目录 - ---- - -### 2. 生产服务器配置(setup-production-server.ps1) - -**操作范围**:只修改 Docker 配置 - -- [ ] 确认目标服务器是生产服务器:`192.168.58.20` -- [ ] 确认只修改 `/etc/docker/daemon.json` -- [ ] 确认会备份现有配置 -- [ ] 确认重启 Docker 时间约 5-10 秒 - -**安全保证**: -- ✅ 不会操作 uploads 目录 -- ✅ 不会操作数据库 -- ✅ 不会操作存储桶 -- ✅ 不会删除任何文件 -- ✅ 容器会自动重启 - -**重启影响**: -- ⚠️ Docker 服务重启:5-10 秒 -- ⚠️ 所有容器短暂中断后自动恢复 -- ✅ 数据不会丢失 - ---- - -### 3. 部署脚本(deploy-build-server.ps1) - -**操作范围**:构建镜像 → 传输镜像 → 启动容器 - -- [ ] 确认部署目标(shadow 或 production) -- [ ] 确认只操作应用容器 -- [ ] 确认 uploads 目录只挂载,不修改 -- [ ] 确认临时文件在 /tmp/ 目录 - -**安全保证**: -- ✅ uploads 目录:只挂载,不修改 -- ✅ 数据库:不操作(只通过应用连接) -- ✅ 存储桶:不操作(只通过应用连接) -- ✅ 其他容器:不操作(PostgreSQL、MinIO、Redis、frp) -- ✅ 临时文件:自动清理 - -**操作的容器**: -- ✅ `youyidian-3d-material`(正式系统) -- ✅ `youyidian-3d-shadow`(影子系统) - -**不操作的容器**: -- ❌ `gongxiangpan-postgres-1`(数据库) -- ❌ `minio`(存储服务) -- ❌ `youyidian-3d-redis-shadow`(Redis) -- ❌ `frpc-minio`(frp 客户端) - ---- - -## 🔍 运行前检查命令 - -### 检查生产服务器状态 - -```powershell -# 检查运行中的容器 -& "C:\Program Files\PuTTY\plink.exe" -batch -pw "jsjj8888" root@192.168.58.20 "docker ps --format 'table {{.Names}}\t{{.Status}}'" - -# 检查 uploads 目录(只看前 20 个文件) -& "C:\Program Files\PuTTY\plink.exe" -batch -pw "jsjj8888" root@192.168.58.20 "ls -la /mnt/PoolOne/apps/youyidian-3d/uploads | head -20" - -# 检查 uploads 文件数量 -& "C:\Program Files\PuTTY\plink.exe" -batch -pw "jsjj8888" root@192.168.58.20 "find /mnt/PoolOne/apps/youyidian-3d/uploads -type f | wc -l" -``` - -### 检查构建机状态 - -```powershell -# 检查 Docker 版本 -& "C:\Program Files\PuTTY\plink.exe" -batch -pw "Jsjj@8888" root@192.168.42.134 "docker --version" - -# 检查磁盘空间 -& "C:\Program Files\PuTTY\plink.exe" -batch -pw "Jsjj@8888" root@192.168.42.134 "df -h /" -``` - ---- - -## 📋 运行步骤 - -### 第一次配置(只需执行一次) - -1. **配置构建机**: - ```powershell - .\setup-build-server.ps1 - ``` - - 预计时间:2-3 分钟 - - 操作:安装 Docker Compose + Registry - - 影响:无(只在构建机) - -2. **检查生产服务器**(不修改): - ```powershell - .\setup-production-server.ps1 -DryRun - ``` - - 预计时间:30 秒 - - 操作:只检查,不修改 - - 影响:无 - -3. **配置生产服务器**: - ```powershell - .\setup-production-server.ps1 - ``` - - 预计时间:1 分钟 - - 操作:配置 insecure-registry - - 影响:Docker 重启 5-10 秒 - -### 日常部署(每次部署) - -1. **部署到影子系统**(测试): - ```powershell - .\deploy-build-server.ps1 -Target shadow - ``` - - 预计时间:2-5 分钟 - - 操作:构建 → 传输 → 部署 - - 影响:只影响影子系统(端口 5320) - -2. **部署到正式系统**(生产): - ```powershell - .\deploy-build-server.ps1 -Target production - ``` - - 预计时间:2-5 分钟 - - 操作:构建 → 传输 → 部署 - - 影响:正式系统短暂重启(约 10 秒) - ---- - -## 🚨 紧急回滚 - -### 如果部署出现问题 - -1. **查看容器日志**: - ```powershell - & "C:\Program Files\PuTTY\plink.exe" -batch -pw "jsjj8888" root@192.168.58.20 "docker logs youyidian-3d-material --tail 100" - ``` - -2. **重启容器**: - ```powershell - & "C:\Program Files\PuTTY\plink.exe" -batch -pw "jsjj8888" root@192.168.58.20 "docker restart youyidian-3d-material" - ``` - -3. **恢复 Docker 配置**(如果配置有问题): - ```powershell - & "C:\Program Files\PuTTY\plink.exe" -batch -pw "jsjj8888" root@192.168.58.20 "cp /etc/docker/daemon.json.backup.* /etc/docker/daemon.json && systemctl restart docker" - ``` - -4. **检查 uploads 目录**(确认没有被删除): - ```powershell - & "C:\Program Files\PuTTY\plink.exe" -batch -pw "jsjj8888" root@192.168.58.20 "ls -la /mnt/PoolOne/apps/youyidian-3d/uploads | head -20" - ``` - ---- - -## ✅ 最终确认 - -在运行任何脚本前,请确认: - -- [ ] 我已阅读并理解所有安全保证 -- [ ] 我确认脚本不会操作 uploads 目录 -- [ ] 我确认脚本不会操作数据库 -- [ ] 我确认脚本不会操作存储桶 -- [ ] 我知道如何查看日志和回滚 -- [ ] 我已备份重要数据(如果是第一次运行) - ---- - -**准备好了吗?开始配置!** - -1. 先运行:`.\setup-build-server.ps1` -2. 然后运行:`.\setup-production-server.ps1 -DryRun`(检查) -3. 确认无误后:`.\setup-production-server.ps1`(配置) -4. 最后测试:`.\deploy-build-server.ps1 -Target shadow`(部署到影子系统) - ---- - -**文档版本**:v1.0 -**更新时间**:2025-01-17