refactor: remove deprecated license service
这个提交包含在:
父节点
c8bd617ae0
当前提交
475067562c
10
.env.example
10
.env.example
@ -44,14 +44,13 @@ IMAGE_TAG=latest
|
||||
# im IM HTTP 和 WebSocket 服务
|
||||
# push 厂商推送通知服务
|
||||
# update 版本管理、RN 热更新、应用市场自动发布
|
||||
# license License 校验服务
|
||||
#
|
||||
# 完整部署示例(MySQL/Redis 托管):
|
||||
# COMPOSE_PROFILES=base,infra-mysql,infra-redis,im,push,update,license
|
||||
# COMPOSE_PROFILES=base,infra-mysql,infra-redis,im,push,update
|
||||
# 生产示例(外部 MySQL/Redis):
|
||||
# COMPOSE_PROFILES=base,im,push,update,license
|
||||
# COMPOSE_PROFILES=base,im,push,update
|
||||
#
|
||||
COMPOSE_PROFILES=base,infra-mysql,infra-redis,im,push,update,license
|
||||
COMPOSE_PROFILES=base,infra-mysql,infra-redis,im,push,update
|
||||
|
||||
# =============================================================================
|
||||
# 功能开关(与 COMPOSE_PROFILES 保持对应)
|
||||
@ -62,7 +61,6 @@ ENABLE_FILE=true
|
||||
ENABLE_IM=true
|
||||
ENABLE_PUSH=true
|
||||
ENABLE_UPDATE=true
|
||||
ENABLE_LICENSE=true
|
||||
ENABLE_BUGCOLLECT=true
|
||||
|
||||
# =============================================================================
|
||||
@ -133,8 +131,6 @@ FILE_DOMAIN=http://192.168.1.100
|
||||
IM_DOMAIN=http://192.168.1.100
|
||||
# 版本管理服务(未部署时留空)
|
||||
UPDATE_DOMAIN=http://192.168.1.100
|
||||
# License 服务(未部署时留空)
|
||||
LICENSE_DOMAIN=http://192.168.1.100
|
||||
# 推送服务(未部署时留空)
|
||||
PUSH_DOMAIN=http://192.168.1.100
|
||||
|
||||
|
||||
10
CHANGELOG.md
10
CHANGELOG.md
@ -23,17 +23,9 @@ bash scripts/update.sh
|
||||
|
||||
### 变更
|
||||
|
||||
**授权管理(License)**
|
||||
- 最大设备数配置迁移至租户平台(`/services/license/:appKey`),租户可自行修改,无需联系运营
|
||||
- 移除了运营后台的授权管理入口
|
||||
|
||||
**Android SDK**
|
||||
- 版本升级至 `1.0.1`,新增 `serverUrl` 参数
|
||||
- `XuqmSDK.initialize(context, appKey, serverUrl = "https://your-server.com")` 即可完成私有化初始化,SDK 内部自动配置所有服务端点及 License 服务指向,无需额外调用
|
||||
|
||||
**私有化部署配置修复**
|
||||
- 修复 `config/xuqm.env` 缺少 `LICENSE_PUBLIC_BASE_URL` 的问题:此前生成的 `license.xuqm` 中 `baseUrl` 指向公有云地址,导致 SDK 通过 `license.xuqm` 自动初始化时 License 请求打到公有云服务器
|
||||
- `scripts/update.sh` 和 `scripts/deploy.sh` 均已补充此配置项,升级脚本会自动将其更新为私有服务器地址
|
||||
- `XuqmSDK.initialize(context, appKey, serverUrl = "https://your-server.com")` 可使用指定私有化服务地址完成初始化
|
||||
|
||||
### 升级方法
|
||||
|
||||
|
||||
@ -56,11 +56,10 @@ bash scripts/reset.sh
|
||||
├── tenant-web /(兜底)
|
||||
├── im-service /api/im/ /ws/im
|
||||
├── update-service /api/v1/updates/ /api/v1/rn/
|
||||
├── license-service /api/license/
|
||||
└── push-service (厂商回调,按需)
|
||||
```
|
||||
|
||||
内置 nginx 容器直接绑定宿主机 `0.0.0.0:80`,**宿主机无需配置 nginx**,上层 nginx 直接 proxy_pass 到本机 IP 即可。各业务容器(11224–11231)绑定 `127.0.0.1`,仅用于本地调试。
|
||||
内置 nginx 容器直接绑定宿主机 `0.0.0.0:80`,**宿主机无需配置 nginx**,上层 nginx 直接 proxy_pass 到本机 IP 即可。各业务容器端口绑定 `127.0.0.1`,仅用于本地调试。
|
||||
|
||||
---
|
||||
|
||||
@ -83,7 +82,6 @@ bash scripts/reset.sh
|
||||
| im | im-service | IM HTTP + WebSocket |
|
||||
| push | push-service | 厂商推送 |
|
||||
| update | update-service | 版本管理 + RN 热更新 |
|
||||
| license | license-service | License 校验 |
|
||||
|
||||
```bash
|
||||
# 后期启用 / 禁用可选服务
|
||||
|
||||
@ -69,16 +69,6 @@ server {
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# License — 必须在通用 /api/ 之前
|
||||
location /api/license/ {
|
||||
set $svc license-service;
|
||||
proxy_pass http://$svc:8085;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# 文件上传下载 — 必须在通用 /api/ 之前
|
||||
location /api/file/ {
|
||||
set $svc file-service;
|
||||
|
||||
@ -60,9 +60,6 @@ XUQM_JWT_SECRET=
|
||||
# 留空时 install.sh 自动生成
|
||||
SDK_INTERNAL_TOKEN=
|
||||
|
||||
# License 服务调用 Token
|
||||
LICENSE_INTERNAL_TOKEN=
|
||||
|
||||
# =============================================================================
|
||||
# SMTP 邮件密码(发送验证码邮件)
|
||||
# =============================================================================
|
||||
|
||||
@ -163,24 +163,6 @@ services:
|
||||
- ./data/update:/data/update # 版本包存储目录
|
||||
restart: unless-stopped
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# License 服务(可选,profile: license)
|
||||
# 端口:8085(内部)
|
||||
# 负责设备激活数量校验和 License 有效期管理
|
||||
# ---------------------------------------------------------------------------
|
||||
license-service:
|
||||
image: ${REGISTRY}/license-service:${IMAGE_TAG}
|
||||
profiles: ["license"]
|
||||
ports:
|
||||
- "127.0.0.1:${SVC_PORT_LICENSE:-11231}:8085"
|
||||
env_file:
|
||||
- ./config/xuqm.env
|
||||
- ./config/secrets.env
|
||||
environment:
|
||||
SPRING_DATASOURCE_URL: "jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT:-3306}/${MYSQL_DATABASE:-xuqm_private}?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true"
|
||||
SPRING_DATASOURCE_USERNAME: "${MYSQL_USERNAME:-xuqm}"
|
||||
restart: unless-stopped
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Bug 收集服务(可选)
|
||||
# 端口:9006(内部),nginx 代理 /api/bugcollect/*
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
|
||||
- [ ] im-service 健康:`curl http://127.0.0.1:11228/actuator/health` 返回 200
|
||||
- [ ] update-service 健康:`curl http://127.0.0.1:11230/actuator/health` 返回 200
|
||||
- [ ] license-service 健康:`curl http://127.0.0.1:11231/actuator/health` 返回 200
|
||||
- [ ] push-service 已启动(厂商凭据按需填写)
|
||||
|
||||
## 中间件
|
||||
@ -28,18 +27,12 @@
|
||||
- [ ] Redis managed 模式:容器自动启动,AOF 持久化
|
||||
- [ ] 重启容器后数据完整
|
||||
|
||||
## License
|
||||
|
||||
- [ ] 所有应用在 `app_licenses` 表有对应记录
|
||||
- [ ] `/api/license/admin/apps/:appKey` 返回 200,不出现 404
|
||||
|
||||
## Nginx 配置
|
||||
|
||||
- [ ] 宿主机 nginx 配置后,通过外部地址可访问控制台
|
||||
- [ ] `/api/im/` 路由到 im-service(11228)
|
||||
- [ ] `/ws/im` WebSocket 连接正常(需每层 nginx 透传 `Upgrade` / `Connection` 头)
|
||||
- [ ] `/api/v1/updates/` 路由到 update-service(11230),不被通用 `/api/` 拦截
|
||||
- [ ] `/api/license/` 路由到 license-service(11231),不被通用 `/api/` 拦截
|
||||
- [ ] `/file/` 支持大文件上传(500MB)
|
||||
|
||||
## 公有化隔离
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|------|------|
|
||||
| `REGISTRY` | Docker 镜像仓库地址 |
|
||||
| `IMAGE_TAG` | 镜像版本,默认 `latest` |
|
||||
| `COMPOSE_PROFILES` | 启用的服务集合,默认 `base,infra-mysql,infra-redis,im,push,update,license` |
|
||||
| `COMPOSE_PROFILES` | 启用的服务集合,默认 `base,infra-mysql,infra-redis,im,push,update` |
|
||||
| `MYSQL_MODE` | `managed`(容器托管)或 `external`(客户自备) |
|
||||
| `REDIS_MODE` | `managed` 或 `external` |
|
||||
| `CONSOLE_DOMAIN` | 对外访问地址,用于服务间跳转和 SDK 配置 |
|
||||
@ -73,9 +73,8 @@ SDK_IM_WS_URL=wss://your-domain/ws/im
|
||||
| 11228 | im-service | 8082 | `/api/im/` `/ws/im` |
|
||||
| 11229 | push-service | 8083 | 厂商回调(按需) |
|
||||
| 11230 | update-service | 8084 | `/api/v1/updates/` `/api/v1/rn/` |
|
||||
| 11231 | license-service | 8085 | `/api/license/` |
|
||||
|
||||
11224–11231 全部绑定 `127.0.0.1`,仅用于直接调试。正常流量走内置 nginx(80 / 11223)。
|
||||
业务容器端口全部绑定 `127.0.0.1`,仅用于直接调试。正常流量走内置 nginx(80 / 11223)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -46,7 +46,6 @@
|
||||
| 11228 | im-service | 8082 |
|
||||
| 11229 | push-service | 8083 |
|
||||
| 11230 | update-service | 8084 |
|
||||
| 11231 | license-service | 8085 |
|
||||
|
||||
宿主机 nginx 配置参考见 [docs/runbook.md](runbook.md)。
|
||||
|
||||
|
||||
@ -68,7 +68,7 @@ location / {
|
||||
|-----------|------|
|
||||
| **80** | 内置 nginx 入口(无宿主机 nginx 场景,`NGINX_BIND=80`) |
|
||||
| **11223** | 内置 nginx 入口(有宿主机 nginx 场景,`NGINX_BIND=127.0.0.1:11223`) |
|
||||
| 11224–11231 | 各业务容器(绑定 127.0.0.1,仅调试用) |
|
||||
| 11224–11230 | 核心与可选业务容器(绑定 127.0.0.1,仅调试用) |
|
||||
|
||||
各业务容器端口仅用于直接调试,正常流量全部走内置 nginx 入口。
|
||||
|
||||
@ -135,7 +135,7 @@ bash scripts/restore.sh <backup-file>
|
||||
|
||||
1. 前往公有化平台控制台 → 安全中心 → 私有化部署迁移 → 生成迁移密钥
|
||||
2. 将 `pmk_` 开头的密钥粘贴进向导
|
||||
3. 脚本自动导出租户数据、导入私有库、写入 license 记录、重启服务
|
||||
3. 脚本自动导出租户数据、导入私有库并重启服务
|
||||
|
||||
迁移为单租户操作,会清空现有 bootstrap 数据后写入迁移数据。
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
{"name": "docs-site", "required": true},
|
||||
{"name": "im-service", "required": false, "profile": "im"},
|
||||
{"name": "push-service", "required": false, "profile": "push"},
|
||||
{"name": "update-service", "required": false, "profile": "update"},
|
||||
{"name": "license-service", "required": false, "profile": "license"}
|
||||
{"name": "update-service", "required": false, "profile": "update"}
|
||||
]
|
||||
}
|
||||
|
||||
@ -56,11 +56,10 @@ FILE_DOMAIN="$(ask "File domain (e.g. https://file.customer.com)" "${FILE_DOMAIN
|
||||
ENABLE_IM="${ENABLE_IM:-false}"
|
||||
ENABLE_PUSH="${ENABLE_PUSH:-false}"
|
||||
ENABLE_UPDATE="${ENABLE_UPDATE:-false}"
|
||||
ENABLE_LICENSE="${ENABLE_LICENSE:-false}"
|
||||
|
||||
if [ "$NON_INTERACTIVE" != "true" ]; then
|
||||
printf '\nWhich optional services to enable now? (space-separated, e.g. "im update")\n'
|
||||
printf 'Available: im push update license\nCurrent: %s\n' "$COMPOSE_PROFILES"
|
||||
printf 'Available: im push update\nCurrent: %s\n' "$COMPOSE_PROFILES"
|
||||
printf 'Enter services (blank to keep current): '
|
||||
read -r OPT_SVCS
|
||||
fi
|
||||
@ -68,7 +67,6 @@ fi
|
||||
if printf '%s' "${OPT_SVCS:-}" | grep -q 'im'; then ENABLE_IM=true; IM_DOMAIN="$(ask "IM domain (e.g. https://im.customer.com)" "${IM_DOMAIN:-}" "")"; fi
|
||||
if printf '%s' "${OPT_SVCS:-}" | grep -q 'push'; then ENABLE_PUSH=true; PUSH_DOMAIN="$(ask "Push domain" "${PUSH_DOMAIN:-}" "")"; fi
|
||||
if printf '%s' "${OPT_SVCS:-}" | grep -q 'update'; then ENABLE_UPDATE=true; UPDATE_DOMAIN="$(ask "Update domain" "${UPDATE_DOMAIN:-}" "")"; fi
|
||||
if printf '%s' "${OPT_SVCS:-}" | grep -q 'license'; then ENABLE_LICENSE=true; LICENSE_DOMAIN="$(ask "License domain" "${LICENSE_DOMAIN:-}" "")"; fi
|
||||
|
||||
# MySQL mode
|
||||
printf '\nMySQL mode (external=you provide connection / managed=deploy script installs MySQL)\n'
|
||||
@ -118,12 +116,10 @@ set_env_value "$ROOT_DIR/.env" "FILE_DOMAIN" "$FILE_DOMAIN"
|
||||
[ -n "${IM_DOMAIN:-}" ] && set_env_value "$ROOT_DIR/.env" "IM_DOMAIN" "$IM_DOMAIN"
|
||||
[ -n "${PUSH_DOMAIN:-}" ] && set_env_value "$ROOT_DIR/.env" "PUSH_DOMAIN" "$PUSH_DOMAIN"
|
||||
[ -n "${UPDATE_DOMAIN:-}" ] && set_env_value "$ROOT_DIR/.env" "UPDATE_DOMAIN" "$UPDATE_DOMAIN"
|
||||
[ -n "${LICENSE_DOMAIN:-}" ] && set_env_value "$ROOT_DIR/.env" "LICENSE_DOMAIN" "$LICENSE_DOMAIN"
|
||||
|
||||
set_env_value "$ROOT_DIR/.env" "ENABLE_IM" "$ENABLE_IM"
|
||||
set_env_value "$ROOT_DIR/.env" "ENABLE_PUSH" "$ENABLE_PUSH"
|
||||
set_env_value "$ROOT_DIR/.env" "ENABLE_UPDATE" "$ENABLE_UPDATE"
|
||||
set_env_value "$ROOT_DIR/.env" "ENABLE_LICENSE" "$ENABLE_LICENSE"
|
||||
|
||||
set_env_value "$ROOT_DIR/.env" "MYSQL_MODE" "$MYSQL_MODE"
|
||||
set_env_value "$ROOT_DIR/.env" "MYSQL_HOST" "$MYSQL_HOST"
|
||||
@ -152,11 +148,9 @@ set_env_value "$XUQM_ENV" "CONSOLE_DOMAIN" "$CONSOLE_DOMAIN"
|
||||
[ -n "${IM_DOMAIN:-}" ] && set_env_value "$XUQM_ENV" "IM_DOMAIN" "$IM_DOMAIN"
|
||||
[ -n "${PUSH_DOMAIN:-}" ] && set_env_value "$XUQM_ENV" "PUSH_DOMAIN" "$PUSH_DOMAIN"
|
||||
[ -n "${UPDATE_DOMAIN:-}" ] && set_env_value "$XUQM_ENV" "UPDATE_DOMAIN" "$UPDATE_DOMAIN"
|
||||
[ -n "${LICENSE_DOMAIN:-}" ] && set_env_value "$XUQM_ENV" "LICENSE_DOMAIN" "$LICENSE_DOMAIN"
|
||||
set_env_value "$XUQM_ENV" "ENABLE_IM" "$ENABLE_IM"
|
||||
set_env_value "$XUQM_ENV" "ENABLE_PUSH" "$ENABLE_PUSH"
|
||||
set_env_value "$XUQM_ENV" "ENABLE_UPDATE" "$ENABLE_UPDATE"
|
||||
set_env_value "$XUQM_ENV" "ENABLE_LICENSE" "$ENABLE_LICENSE"
|
||||
|
||||
# Write secrets.env
|
||||
set_env_value "$ROOT_DIR/config/secrets.env" "MYSQL_PASSWORD" "$MYSQL_PASSWORD"
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
# 2. 写入配置(.env / secrets.env / xuqm.env / bootstrap.env / nginx)
|
||||
# 3. 登录 ACR 镜像仓库
|
||||
# 4. 启动基础设施容器(MySQL、Redis)并等待就绪
|
||||
# 5. 拉取镜像并启动所有业务容器(base + im + push + update + license)
|
||||
# 5. 拉取镜像并启动所有业务容器(base + im + push + update)
|
||||
# 6. Schema 扩展(is_default / deletable 列 + 删除保护触发器)+ 系统应用初始化
|
||||
# 7. 租户初始化(新建:填写信息并验证;迁移:凭迁移密钥调用 API 导入)
|
||||
# 8. 运行一键验证脚本确认所有服务正常
|
||||
@ -91,7 +91,7 @@ printf '\033[1;35m XuqmGroup 私有化一键部署脚本(全量部署)\033[
|
||||
printf '\033[1;35m══════════════════════════════════════════════════\033[0m\n'
|
||||
printf ' 部署目录: %s\n' "$ROOT_DIR"
|
||||
printf ' 镜像仓库: %s\n' "$REGISTRY"
|
||||
printf ' 服务集: base + im + push + update + license\n\n'
|
||||
printf ' 服务集: base + im + push + update\n\n'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 0b. 租户初始化方式选择(交互式,在 Step 1 预检前执行)
|
||||
@ -298,10 +298,10 @@ for port in "$_NGINX_PORT"; do
|
||||
fi
|
||||
done
|
||||
|
||||
# 自动检测内部服务端口冲突(WSL2/多套部署场景下 11224-11231 可能被宿主机占用)
|
||||
# 自动检测内部服务端口冲突(WSL2/多套部署场景下 11224-11230 可能被宿主机占用)
|
||||
_SVC_PORT_OFFSET=0
|
||||
if ss -tlnp 2>/dev/null | grep -qE ':(11224|11225|11226|11228|11229|11230|11231) '; then
|
||||
warn "检测到内部服务端口(11224-11231)已被占用,自动使用偏移 +10000(21224-21231)"
|
||||
if ss -tlnp 2>/dev/null | grep -qE ':(11224|11225|11226|11228|11229|11230) '; then
|
||||
warn "检测到内部服务端口(11224-11230)已被占用,自动使用偏移 +10000(21224-21230)"
|
||||
_SVC_PORT_OFFSET=10000
|
||||
fi
|
||||
SVC_PORT_TENANT=$((11224 + _SVC_PORT_OFFSET))
|
||||
@ -310,9 +310,8 @@ SVC_PORT_WEB=$((11226 + _SVC_PORT_OFFSET))
|
||||
SVC_PORT_IM=$((11228 + _SVC_PORT_OFFSET))
|
||||
SVC_PORT_PUSH=$((11229 + _SVC_PORT_OFFSET))
|
||||
SVC_PORT_UPDATE=$((11230 + _SVC_PORT_OFFSET))
|
||||
SVC_PORT_LICENSE=$((11231 + _SVC_PORT_OFFSET))
|
||||
[ "$_SVC_PORT_OFFSET" -eq 0 ] && ok "内部服务端口段 11224-11231 空闲" || \
|
||||
ok "内部服务端口段自动调整为 21224-21231"
|
||||
[ "$_SVC_PORT_OFFSET" -eq 0 ] && ok "内部服务端口段 11224-11230 空闲" || \
|
||||
ok "内部服务端口段自动调整为 21224-21230"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 2 — 写入配置
|
||||
@ -335,7 +334,7 @@ REGISTRY_PASSWORD=${REGISTRY_PASSWORD}
|
||||
IMAGE_TAG=${IMAGE_TAG}
|
||||
|
||||
# 启用全量服务(含内置路由 nginx)
|
||||
COMPOSE_PROFILES=base,infra-mysql,infra-redis,im,push,update,license
|
||||
COMPOSE_PROFILES=base,infra-mysql,infra-redis,im,push,update
|
||||
|
||||
# nginx 入口绑定(80=直接监听宿主机80;127.0.0.1:11223=本地监听需宿主机nginx转发)
|
||||
NGINX_BIND=${NGINX_BIND}
|
||||
@ -359,7 +358,6 @@ DOCS_DOMAIN=${CONSOLE_BASE}/docs
|
||||
FILE_DOMAIN=${CONSOLE_BASE}
|
||||
IM_DOMAIN=${CONSOLE_BASE}
|
||||
UPDATE_DOMAIN=${CONSOLE_BASE}
|
||||
LICENSE_DOMAIN=${CONSOLE_BASE}
|
||||
PUSH_DOMAIN=${CONSOLE_BASE}
|
||||
|
||||
# 功能开关(全量启用)
|
||||
@ -367,19 +365,17 @@ ENABLE_FILE=true
|
||||
ENABLE_IM=true
|
||||
ENABLE_PUSH=true
|
||||
ENABLE_UPDATE=true
|
||||
ENABLE_LICENSE=true
|
||||
|
||||
TENANT_BOOTSTRAP_EMAIL=${DEPLOY_TENANT_EMAIL}
|
||||
TENANT_BOOTSTRAP_APP_KEY=ak_private_default
|
||||
|
||||
# 内部服务宿主机端口绑定(自动偏移后的值,默认 11224-11231)
|
||||
# 内部服务宿主机端口绑定(自动偏移后的值,默认 11224-11230)
|
||||
SVC_PORT_TENANT=${SVC_PORT_TENANT}
|
||||
SVC_PORT_FILE=${SVC_PORT_FILE}
|
||||
SVC_PORT_WEB=${SVC_PORT_WEB}
|
||||
SVC_PORT_IM=${SVC_PORT_IM}
|
||||
SVC_PORT_PUSH=${SVC_PORT_PUSH}
|
||||
SVC_PORT_UPDATE=${SVC_PORT_UPDATE}
|
||||
SVC_PORT_LICENSE=${SVC_PORT_LICENSE}
|
||||
EOF
|
||||
ok ".env 已写入"
|
||||
|
||||
@ -413,7 +409,6 @@ ENABLE_FILE=true
|
||||
ENABLE_IM=true
|
||||
ENABLE_PUSH=true
|
||||
ENABLE_UPDATE=true
|
||||
ENABLE_LICENSE=true
|
||||
|
||||
# 数据库(容器内使用 Docker 服务名)
|
||||
MYSQL_HOST=mysql
|
||||
@ -432,7 +427,6 @@ DOCS_DOMAIN=${CONSOLE_BASE}/docs
|
||||
FILE_DOMAIN=${CONSOLE_BASE}
|
||||
IM_DOMAIN=${CONSOLE_BASE}
|
||||
UPDATE_DOMAIN=${CONSOLE_BASE}
|
||||
LICENSE_DOMAIN=${CONSOLE_BASE}
|
||||
PUSH_DOMAIN=${CONSOLE_BASE}
|
||||
|
||||
# SDK 对外服务地址(客户端 SDK 使用)
|
||||
@ -442,9 +436,6 @@ SDK_IM_WS_URL=${_WS_SCHEME}://${DEPLOY_HOST}/ws/im
|
||||
# BugCollect 上报地址:SDK 会在此基础上拼接 /bugcollect/v1/issues/batch
|
||||
SDK_BUGCOLLECT_API_URL=${CONSOLE_BASE}/api
|
||||
|
||||
# License 文件内嵌的 baseUrl(SDK 读取 license.xuqm 时用此地址连接私有 license 服务)
|
||||
LICENSE_PUBLIC_BASE_URL=${CONSOLE_BASE}
|
||||
|
||||
# 系统 IM 通信应用 key(私有化服务间消息通知使用)
|
||||
SYSTEM_APP_KEY=ak_409e217e4aa14254ad73ad3c
|
||||
EOF
|
||||
@ -517,8 +508,7 @@ cat > "$ROOT_DIR/config/sdk/xuqm-private-sdk.json" <<EOF
|
||||
"file": true,
|
||||
"im": true,
|
||||
"push": true,
|
||||
"update": true,
|
||||
"license": true
|
||||
"update": true
|
||||
},
|
||||
"connectTimeoutMs": 10000,
|
||||
"readTimeoutMs": 30000,
|
||||
@ -536,7 +526,7 @@ cat > "$ROOT_DIR/config/docs/docs-runtime.json" <<EOF
|
||||
"im": "${CONSOLE_BASE}",
|
||||
"update": "${CONSOLE_BASE}"
|
||||
},
|
||||
"features": { "file": true, "im": true, "push": true, "update": true, "license": true }
|
||||
"features": { "file": true, "im": true, "push": true, "update": true }
|
||||
}
|
||||
EOF
|
||||
|
||||
@ -633,7 +623,7 @@ done
|
||||
# ---------------------------------------------------------------------------
|
||||
# Step 5 — 启动所有业务容器(全服务)
|
||||
# ---------------------------------------------------------------------------
|
||||
step "拉取镜像并启动所有业务容器(base + im + push + update + license)"
|
||||
step "拉取镜像并启动所有业务容器(base + im + push + update)"
|
||||
|
||||
docker compose \
|
||||
--env-file "$ROOT_DIR/.env" \
|
||||
@ -641,7 +631,7 @@ docker compose \
|
||||
-f "$ROOT_DIR/docker-compose.infra.yml" \
|
||||
--profile base \
|
||||
--profile infra-mysql --profile infra-redis \
|
||||
--profile im --profile push --profile update --profile license \
|
||||
--profile im --profile push --profile update \
|
||||
up -d
|
||||
|
||||
# 等待 tenant-service 健康(直接打 9001 端口,不经过 nginx)
|
||||
|
||||
@ -5,7 +5,7 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
. "$ROOT_DIR/scripts/lib.sh"
|
||||
|
||||
SERVICE="${1:-}"
|
||||
[ -n "$SERVICE" ] || fail_json "XUQM_PRIVATE_1002" "service name is required (im|push|update|license)" "disable-service"
|
||||
[ -n "$SERVICE" ] || fail_json "XUQM_PRIVATE_1002" "service name is required (im|push|update)" "disable-service"
|
||||
|
||||
if [ ! -f "$ROOT_DIR/.env" ]; then
|
||||
cp "$ROOT_DIR/.env.example" "$ROOT_DIR/.env"
|
||||
@ -16,8 +16,8 @@ audit "disable-service" "STARTED" "$SERVICE"
|
||||
progress "disable-service" "STARTED" "$SERVICE"
|
||||
|
||||
case "$SERVICE" in
|
||||
im|push|update|license) ;;
|
||||
*) fail_json "XUQM_PRIVATE_1002" "unknown service: $SERVICE (valid: im push update license)" "disable-service" ;;
|
||||
im|push|update) ;;
|
||||
*) fail_json "XUQM_PRIVATE_1002" "unknown service: $SERVICE (valid: im push update)" "disable-service" ;;
|
||||
esac
|
||||
|
||||
# Stop the container first (data is preserved)
|
||||
|
||||
@ -46,7 +46,7 @@ grep -v -E '(PASSWORD|SECRET|TOKEN|KEY|SMTP|AUTH)' "$ROOT_DIR/config/xuqm.env" 2
|
||||
tail -200 "$ROOT_DIR/logs/audit.log" 2>/dev/null > "$DIAG_DIR/audit-recent.log" || true
|
||||
|
||||
# Recent container logs (last 100 lines per service, sanitized)
|
||||
for svc in tenant-service file-service nginx im-service push-service update-service license-service; do
|
||||
for svc in tenant-service file-service nginx im-service push-service update-service; do
|
||||
CTR="$(compose ps -q "$svc" 2>/dev/null | head -1 || true)"
|
||||
if [ -n "$CTR" ]; then
|
||||
docker logs --tail=100 "$CTR" 2>&1 | \
|
||||
|
||||
@ -5,7 +5,7 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
. "$ROOT_DIR/scripts/lib.sh"
|
||||
|
||||
SERVICE="${1:-}"
|
||||
[ -n "$SERVICE" ] || fail_json "XUQM_PRIVATE_1002" "service name is required (im|push|update|license)" "enable-service"
|
||||
[ -n "$SERVICE" ] || fail_json "XUQM_PRIVATE_1002" "service name is required (im|push|update)" "enable-service"
|
||||
|
||||
if [ ! -f "$ROOT_DIR/.env" ]; then
|
||||
cp "$ROOT_DIR/.env.example" "$ROOT_DIR/.env"
|
||||
@ -28,12 +28,8 @@ case "$SERVICE" in
|
||||
set_env_value "$ROOT_DIR/.env" "ENABLE_UPDATE" "true"
|
||||
[ -n "${UPDATE_DOMAIN:-}" ] || fail_json "XUQM_PRIVATE_1003" "UPDATE_DOMAIN must be set before enabling update" "enable-service"
|
||||
;;
|
||||
license)
|
||||
set_env_value "$ROOT_DIR/.env" "ENABLE_LICENSE" "true"
|
||||
[ -n "${LICENSE_DOMAIN:-}" ] || fail_json "XUQM_PRIVATE_1003" "LICENSE_DOMAIN must be set before enabling license" "enable-service"
|
||||
;;
|
||||
*)
|
||||
fail_json "XUQM_PRIVATE_1002" "unknown service: $SERVICE (valid: im push update license)" "enable-service"
|
||||
fail_json "XUQM_PRIVATE_1002" "unknown service: $SERVICE (valid: im push update)" "enable-service"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@ -53,7 +53,6 @@ profile_contains() { case ",${PROFILES}," in *","$1","*) return 0;; esac; return
|
||||
profile_contains "im" && pull_and_save "im-service"
|
||||
profile_contains "push" && pull_and_save "push-service"
|
||||
profile_contains "update" && pull_and_save "update-service"
|
||||
profile_contains "license" && pull_and_save "license-service"
|
||||
|
||||
# Infrastructure images (always include for managed mode)
|
||||
docker pull nginx:1.27-alpine 2>/dev/null && docker save nginx:1.27-alpine -o "$IMAGES_DIR/nginx.tar" || true
|
||||
|
||||
@ -40,7 +40,7 @@ for svc in tenant-service file-service tenant-web nginx; do
|
||||
done
|
||||
|
||||
# Optional service containers (docs-site included here — warn only if present but unhealthy)
|
||||
for svc in docs-site im-service push-service update-service license-service; do
|
||||
for svc in docs-site im-service push-service update-service; do
|
||||
STATE="$(compose ps -q "$svc" 2>/dev/null | head -1 || true)"
|
||||
if [ -n "$STATE" ]; then
|
||||
STATUS="$(docker inspect --format='{{.State.Status}}' "$STATE" 2>/dev/null || echo 'unknown')"
|
||||
@ -150,9 +150,6 @@ fi
|
||||
[ "${ENABLE_UPDATE:-false}" = "true" ] && [ -n "${UPDATE_DOMAIN:-}" ] && \
|
||||
http_check "http.update-service" "${UPDATE_DOMAIN}/actuator/health"
|
||||
|
||||
[ "${ENABLE_LICENSE:-false}" = "true" ] && [ -n "${LICENSE_DOMAIN:-}" ] && \
|
||||
http_check "http.license-service" "${LICENSE_DOMAIN}/actuator/health"
|
||||
|
||||
# Disk space
|
||||
DISK_USE="$(df -h "$ROOT_DIR" | awk 'NR==2{print $5}' | tr -d '%')"
|
||||
if [ -n "$DISK_USE" ]; then
|
||||
|
||||
@ -20,7 +20,7 @@ usage() {
|
||||
Usage: ./scripts/install.sh [options]
|
||||
|
||||
Options:
|
||||
--profile <profiles> Docker Compose profiles, for example: base,im,push,update,license
|
||||
--profile <profiles> Docker Compose profiles, for example: base,im,push,update
|
||||
--mysql-mode <mode> external or managed
|
||||
--redis-mode <mode> external or managed
|
||||
--offline-bundle <path> Load images from an offline bundle before deployment
|
||||
|
||||
@ -38,15 +38,13 @@ cat > "$ROOT_DIR/config/docs/docs-runtime.json" <<EOF
|
||||
"file": "${FILE_DOMAIN:-}",
|
||||
"im": "${IM_DOMAIN:-}",
|
||||
"update": "${UPDATE_DOMAIN:-}",
|
||||
"license": "${LICENSE_DOMAIN:-}",
|
||||
"push": "${PUSH_DOMAIN:-}"
|
||||
},
|
||||
"features": {
|
||||
"file": ${ENABLE_FILE:-true},
|
||||
"im": ${ENABLE_IM:-false},
|
||||
"push": ${ENABLE_PUSH:-false},
|
||||
"update": ${ENABLE_UPDATE:-false},
|
||||
"license": ${ENABLE_LICENSE:-false}
|
||||
"update": ${ENABLE_UPDATE:-false}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
@ -63,14 +61,12 @@ cat > "$ROOT_DIR/config/sdk/xuqm-private-sdk.json" <<EOF
|
||||
"imWsUrl": "$(ws_url "${IM_DOMAIN:-}")",
|
||||
"pushBaseUrl": "${PUSH_DOMAIN:-}",
|
||||
"updateBaseUrl": "${UPDATE_DOMAIN:-}",
|
||||
"licenseBaseUrl": "${LICENSE_DOMAIN:-}",
|
||||
"docsBaseUrl": "${DOCS_DOMAIN:-}",
|
||||
"features": {
|
||||
"file": ${ENABLE_FILE:-true},
|
||||
"im": ${ENABLE_IM:-false},
|
||||
"push": ${ENABLE_PUSH:-false},
|
||||
"update": ${ENABLE_UPDATE:-false},
|
||||
"license": ${ENABLE_LICENSE:-false}
|
||||
"update": ${ENABLE_UPDATE:-false}
|
||||
},
|
||||
"connectTimeoutMs": 10000,
|
||||
"readTimeoutMs": 30000,
|
||||
@ -88,8 +84,7 @@ cat > "$ROOT_DIR/.deploy-state/current.json" <<EOF
|
||||
"file": ${ENABLE_FILE:-true},
|
||||
"im": ${ENABLE_IM:-false},
|
||||
"push": ${ENABLE_PUSH:-false},
|
||||
"update": ${ENABLE_UPDATE:-false},
|
||||
"license": ${ENABLE_LICENSE:-false}
|
||||
"update": ${ENABLE_UPDATE:-false}
|
||||
},
|
||||
"lastHealthcheck": null
|
||||
}
|
||||
|
||||
@ -216,16 +216,6 @@ else
|
||||
ok "SDK_FILE_SERVICE_URL 正常: ${_CURRENT_FILE}"
|
||||
fi
|
||||
|
||||
# LICENSE_PUBLIC_BASE_URL:生成 license.xuqm 文件时写入的 baseUrl,SDK 读取后用于连接私有 license 服务
|
||||
_CURRENT_LICENSE_URL="$(grep '^LICENSE_PUBLIC_BASE_URL=' "$ROOT_DIR/config/xuqm.env" 2>/dev/null | cut -d= -f2- || true)"
|
||||
if [ -z "$_CURRENT_LICENSE_URL" ] || _url_needs_fix "$_CURRENT_LICENSE_URL"; then
|
||||
_set_env "$ROOT_DIR/config/xuqm.env" "LICENSE_PUBLIC_BASE_URL" "$_CONSOLE_DOMAIN"
|
||||
ok "LICENSE_PUBLIC_BASE_URL 已更新 → ${_CONSOLE_DOMAIN}"
|
||||
_FIXED=1
|
||||
else
|
||||
ok "LICENSE_PUBLIC_BASE_URL 正常: ${_CURRENT_LICENSE_URL}"
|
||||
fi
|
||||
|
||||
# SDK_BUGCOLLECT_API_URL:BugCollect SDK 上报地址(SDK 会在此基础上拼接 /bugcollect/v1/...)
|
||||
# 正确值:{CONSOLE_DOMAIN}/api,不含 /bugcollect 后缀
|
||||
_CORRECT_BC_URL="${_CONSOLE_DOMAIN}/api"
|
||||
@ -514,7 +504,7 @@ _COMPOSE="docker compose --env-file ${ROOT_DIR}/.env \
|
||||
|
||||
# 使用 up -d 而非 restart:restart 只重启容器进程,不会切换到新拉取的镜像;
|
||||
# up -d 会检测镜像变更并重建容器,是应用新版本的正确方式。
|
||||
for _svc in tenant-service im-service file-service update-service license-service push-service tenant-web nginx; do
|
||||
for _svc in tenant-service im-service file-service update-service push-service tenant-web nginx; do
|
||||
# 仅重启已激活的服务(跳过未运行的可选服务)
|
||||
if $_COMPOSE ps --services --filter status=running 2>/dev/null | grep -q "^${_svc}$"; then
|
||||
info "应用新镜像并重启 ${_svc} ..."
|
||||
|
||||
@ -156,7 +156,7 @@ for CTR_SUFFIX in $REQUIRED_CONTAINERS; do
|
||||
fi
|
||||
done
|
||||
|
||||
OPTIONAL_CONTAINERS="file-service im-service push-service update-service license-service bugcollect-service symbolicator mysql redis"
|
||||
OPTIONAL_CONTAINERS="file-service im-service push-service update-service bugcollect-service symbolicator mysql redis"
|
||||
for CTR_SUFFIX in $OPTIONAL_CONTAINERS; do
|
||||
CTR_NAME=$(docker ps --filter "name=$CTR_SUFFIX" --filter "status=running" --format '{{.Names}}' 2>/dev/null | head -1)
|
||||
if [ -n "$CTR_NAME" ]; then
|
||||
|
||||
@ -17,14 +17,12 @@
|
||||
- IM:
|
||||
- Push:
|
||||
- Update:
|
||||
- License:
|
||||
|
||||
## 可选服务
|
||||
|
||||
- IM:未部署 / 已部署
|
||||
- Push:未部署 / 已部署
|
||||
- Update:未部署 / 已部署
|
||||
- License:未部署 / 已部署
|
||||
|
||||
## 验收
|
||||
|
||||
|
||||
@ -20,5 +20,4 @@ DOCS_DOMAIN=https://docs.customer.com
|
||||
FILE_DOMAIN=https://file.customer.com
|
||||
IM_DOMAIN=https://im.customer.com
|
||||
UPDATE_DOMAIN=https://update.customer.com
|
||||
LICENSE_DOMAIN=https://license.customer.com
|
||||
PUSH_DOMAIN=https://push.customer.com
|
||||
|
||||
@ -20,5 +20,4 @@ DOCS_DOMAIN=https://docs.customer.com
|
||||
FILE_DOMAIN=https://file.customer.com
|
||||
IM_DOMAIN=https://im.customer.com
|
||||
UPDATE_DOMAIN=https://update.customer.com
|
||||
LICENSE_DOMAIN=https://license.customer.com
|
||||
PUSH_DOMAIN=https://push.customer.com
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户