zijunchiang
|
8c76b0a599
|
feat(web): 移除 Docker 与反代部署,改为 Linux 业务服务并自带管理端托管
需求变更:Web 端只保留业务需求,反向代理交由另外的服务处理,
本项目仅提供 IIS / nginx 反代说明文档,不部署反代。
主要改动:
- web-server: 新增管理端静态托管(ADMIN_DIR、SPA 深链接回退),
反代因此只需一条全匹配转发规则;新增 adminDir 配置项
- deploy/install.sh: 删除 nginx 安装与站点配置逻辑,改为原生 Linux
服务部署(systemd → OpenRC → SysVinit → 后台进程四级降级),
打印反代交接指引
- deploy/ctl.sh: 启停/状态/日志脚本
- deploy/proxy/: 新增反代说明文档(README.md、nginx.conf.example、
web.config.example),标注上传上限与超时必须同步调整
- 删除 deploy/nginx/、web-server/admin/nginx.conf、Dockerfile、
docker-compose.yml、.dockerignore
- scripts/package-release.sh: 锚定排除规则 + 产物完整性校验
- 文档同步:README.txt、DSH.md、project.yaml、tasks/008、tasks/010
|
2026-09-15 01:25:19 +08:00 |
|
zijunchiang
|
653d9d168c
|
feat(deploy): 缺少 deploy/.env 时复用安装目录中的历史配置
用户在重新解压发布包后再次执行 install.sh,因缺少 deploy/.env 被拦下。
按文档流程每次升级都要重新解压,若每次都要求重填数据库口令,既繁琐
又容易出错(口令含 * 等特殊字符)。
- 优先使用当前目录的 deploy/.env
- 其次复用 $APP_DIR/deploy/.env(上次安装留下的配置)
- 两处都没有才报错,且错误信息列出需要填写的五个字段及注意事项
实测三种情形:
全新安装(两处都无)→ 报错并给出字段说明,退出码 1
安装目录有历史配置 → 自动复用,退出码 0
当前目录已有 .env → 直接使用,不覆盖
|
2026-09-15 01:03:20 +08:00 |
|
zijunchiang
|
87a1ded2d2
|
fix(deploy): install.sh 复制时同样误排除了 storage 目录
用户重装后仍报同一错误,且日志显示「复制 web-server … 174 个文件」。
经复现:发布包内 web-server 有 180 个文件(含 src/storage 2 个、
dist/storage 4 个),但 install.sh 复制后只剩 174 个——storage 被剔除了。
根因:上一轮只修了 package-release.sh,install.sh 里**还有一份独立的
copy_tree() 排除规则**,其中 'storage' 同样未锚定。install.sh 的
COPY_EXCLUDES 与 tar 回退分支都把 'storage' 当作任意层级模式,
于是 src/storage 与 dist/storage 在复制进 /opt/opendance 时被剔除。
这是同一类错误在本项目的第三次(.gitignore → package-release.sh →
install.sh)。因此这次不再只改模式,而是把语义显式化并加硬校验:
- 排除规则拆成三类常量,语义明确:
TOP_DIRS 仅顶层:storage data tmp dist-release → 必须锚定
ANY_DIRS 任意层级:node_modules .git coverage .gradle
TOP_FILES 仅顶层文件:.env .env.local
- rsync 用前导 '/' 锚定;tar 对 TOP_* 只给 './x'(绝不给 '*/storage'),
对 ANY_* 才给 './x' + '*/x'
- 复制后硬校验关键产物(dist/main.js、dist/storage/storage.module.js、
dist/app.module.js、admin/index.html),缺失即 die 并指出是排除规则问题
实测:
- rsync 路径:180 文件,src/storage 与 dist/storage 均在,
运行时 storage 与 .env 未带入,.env.example 保留
- tar 回退路径(隔离 PATH 屏蔽 rsync 后真跑):同样 180 文件,存储目录完整
- git 检出布局:214 文件,嵌套 admin/node_modules 未带入,本地 .env 未带入
- 对照实验:把锚定改回未锚定 → 复制剩 174 文件 → 守卫立刻报
「缺少关键文件 dist/storage/storage.module.js」并终止,不再拖到启动才炸
|
2026-09-15 01:00:58 +08:00 |
|
zijunchiang
|
caca7672cb
|
fix(release): 修复发布包缺失 storage 模块,并加入产物完整性校验
用户实测:用发布包部署后启动报 MODULE_NOT_FOUND
at dist/models/models.module.js:13 require('../storage/storage.module')
根因:package-release.sh 的 rsync 用了 --exclude 'storage'。该模式匹配
**任意层级**的同名目录,把源码目录 src/storage/ 与编译产物 dist/storage/
一并排除——发布包里完全没有 storage 模块,服务必然起不来。
这与第一阶段 .gitignore 里 'storage/' 误伤 src/storage/ 是同一类错误,
本项目第二次踩到。
修复:
- 排除模式全部锚定到 web-server 根:'/storage/'、'/data/'、'/tmp/'、
'/.env'、'/admin/',不再匹配嵌套同名目录
- 新增产物完整性校验(打包后自动执行,失败即删除压缩包):
src 下每个 .ts 必须有对应 dist/*.js;关键文件清单齐全;
不得混入 node_modules / 真实 .env / 运行时存储 / keystore
- ctl.sh 补上缺失的 warn 函数(line 120: warn: command not found)
实测:
- 对照实验:排除模式改回 'storage' 后校验准确报出缺少
dist/storage/storage.module.js 并删除压缩包,退出码 1
- 新包端到端:解压 → npm ci --omit=dev(213 包)→ 启动 → /health 200、
MariaDB 已连接、迁移 0、catalog/songs/models/motions 全部 200
|
2026-09-15 00:54:22 +08:00 |
|
zijunchiang
|
f6fe9af0a2
|
fix(deploy): 修复 NODE_ENV 污染导致管理端构建失败(tsc: not found)
用户实测:部署时构建管理端报 `sh: 1: tsc: not found`,且 npm 只装了 23 个包。
根因:脚本开头用 `set -a; . deploy/.env; set +a` 载入 .env,其中的
NODE_ENV=production 被导出到脚本自身环境;npm 见到它便会跳过
devDependencies,于是 typescript / vite / nest 等构建工具全部缺失。
本地实测完全复现:
NODE_ENV=production npm ci → added 23 package,无 tsc
env -u NODE_ENV npm ci --include=dev → added 53 package,tsc/vite 齐备
修复:
- 新增 npm_install_with_dev():统一用 `env -u NODE_ENV npm ... --include=dev`
- 管理端构建改用它;**API 构建回退路径存在同一隐患,一并修复**
- 管理端改为在 $APP_DIR/web-server/admin 内构建(不再污染源码树、
也不要求源码目录可写),构建完删除该处 node_modules 释放磁盘
- 构建失败时给出可操作提示(改用发布包)
另修复一处静默的信息泄露:
- 复制源码树时未排除 .env,本地开发用的 web-server/.env(含真实数据库
口令)会被复制进 /opt/opendance/web-server/.env;deploy/.env 才是权威配置,
多一个 dotenv 配置源只会造成排障困惑。已把 .env / .env.local 加入排除,
并验证 .env.example 不受影响(209 → 208 个文件)
实测:
旧行为 tsc 缺失、构建报 tsc: not found(与用户报错一致)
新行为 tsc/vite 齐备,vite build 成功产出 dist/index.html + 3 个 assets
复制排除:.env 不复制、.env.example 保留、node_modules 无泄漏
|
2026-09-15 00:44:54 +08:00 |
|
zijunchiang
|
c092b833fb
|
fix(deploy): 支持无 systemd 的环境,并修复降级路径的两个真实缺陷
用户实测:服务器没有 systemctl,install.sh 直接报错退出。
原错误信息本身也是错的(建议 SKIP_NGINX=1,但那只跳过 nginx,仍走 systemctl)。
进程管理改为四层降级:
systemd → OpenRC → SysVinit → nohup 后台进程(deploy/ctl.sh)
- 新增 deploy/ctl.sh:start/stop/restart/status/logs,PID 文件 + 进程名双重判定
- 新增 deploy/openrc/opendance-api、deploy/initd/opendance-api
- 无 init 系统时写 crontab @reboot 实现开机自启
- uninstall.sh 同步支持四种模式清理(原先只处理 systemd,会留下运行中的进程)
- 汇总输出按实际初始化系统给出对应运维命令
测试中发现并修复降级路径的两个真实缺陷:
1. nohup 无法调用 shell 函数
实测退出码 127 且什么都不执行
(nohup 是外部命令,只能执行可执行文件)。
这会让无 systemd 的降级路径完全失效——服务根本起不来。
改为按 runuser / setpriv / su 显式拼接成外部命令后再 nohup。
另加启动后 1 秒存活检测,失败立即打印日志,不再白等 30 秒。
2. find_pids 在无进程时返回一个空格
在空输入下仍会执行一次 echo,输出空行,
最终得到 " ";调用方 [ -n ... ] 会判为「有进程」,
导致 start 直接跳过、status 谎报运行中。改为纯 bash 拼接,空时返回空串。
实测(真实 API 进程,端口 3100):
start → 健康检查 200,PID 正确
重复 start → 识别已在运行,进程数保持 1
status → 运行中
restart → 新 PID,健康检查 200
stop → 无残留进程,端口释放
无 process 时 find_pids 返回空串,is_running=false
|
2026-09-15 00:34:52 +08:00 |
|
zijunchiang
|
1ffe3059af
|
fix(deploy): install.sh 不再依赖 sudo
用户实测报错:deploy/install.sh: line 173: sudo: command not found
本脚本已经强制要求 root 权限,用 sudo 降权到服务用户本就多余,
且部分服务器(尤其精简系统/容器)根本没有安装 sudo。
- 新增 as_service_user():runuser → setpriv → su 依次回退,
并在三者都不可用时给出明确错误
- 替换全部 sudo -u 调用(npm ci / npm install / npm run build / 迁移)
- 新增 http_get() / http_ok():curl → wget → node fetch 依次回退,
健康检查不再强依赖 curl
- 启动前检查 systemctl(本部署依赖 systemd),缺失时给出可操作提示
- 修正 install.sh / uninstall.sh 中所有「用 sudo 执行」的提示文案
实测(桩替换 runuser 验证分派与参数传递):
有 runuser:runuser -u opendance -- npm ci --omit=dev --loglevel=error
仅 su:正确回退到 su
HTTP:curl 路径与 node fetch 回退路径返回一致
|
2026-09-15 00:27:27 +08:00 |
|
zijunchiang
|
7cd607ecde
|
fix(deploy): 修复 install.sh 同步文件时的长时间卡死
用户实测:执行到「同步程序文件到 /opt/opendance」后卡死。
根因:在源码检出目录执行时,web-server/ 下有 node_modules(236MB /
27359 个文件,admin 下还有 122MB),原实现用 cp -r 全量复制,
随后又对整个目录 chown -R,处理三万个文件表现为卡死。
修复:
- 复制改用 copy_tree(),排除 node_modules/.git/storage/dist-release 等
运行期可再生目录;有 rsync 用 rsync -a --delete,否则用 tar 管道回退
- tar 回退的排除模式同时给出 './x' 与 '*/x':只写 './x' 无法匹配嵌套的
'./admin/node_modules'(实测会漏掉 122MB,等于没修)
- 增加目录安全检查:安装目录与源目录相同、或二者互相包含时直接报错退出,
避免 rm -rf 删掉源文件 / cp 无限递归
- 支持两种目录布局:发布包 admin/ 在根目录,源码检出在
web-server/admin/dist(缺失则现场构建),此前从源码目录执行必然在
「缺少 admin/ 目录」处失败
- 每个目录打印复制结果与文件数,npm 安装前给出预计耗时提示,
不再有长时间无输出的「假卡死」
- 失败时 trap 打印行号
实测(用脚本中真实代码块驱动的用例):
源码检出目录 → /tmp:rsync 路径 1 秒 / 209 文件;tar 回退路径同样 209 文件
发布包解压目录 → /tmp:0 秒,admin 与 dist/main.js 均正确
同目录 / 嵌套目录两种危险布局:均被拒绝并给出可操作提示
两条路径均无 node_modules 泄漏
|
2026-09-15 00:14:06 +08:00 |
|
zijunchiang
|
32525dd59a
|
docs(web): 清理残留的 Docker 引用(admin README / project.yaml / 注释)
|
2026-09-14 22:47:47 +08:00 |
|
zijunchiang
|
07ee30d704
|
docs(web): 开发环境样例补充 HOST 说明
|
2026-09-14 22:45:31 +08:00 |
|
zijunchiang
|
75498db1c0
|
feat(web): 部署方式由 Docker 改为 Linux 原生站点(nginx + systemd)
需求变更:Web 服务端不再使用 Docker,改为直接运行在 Linux 上的网站。
- 移除 deploy/docker-compose.yml、web-server/Dockerfile、
web-server/admin/Dockerfile、web-server/.dockerignore
- 新增 deploy/install.sh:建服务用户与目录 → 装运行期依赖 → 迁移
→ 注册 systemd 服务 → 配置 nginx 站点 → 健康检查,一键完成
- 新增 deploy/systemd/opendance-api.service:ProtectSystem=strict 等
安全加固,ReadWritePaths 限定为上传目录
- 新增 deploy/nginx/opendance.conf:同站点托管管理端静态资源 +
反代 /api /health /static,client_max_body_size 512m,SPA 回退
- 新增 deploy/uninstall.sh:默认保留数据,--purge 才删除
- 新增配置项 HOST(AppConfig.bindHost):原生部署下 Node 只监听
127.0.0.1,不直接对外暴露,实测外部 IP 不可达
- 同步更新 contracts/rest-api.yaml、DSH.md、project.yaml、README.txt、
tasks/008、tasks/010 与发布打包脚本
|
2026-09-14 22:42:56 +08:00 |
|
zijunchiang
|
0c133986b4
|
test(web): 新增演示数据播种脚本(供管理端与客户端联调)
|
2026-09-14 20:08:20 +08:00 |
|
zijunchiang
|
dbd9155b40
|
fix(release): 打包清单读取避免 SIGPIPE 误报
v0.1.0
|
2026-09-14 19:01:58 +08:00 |
|
zijunchiang
|
b9215d4190
|
docs(web): 任务说明、DSH 约束与交付文档
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
5a8b77b0a4
|
feat(web): T-WEB-010 部署脚本(Docker Compose,不含 MySQL)
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
640736c77b
|
feat(web): T-WEB-008/009 管理端界面(歌曲/模型/动作/审核 + VRM 预览)
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
0f66b53480
|
feat(web): 客户端目录导出 /api/catalog/export 与版本指纹
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
7ff3f1598d
|
feat(web): T-WEB-007 上传审核流程(状态机 + 审核流水)
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
a2e3282603
|
feat(web): T-WEB-006 BVH/FBX → MediaPipe33 关键点预处理
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
73e793318e
|
feat(web): T-WEB-005 模型上传 + VRM 优先 + 版本识别
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
ff8c4dd26a
|
feat(web): T-WEB-004 动作数据上传 + 来源五元组校验
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
d9614aadb0
|
feat(web): T-WEB-003 /api/songs CRUD + 音频上传
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
6714b1e67c
|
feat(web): T-WEB-002 TypeORM 迁移生成表结构(5 表,可逆)
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
bd6cb9fa90
|
feat(web): T-WEB-001 NestJS 骨架 + 连接现有 MySQL 实例
|
2026-09-14 19:00:55 +08:00 |
|
zijunchiang
|
9b8fc6be96
|
chore(contracts): 冻结 v0.1.0 跨端契约(REST/WebSocket/数据模型/拓扑/格式/数据库)
|
2026-09-14 19:00:55 +08:00 |
|