# app 业务服务部署 把 **gateway + home + api + mcp + timer** 五个集群(RPCX/ETCD)服务打成**一个镜像** `starpivot-app`, 推送到私有仓库 `docker-registry.ideapsound.com`,再到目标机拉取重启。容器内用 shell(entrypoint) 管理 5 个进程, 任一进程退出即整体重启。 > 约定:仓库**只提交模板**(`*.example`)。部署脚本会把**模板 + `docker-compose.yml`** 同步到服务器, > 但**绝不上传/覆盖**你在服务器上填好的真实 `.env` / `confs/*.yaml`(首次需登录服务器照模板复制并填值)。 ## 文件 | 文件 | 说明 | |---|---| | `../../apps/services/Dockerfile.voitrans` | 镜像构建(编译 5 个二进制 + entrypoint),构建上下文 = `apps/services/` | | `../../apps/services/entrypoint.voitrans.sh` | 容器入口,拉起并守护 5 个服务进程 | | `docker-compose.yml` | 运行镜像,把部署目录挂为容器 `/app`,`.env` 注入容器(此文件由你放到服务器) | | `confs/*.yaml.example` | 5 个服务配置的**模板**;真实 `confs/*.yaml` 被 gitignore,基础设施端点/密钥用 `${VAR}` 由 `.env` 注入 | | `env/env.example` | 运行时环境**模板**(只一份,不分区域);真实 `.env` 被 gitignore | | `dev-deploy.sh` | **开发**:构建 dev 镜像 → 推送 → 远端拉取重启(固定 tag `dev-latest`) | | `prod-build.sh` | **生产①**:构建带版本号镜像并推送(`:版本` + `:latest`),不部署 | | `prod-deploy.sh` | **生产②**:选区域 + 版本 tag 部署,支持回滚 | ## 用法 ### 一、在服务器上准备好真实配置(一次性) 脚本每次会同步 `docker-compose.yml` + `*.example` 模板到目标机。**首次**需登录服务器把模板复制成真实文件并填值 (`cp env.example .env`、`for f in confs/*.yaml.example; do cp "$f" "${f%.example}"; done`,dev-deploy 缺真实文件时也会提示): ``` <部署目录>/ ├── docker-compose.yml # 从本目录拷贝 ├── .env # 照 env/env.example 填真实值(DSN/Redis/ETCD/NATS/CLUSTER_TAG/ │ # GATEWAY_TOKEN_KEY/GATEWAY_ENCRYPT_KEY/ANALYZE_APP_NAME 等) ├── confs/*.yaml # 照 confs/*.yaml.example 填(${VAR} 端点保持,密钥按需填) └── confs/ 附属文件 # 见下「需要提供的东西」 ``` dev 部署目录默认 `/home/work/voitrans-a11`,prod 默认 `/opt/yunyan/voitrans`(见脚本)。 ### 二、部署 开发: ```bash cd deploy/voitrans ./dev-deploy.sh lingpu # 发布到灵谱测试环境(构建 dev-latest → 推送 → 远端拉取重启) ./dev-deploy.sh yunyan # 发布到云雁测试环境 ./dev-deploy.sh # 不带参数 → 交互选择测试环境 ``` 生产(构建与部署分离): ```bash ./prod-build.sh 0.1.1 # 构建并推送 voitrans-a11:0.1.1 (+latest) ./prod-deploy.sh shanghai 0.1.1 # 部署 0.1.1 到上海 ./prod-deploy.sh japan 0.1.1 # 部署到日本 ./prod-deploy.sh singapore 0.1.1 # 部署到新加坡 ./prod-deploy.sh shanghai rollback # 上海回滚到上一版本(与当前版本来回切换) ``` > 改了服务器上的 `.env` 后,必须经 `up`(脚本里的 `docker compose up -d`)**重建容器**才生效,`restart` 不会重读环境变量。 > prod 的版本/回滚记录存服务器上的 `.deploy_tag` / `.deploy_tag.prev`,不动你维护的 `.env`。 ## 需要填写 / 提供的东西 - **部署目标与凭据**:写死在各脚本顶部。 - `dev-deploy.sh`:`env_profile()` 里各测试环境(`lingpu` / `yunyan`)的 `REGISTRY/DEV_HOST/DEV_KEY/DEV_DIR`。 - `prod-deploy.sh`:`region_profile()` 里各区域的 `DEPLOY_HOST`。 - 仓库账号 `admin` / 密码已写死;`DEPLOY_KEY` 默认 `~/.ssh/id_rsa`。 - ⚠️ 本目录脚本纳入 git,**公开仓库前务必清空** `*_HOST` 与 `REGISTRY_PASS`。 - **基础设施端点**:填服务器 `.env` 的 `ETCD_SERVERS / DB_ADMIN_DSN / DB_DEVICE_DSN / REDIS_* / NATS_URL`, 以及统计上报 `ANALYZE_APP_NAME`(须与 console 注册表应用名一致)/ `ANALYZE_REGION`、集群隔离 `CLUSTER_TAG`、 网关 `GATEWAY_TOKEN_KEY` 与 v2 加密 `GATEWAY_ENCRYPT_KEY`(须与 Flutter 端 AES key 一致)。 - **confs 引用的附属文件**(按需放入服务器部署目录,会随工作目录挂入容器 `/app`): - `home.yaml`:`./smart-bluetooth-447104-2b269474bd72.json`(Google)、firebase/google 登录 json、 `./apiclient_key.pem`(微信支付)、`confs/ip2region_v4.xdb` 与 `v6.xdb`(IP 库)、 `wordfilter/*.txt`(敏感词,不需要则删掉 `home.yaml` 的 `wordfilter` 段)。 - 缺这些文件会导致对应服务启动失败(容器反复重启),用不到的集成请删掉对应配置段。 ## 端口(容器内,对外经反代/NPM 暴露) `gateway` 7001 RPCX / 7100 HTTP · `home` 7002 · `timer` 7003 · `mcp` 7004 / 7300 HTTP · `api` 7005 / 8080 Console。 依赖的 `etcd / mysql / redis / nats` 须在 `DOCKER_NETWORK`(默认 `1panel-network`)网络内,用容器名连接。