# IotLCM 部署仓 IotLCM 物联网卡管理平台的部署编排与数据库初始化脚本。使用 Docker Compose 在单机上拉起完整平台。 ## 一键启动 ```bash git clone <仓库地址> iotlcm cd iotlcm/deploy docker compose up -d ``` 无需复制或修改任何文件,配置里已带可用默认值。首次启动会自动完成 MySQL 建库建表(95 张)、种子数据导入、时序库建表,实测约 30 秒~1 分钟。 等待 MySQL 健康后其余服务依次启动,观察进度: ```bash docker compose logs -f mysql ``` 启动完成后在本机访问 `http://127.0.0.1:8009`(编排默认把业务端口绑定在 127.0.0.1,需要局域网/公网访问见下方「重要提示」): | 项 | 值 | | --- | --- | | 账号 | `admin` | | 口令 | `Iotlcm2026Default` | > ⚠️ **正式使用前必须修改默认口令**,见下方「上线前必改」。 ## 可选服务 ```bash docker compose --profile with-gateway up -d # 单端口入口(默认对外 5051) docker compose --profile with-mock up -d # 运营商接口挡板 docker compose --profile with-bot up -d # 飞书通知(运维自用) docker compose --profile with-nginx up -d # 多域名反向代理(对外 80) docker compose --profile with-website up -d # 官网(项目门户站) ``` 多个 profile 可组合:`--profile with-gateway --profile with-mock up -d` ### 单端口入口(with-gateway) 只暴露一个端口时用它。容器内监听 80,宿主机端口由 `GATEWAY_PORT` 控制(默认 **5051**): ```bash docker compose --profile with-gateway up -d # 或换端口 GATEWAY_PORT=8088 docker compose --profile with-gateway up -d ``` | 路径 | 去向 | | --- | --- | | `/` | 管理端(admin-ui,内部已代理 `/api/` 到 admin-svr) | | `/docs/` | 文档站 | | `/www/` | 官网(需同时启用 `with-website`) | | `/openapi/` | 对外 API | | `/route/open/` | 运营商能力代理(白名单 / 共享 Token) | 配置见 `config/gateway/nginx.conf`。小程序 / H5 端的静态资源是根路径部署的,不能挂在同一域名的子路径下,需要单独域名或端口(见 `with-nginx` 的 app 段)。 ### 官网(with-website) 项目门户站(项目介绍、功能矩阵、快速开始、教程入口),源码在仓库的 `website/` 目录,与文档站同构(VitePress)。 ```bash docker compose --profile with-website up -d --build website ``` 镜像发布到公共仓库之前用 `--build` 本地构建;发布后去掉 `--build` 即可。 **两种形态**由构建参数 `WEBSITE_SITE_BASE` 决定: | 形态 | 参数 | 访问方式 | | --- | --- | --- | | 子路径(过渡,无独立域名) | `/www/`(默认) | 网关的 `http://<主机>:5051/www/` | | 独立域名 | `/` | 域名根路径,如 `https://<官网域名>/` | ```bash # 独立域名形态 WEBSITE_SITE_BASE=/ docker compose --profile with-website up -d --build website ``` 形态切换只改构建参数与入口配置,页面内容同源,不用改代码。独立域名形态下把 DNS 指到本机, 并在 `config/nginx/iotlcm.conf` 里加一段 `server_name <官网域名>` 的 vhost 指向 `website` 容器。 `with-bot` 是把全量同步等运维事件推送到飞书群的**内部运维工具**,不是平台功能。它需要你自己的飞书自建应用凭证(`config/bot/config.yaml` 的 `appId` / `appSecret` / `chatId`),没填就不启动。 **默认不启动,也不影响平台功能**;不需要飞书通知就完全不用管它。 ## 镜像版本 所有镜像(含基础组件)都在**同一个镜像仓库** `<镜像仓库>/iotlcm/iotlcm` 下,靠 tag 区分服务与版本: ```text crpi-.../iotlcm/iotlcm:mysql-8.0 crpi-.../iotlcm/iotlcm:redis-7.2 crpi-.../iotlcm/iotlcm:iotlcm-admin-svr-v1.0.4 crpi-.../iotlcm/iotlcm:iotlcm-app-server-v1.0.2 ``` tag 格式统一为 **`<服务名>-<版本>`**。 当前业务版本: | 服务 | 版本 | | --- | --- | | 除 app 线外的全部业务服务 | `v1.0.4` | | `iotlcm-app-server` / `iotlcm-app-web` | **`v1.0.2`**(小程序线独立版本,不跟随平台 tag) | > 版本号与功能一一对应:小程序线的功能停在 v1.0.2,因此镜像 tag 也停在 v1.0.2;平台后续发 v1.0.5 时它依然不动。 升级时在 `docker-compose.yml` 中同步更新 tag 的版本部分,不要改用 `latest`。 ## 部署内容 | 类别 | 服务 | | --- | --- | | 基础组件 | MySQL、Redis、RabbitMQ、Consul、TDengine(流量历史) | | 业务服务 | admin-svr(管理端后端)、admin-ui(管理端前端)、openapi(对外 API)、app-server(小程序后端)、app-web(小程序前端)、upstream-chan(运营商对接)、upstream-proxy(通道缓存转发)、worker-svr(异步任务)、sms(短信)、docs(文档站) | | 可选 | onelink-mock(运营商接口挡板)、bot(飞书通知)、nginx(反向代理) | ## 目录结构 ``` iotlcm/deploy/ ├── docker-compose.yml # 服务编排(含全部默认值) ├── config/ # 各服务配置,已带可用默认值 │ ├── admin-svr/config.yaml │ ├── admin-ui/default.conf │ ├── app-server/config.yaml │ ├── bot/config.yaml │ ├── nginx/iotlcm.conf │ ├── openapi/config.yaml │ ├── sms/config.yaml │ ├── upstream-chan/config.yaml │ ├── upstream-proxy/config.yaml │ └── worker-svr/config.yaml ├── schema/init.sql # MySQL 初始化(单文件,首次启动自动执行) ├── tdengine-init/ # TDengine 建库建表(首次启动自动执行) └── data/ # 运行数据(首次启动自动创建,不入版本库) ``` 全新初始化生成 95 张业务表(原有 91 张 + worker 异步恢复所需 4 张);已部署旧库不会自动执行新增迁移,见 `schema/README.md`。 编排已内置 TDengine(流量历史库),由 `tdengine-init` 服务在 TDengine 健康后自动建库建表: | 库 | 分片 | 保留 | 超级表 | | --- | --- | --- | --- | | `iotlcm_daily` | 7 天 | 3 年 | `t_sim_card_usage_daily` | | `iotlcm_monthly` | 30 天 | 3 年 | `t_sim_card_usage_monthly` | 结构取自生产环境,`tdengine-init` 会校验建表结果,缺表则报错退出。业务代码只读写不建表,因此这一步不能跳过。 TDengine 版本为 `3.3.6.13`(公开镜像可得),生产用的是 `3.4.0.9`。两者在流量历史的读写上一致;如需与生产完全对齐,可自行构建镜像并替换 `docker-compose.yml` 里的 tag。 ## 上线前必改 默认口令仅用于快速试用。**正式部署前必须修改以下内容**,具体位置见[部署手册](../docs/docs/deploy/index.md): | 项 | 位置 | | --- | --- | | 数据库口令(root 与应用账号) | `docker-compose.yml` + `config/*/config.yaml` + `schema/init.sql` | | Redis 口令 | `docker-compose.yml` + `config/*/config.yaml` | | RabbitMQ 口令 | `docker-compose.yml` + `config/*/config.yaml` | | admin 初始口令 | `docker-compose.yml` + `schema/init.sql` | | JWT 签名密钥 | `config/admin-svr`、`config/openapi`、`config/app-server` 三处 | | 对外域名 | `config/nginx/iotlcm.conf` | ::: warning 改口令必须多处同步 因为配置文件里是字面值(未使用环境变量),改口令时**编排、配置、初始化脚本三处必须一致**,漏改会导致服务连不上数据库。 ::: ## 重要提示 - **`JWT_SIGNING_KEY` 必须在 `admin-svr`、`openapi`、`app-server` 三者间完全一致**,否则令牌跨服务不通 - **镜像标签不要用 `latest`**,生产环境请固定到具体版本 - **改 `schema/` 下的脚本不会自动生效**,需要清空 `data/mysql` 重新初始化(会丢失全部数据) - 业务端口默认只绑定 `127.0.0.1`(admin-ui/admin-svr/openapi/app-web/docs/sms),要从其他机器访问,二选一: - 用 `--profile with-nginx` 起自带反向代理(对外 80,按域名/路径分流,配置见 `config/nginx/iotlcm.conf`) - 或把 `docker-compose.yml` 里对应服务的 `127.0.0.1:xxxx` 改成 `0.0.0.0:xxxx`(需自备防火墙策略) ## 许可 [Apache License 2.0](LICENSE)