b1f9642f61
fix: IM App Key 查询改用 is_default=1(enable_im 列不存在时报错)
2026-06-12 19:33:09 +08:00
a15c86d7e8
fix: SDK config 测试加 packageName 参数,IM 服务测试用真实 App Key
2026-06-12 19:31:11 +08:00
dde9a76029
feat: 支持 XUQM_CLEAN_DATA=1 在新建部署时清除旧数据目录
2026-06-12 19:14:47 +08:00
2f304d8384
feat: 预检自动检测内部端口冲突,WSL2/多套部署场景自动偏移 +10000
2026-06-12 19:09:44 +08:00
921db616e5
feat: 内部服务端口变量化(SVC_PORT_TENANT/FILE/WEB/IM/PUSH/UPDATE/LICENSE)
2026-06-12 19:09:33 +08:00
c7a2979f7c
fix: Redis 宿主机端口改为 127.0.0.1:REDIS_HOST_PORT(默认16379),避免 WSL2/已有 Redis 端口冲突
2026-06-12 19:00:48 +08:00
8d400e07cc
fix: Docker 镜像加速首选 docker.1ms.run(国内可用)
2026-06-12 18:56:25 +08:00
f8d02468db
feat: 自动检测并配置 Docker Hub 国内镜像加速(XUQM_SUDO_PASS 支持)
2026-06-12 18:46:37 +08:00
f7b5ac1a6c
fix: 自动移除 WSL2 Docker Windows 凭据存储配置(docker-credential-desktop.exe)
2026-06-12 18:43:57 +08:00
bddff7d9c8
fix: NONINTERACTIVE 已有部署时按 DEPLOY_MODE 自动选择更新或全量重部署
2026-06-12 18:42:25 +08:00
d327284af3
fix: NONINTERACTIVE 模式跳过 /dev/tty 重定向(CI/SSH 自动化部署)
2026-06-12 18:41:40 +08:00
f1de6167d3
fix: WSL兼容+verify加载secrets+deploy非交互模式
2026-06-12 18:34:47 +08:00
1c8988f973
fix: WSL兼容+verify加载secrets+deploy非交互模式
2026-06-12 18:34:46 +08:00
fac6f8b988
fix: WSL兼容+verify加载secrets+deploy非交互模式
2026-06-12 18:34:45 +08:00
徐勤民
de95af8e9f
fix(deploy): 解决一键更新后nginx服务停止问题
...
- 添加检查nginx运行状态逻辑
- 在nginx未运行时自动启动服务
- 防止因--remove-orphans时序问题导致的nginx停止
- 确保部署完成后nginx正常运行
2026-05-23 03:52:07 +08:00
徐勤民
bb23242cff
feat(nginx): 更新系统接口配置支持一键更新和重置功能
...
- 修改location规则从精确匹配改为正则匹配以支持update和reset两个接口
- 扩展注释说明同时覆盖一键更新和重置操作的超时需求
- 保持原有的长超时设置以确保docker操作能够顺利完成
2026-05-22 16:49:42 +08:00
徐勤民
dad0cebc4d
fix(deploy): inject FILE_BASE_URL and FILE_SERVICE_INTERNAL_URL into update-service
...
Allows update-service to rewrite file URLs to the internal Docker network address,
fixing APK inspection timeout when file is hosted at the customer's custom domain.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 16:03:21 +08:00
徐勤民
f16335c190
fix(nginx): 为一键更新接口设置 600s 超时
...
docker pull 期间可能长时间无输出,60s proxy_read_timeout 导致
ERR_INCOMPLETE_CHUNKED_ENCODING。添加精确匹配 location 解决。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 17:19:46 +08:00
徐勤民
ca7d01abb3
fix: tenant-service 部署根目录改为读写挂载
...
自动修复功能需要写入 nginx 配置和 docker-compose.yml,
只读挂载会导致一键更新中的配置修复步骤失败。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 17:07:52 +08:00
徐勤民
3d78c74b1b
fix: 修复文件上传 500 错误及文件持久化配置
...
1. nginx: location /file/ 改为 /api/file/(原路径未匹配到任何请求,
/api/file/upload 被 /api/ 兜底路由转发给 tenant-service 导致 500)
2. docker-compose: file-service 增加 FILE_UPLOAD_DIR=/data/uploads
和 FILE_BASE_URL=${CONSOLE_DOMAIN},确保文件写入持久化卷且
返回的下载 URL 指向私有服务器而非公有平台默认地址
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 17:00:08 +08:00
徐勤民
3242e7d088
fix(deploy): 补齐 LICENSE_PUBLIC_BASE_URL,修复私有化 license 文件域名错误
...
deploy.sh 和 update.sh 均写入 LICENSE_PUBLIC_BASE_URL,确保
生成的 license.xuqm 中 serverUrl 指向私有服务器而非公有云默认值。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 15:25:25 +08:00
徐勤民
c7e9cb8fa9
feat: docker.sock 挂载 + PRIVATE_DEPLOY_ROOT 支持一键更新
...
- docker-compose.yml:tenant-service 挂载 /var/run/docker.sock 和部署根目录
- deploy.sh:写入 PRIVATE_DEPLOY_ROOT 到 .env
- update.sh:旧版升级时自动补齐 PRIVATE_DEPLOY_ROOT
- .env.example:新增 PRIVATE_DEPLOY_ROOT 注释说明
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 14:47:18 +08:00
徐勤民
b9b90d7e7f
release: 2026.05.21-private.2
...
- License 最大设备数迁移至租户平台自助管理
- 移除运营后台授权管理入口
- Android SDK 1.0.1:XuqmSDK.initialize 新增 serverUrl 参数
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 13:00:16 +08:00
徐勤民
dde3f9ece7
docs: 整理全量文档
...
- README: 补充 reset.sh 快速入口和脚本对比表
- runbook: 新增「容器重置」章节和「故障排查」(502/crash-loop/WebSocket/镜像未生效)
- configuration: 修正端口表(im=11228/push=11229/update=11230/license=11231),
补充 SPRING_DATASOURCE_PASSWORD 设计说明,移除已废弃的 environment 密码块说明
- acceptance-checklist: 修正端口号,补充 WebSocket 多层透传说明,移除不存在的 11227 行
- deployment-defaults: 同步端口表,补充 reset.sh 和 WebSocket 注意事项
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:48:45 +08:00
徐勤民
e61a1dce08
docs(reset): 补充脚本关系说明及全新安装一行命令
...
在头部注释中明确 install.sh / update.sh / reset.sh 三者的使用场景,
并附上全新安装的 curl 一行命令,方便运维人员快速判断应执行哪个脚本。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:44:04 +08:00
徐勤民
5c9c4c890f
feat: 新增容器重置脚本 reset.sh
...
保留配置和数据卷,彻底重建所有容器并拉取最新镜像。
解决容器 IP 缓存失效、crash-loop、密码注入错误、镜像未生效等场景。
自动补齐旧版 secrets.env 缺少的 Spring 密码变量(迁移幂等)。
支持 --no-pull 标志跳过镜像拉取,仅重建容器。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:36:41 +08:00
徐勤民
33ae1b9599
fix(update): 升级时自动补齐旧 secrets.env 缺失的 Spring 密码变量
...
旧部署的 secrets.env 只有 MYSQL_PASSWORD / REDIS_PASSWORD,
新版 docker-compose.yml 已移除 environment 块中的密码覆盖,
改由 env_file 注入 SPRING_DATASOURCE_PASSWORD 等 Spring 直读变量。
update.sh 升级时自动检测并追加缺失条目,保证幂等且兼容旧部署。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:30:23 +08:00
徐勤民
429077e7eb
fix: 修复 docker compose 变量替换导致 DB/Redis 密码变空字符串
...
docker compose 的 environment 块在 shell 缺少 MYSQL_PASSWORD /
REDIS_PASSWORD 时将 SPRING_DATASOURCE_PASSWORD 替换为空字符串,
此空字符串会覆盖 env_file 注入的值,导致 Spring 连接 MySQL/Redis
时使用空密码(using password: NO)。
修复:
1. deploy.sh 在 secrets.env 中额外写入 SPRING_DATASOURCE_PASSWORD
和 SPRING_DATA_REDIS_PASSWORD,由 env_file 直接注入容器
2. docker-compose.yml 中删除这两个 environment 条目,消除覆盖风险
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:27:47 +08:00
徐勤民
b411e613bd
fix(nginx): 变量化 proxy_pass 配合 resolver 实现动态 DNS 解析
...
静态 proxy_pass 在 nginx 启动时解析主机名,容器重建后 IP 变更导致
502 且 nginx -s reload 因 host not found 失败。
改为 set $svc + proxy_pass http://$svc:port 写法,配合 resolver 127.0.0.11
每 10s 重新解析,容器重建后 nginx 自动感知新 IP,无需手动操作。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:17:25 +08:00
徐勤民
5e75dbeb90
fix(nginx): 添加 Docker DNS resolver 防止容器重建后 IP 缓存失效
...
nginx 默认在启动时静态解析上游服务名,容器重建后 IP 变更导致
502 Connection refused。添加 resolver 127.0.0.11 valid=10s 让
nginx 定期重解析,服务重建后无需手动 reload nginx。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:13:10 +08:00
徐勤民
dd1daaaae9
fix(update): 重启所有运行中的业务服务而非仅 tenant-service
...
原脚本只重启 tenant-service 和 nginx,导致 im-service/file-service 等
服务的镜像更新不生效。改为遍历所有可能的业务服务,按实际运行状态
决定是否重启,跳过未激活的可选服务。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:08:25 +08:00
徐勤民
34bfa71bd5
fix(update): 修复 WebSocket 101 误判 + 清理孤儿容器
...
- WebSocket 探测:curl 在 101 握手后无法继续 WS 协议会追加 000,
返回值为 "101000",改为 grep '^101' 判断首三位而非精确匹配
- up -d 加 --remove-orphans:自动清理已从 compose 文件移除的容器
(如之前删除的 ops-web),消除每次升级的 WARN 噪音
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 09:27:22 +08:00
徐勤民
777eb23b60
fix(update): restart→up -d 确保新镜像生效;新增 WebSocket 连通性自检
...
- 将 docker compose restart 改为 up -d --no-deps:
restart 仅重启容器进程,不切换镜像;up -d 检测镜像变更后重建容器,
是拉取新镜像后使其生效的正确方式
- 新增 Step 9 WebSocket 自检:
· 探测容器 nginx → im-service 本地握手(HTTP 101 = 正常)
· 同时探测外部域名 WebSocket 握手,失败时输出上层代理配置指引
(覆盖云 SLB/CDN 开启 WebSocket、nginx 补充四行头的两种场景)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 19:06:07 +08:00
徐勤民
4ff09ae768
feat(update): 完整重写热更新脚本,覆盖所有已知部署问题
...
Step 1 - CONSOLE_DOMAIN:检测裸 IP,交互提示输入公网域名
Step 2 - SDK URL:修复 xuqinmin.com 残留 / 内网 IP / 空值三种情形
Step 3 - SDK JSON:同步 xuqm-private-sdk.json
Step 4 - 宿主机 nginx WebSocket 头:
· nginx -T 获取完整配置
· Python3 精确定位代理到容器 nginx 的 location 块
· 缺少 proxy_http_version 1.1 / Upgrade / Connection 时自动注入
· 修改前备份 .xuqm.bak,nginx -t 失败自动回滚,成功后 nginx -s reload
· 未发现代理配置时输出标准模板供参考
Step 5 - 拉取镜像(可选)
Step 6 - 重启 tenant-service + nginx
Step 7 - 等待 tenant-service 健康(最长 120s)
Step 8 - 自动处理积压 PENDING 服务开通申请
Step 9 - 全量验证
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 18:58:28 +08:00
徐勤民
7d8f916ea5
fix(update): 检测并修复 CONSOLE_DOMAIN 及 SDK URL 为内网 IP 的情况
...
- CONSOLE_DOMAIN 为私有 IP 段时提示用户输入正确的公网域名
- SDK_IM_WS_URL / SDK_IM_API_URL / SDK_FILE_SERVICE_URL 包含
裸 IP(10.x / 172.x / 192.168.x / 127.x)时同样触发修复
- 提取 _url_needs_fix 辅助函数消除重复判断逻辑
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 18:49:50 +08:00
徐勤民
28fd8c0793
feat(update): upgrade 后自动调用 approve-pending-requests 修复积压申请
...
update.sh 在 tenant-service 健康后调用
POST /api/private/admin/approve-pending-requests
自动开通所有 PENDING 状态的服务申请,无需用户手动操作。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 18:46:00 +08:00
徐勤民
21d80a8449
release: 2026.05.20-private.2
...
修复:私有化模式下已有 PENDING 服务开通申请时重复申请返回 400
升级方式:运行 upgrade.sh 拉取最新 tenant-service 镜像后,
重新点击控制台「申请开通」即可自动审批。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 18:37:40 +08:00
徐勤民
a327a262dd
feat(deploy): 移除 ops-web、修复 SDK URL 注入、新增一键升级
...
核心变更:
- 完全移除 ops-web 容器(私有化部署无需运营后台)
- nginx sub_filter 替换前端 JS bundle 中的公网 SDK URL
- deploy.sh 写入正确的 SDK_IM_WS_URL / SDK_IM_API_URL / SDK_FILE_SERVICE_URL
- 新增 scripts/update.sh:热更新脚本,修复配置 + 可选拉镜像 + 重启 + 验证
- 新增 upgrade.sh:一键升级入口,curl 下载后直接执行,流程同 install.sh
- install.sh 检测已有部署(.env 存在),自动路由到 update.sh 而非重跑向导
- 关键配置文件(.env / secrets.env / xuqm.env)在 tarball 解压前备份后恢复
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 18:25:12 +08:00
徐勤民
0c4802b20a
feat(deploy): nginx 绑定模式可选,兼容有/无宿主机 nginx 两种场景
...
向导新增第 0d 步:询问宿主机 80 端口是否空闲。
- 空闲(多层代理/内网)→ NGINX_BIND=80,容器直接监听宿主机 80
- 已有 nginx(云服务器 HTTPS)→ NGINX_BIND=127.0.0.1:11223,宿主机加一条转发
docker-compose.yml nginx ports 改用 ${NGINX_BIND:-80}:80 变量控制。
端口检查、Step 7 验证地址、部署完成输出均根据模式动态调整。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 17:20:02 +08:00
徐勤民
8b0c05e0e4
feat(nginx): 容器直接绑定 0.0.0.0:80,宿主机无需 nginx 配置
...
将内置 nginx 从 127.0.0.1:11223 改为直接绑定宿主机 0.0.0.0:80。
上层 nginx 直接 proxy_pass 到本机 IP:80 即可,省去宿主机 nginx 配置环节。
同步更新端口检查(80)、部署完成提示、runbook/configuration/README 文档。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 17:15:53 +08:00
徐勤民
f490b62f0b
fix(deploy): 移除输出中硬编码的 IP 地址
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 17:12:33 +08:00
徐勤民
35f07bad95
fix(deploy): 修正端口检查、删除死代码、验证走内置nginx
...
1. 端口检查:80/443 → 11223(内置 nginx 实际使用的端口)
2. 删除 if false 死代码块(旧版 nginx 配置模板,137行无效代码)
3. Step 7 验证:改为 BASE_URL=http://127.0.0.1:11223,不依赖
宿主机或外层 nginx 是否已配置,避免部署后验证误报失败
4. 最终输出:添加多层 nginx 代理场景的 WebSocket 头透传提示
5. verify.sh:移除不存在的 docs-site 容器检查(避免恒定 WARN)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 16:56:42 +08:00
徐勤民
2f81f21e42
docs: 更新架构图和 nginx 配置说明至单入口设计
...
README 架构图改为内置 nginx 容器作为统一入口(端口 11223),
服务表移除 nginx-bundled(可选)改为 nginx 列入 base,
注意事项更新为 proxy_pass 127.0.0.1:11223。
configuration.md 将"内置 nginx(可选)"更正为必启服务。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 16:35:27 +08:00
徐勤民
a55121aa05
feat(nginx): 内置路由 nginx 作为统一入口,宿主机 nginx 只需一条 proxy_pass
...
将 nginx 容器从可选 profile 改为 base 必启服务,绑定 127.0.0.1:11223。
新增 config/nginx/conf.d/xuqm.conf 按 Docker 服务名路由所有内部请求。
部署完成提示从多条 location 精简为单条 proxy_pass http://127.0.0.1:11223 。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 16:13:04 +08:00
徐勤民
a5ecb30bf0
docs: 全面更新文档,清理过期内容,对齐最新设计
...
主要变更:
- README.md: 重写,入口改为一键 install.sh,补充架构图和端口表
- runbook.md: 重写,移除旧脚本引用和内部 agent 规则,补充 nginx 配置和端口对照
- configuration.md: 更新端口表(11224-11231),移除 docs-site 引用,
补充内置 nginx 说明(nginx-bundled profile)
- deployment-defaults.md: 改为通用模板,移除明文密码、真实 IP 和客户信息
- acceptance-checklist.md: 重写,改为直接 curl 端口验证,补充 license 和 nginx 验收项
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 16:06:42 +08:00
徐勤民
f2f9f06bf7
chore(config): 删除私有部署配置文件
...
- 移除 .deploy-state/current.json 部署状态文件
- 移除 .deploy-state/last-healthcheck.json 健康检查记录文件
- 移除 .deploy-state/progress.md 部署进度文档
- 移除 config/docs/docs-runtime.json 文档运行时配置文件
- 移除 config/sdk/xuqm-private-sdk.json SDK配置文件
2026-05-20 15:54:16 +08:00
徐勤民
964188ba8c
fix(ports): 宿主机端口改为 11224-11231
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 15:43:05 +08:00
徐勤民
69da547866
fix(ports): 宿主机端口改为 10223-10230,绑定 127.0.0.1
...
原端口(8080-9001)在 Windows/Hyper-V 环境下可能被系统排除导致绑定失败。
统一改用 10223 起顺序编号,同时绑定 127.0.0.1 限制只有本机 nginx 可访问:
10223 tenant-service 10224 file-service 10225 tenant-web
10226 ops-web 10227 im-service 10228 push-service
10229 update-service 10230 license-service
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 15:40:28 +08:00
徐勤民
2a250e79a0
refactor(deploy): 去除内置 nginx,各服务暴露宿主机端口,末尾输出 nginx 配置参考
...
私有化部署场景下用户通常有自己的 nginx,内置 nginx 容器会占用 80/443
与宿主机冲突,且域名/HTTPS 交互配置对用户是噪音。
- docker-compose.yml: nginx 容器改为 profile=nginx-bundled(默认不启动)
各业务容器增加 ports 暴露宿主机端口(9001/8086/8082/8083/8084/8085/8080/8081)
- deploy.sh: 去除 域名/HTTPS/certbot 交互,改为询问一个外部访问地址(用于 SDK 配置)
健康检查和 import API 直接打 127.0.0.1:9001,不再依赖 nginx 容器
末尾输出端口表和可直接复制的 nginx location 配置参考
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 15:30:55 +08:00
徐勤民
60aeb61433
fix(deploy): 迁移/新建租户后同步写入 app_licenses,修复 license 404
...
importData API 只写 t_tenant/t_app/t_feature_service,不写 license-service
的 app_licenses 表,导致前端 /api/license/admin/apps/:appKey 返回 404。
在 deploy.sh 的迁移和新建两个分支中,import 成功后直接对同一 MySQL 执行
INSERT ... ON DUPLICATE KEY UPDATE,为所有非系统应用补写 app_licenses 记录。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 12:11:19 +08:00