# app 业务单镜像部署 # # gateway + home + api + mcp + timer 五个集群服务(shell 脚本管理多进程)打成单镜像。 # 服务名固定为 app,容器名由部署脚本按「应用」注入(CONTAINER_NAME,如 ym → ym-a11), # 同一台机上多个应用(voitrans / ym / lumi …)各占一个目录、一个容器,互不撞名。 # 镜像版本通过 TAG 控制;接入外部网络(默认 1panel-network),与 etcd/mysql/redis/nats 通过容器名互通。 # 不直接 docker compose 调用,统一经 dev-deploy.sh / prod-deploy.sh(它们把 env/.env 落为 .env)。 services: # 这里的 app 只是模板占位:prod-deploy.sh 下发时会把这一行改写成本应用名 # (ym → `ym-a11:`),所以服务器上的 docker-compose.yml 里 service 名 = 容器名 = <应用>-a11, # docker compose ps / 面板里一眼看得出是哪个应用。别在仓库模板里写死某个应用名。 # dev-deploy.sh 不改写(测试机单份部署),保持 app + 默认容器名 starpivot-app。 app: # 镜像名由部署脚本注入(IMAGE_NAME,来自 deploy/registry-profiles.sh 的 prod_image_name), # 这里的默认值只在手工 docker compose 时兜底——别在此写死,写死过一次就和脚本漂移了。 image: ${REGISTRY:-registry.ymaikj.com}/${IMAGE_NAME:-starpivot-app}:${TAG:-latest} # 容器名按「应用」区分:prod-deploy.sh 注入 CONTAINER_NAME=<应用>-a11(ym → ym-a11), # 并写回 .env,手工 docker compose 时也用同一个名字。默认值只给 dev / 未注入时兜底。 container_name: ${CONTAINER_NAME:-starpivot-app} restart: unless-stopped platform: ${PLATFORM:-linux/amd64} networks: - appnet # 把整个部署目录挂为 /app(WORKDIR):内含 confs/ log/ 及各服务运行期资源(密钥/词库等,如有) volumes: - .:/app # 把 .env 整体注入容器,供各 yaml 里 ${VAR} 在启动时展开(compose 默认只做文件内插值,需显式 env_file) env_file: - .env environment: TZ: Asia/Shanghai stop_grace_period: 30s # 端口(容器内部,对外经反代/NPM 暴露;如需直接发布改用下方 ports): # 7001 gateway RPCX / 7100 gateway HTTP # 7002 home RPCX / 7003 timer RPCX # 7004 mcp RPCX / 7300 mcp HTTP # 7005 api RPCX / 8080 api Console expose: - "7100" - "7300" - "8080" # 如需宿主机直接访问,取消注释(左=宿主端口,右=容器端口): # ports: # - "7100:7100" # gateway HTTP # - "8080:8080" # api Console # - "7300:7300" # mcp HTTP # 健康检查:探测 gateway HTTP 端口 healthcheck: test: ["CMD", "sh", "-c", "nc -z 127.0.0.1 7100 || exit 1"] interval: 30s timeout: 5s retries: 3 start_period: 30s # 外部共享网络:依赖的 etcd/mysql/redis/nats 在此网络(用容器名连接),目标机需预先存在 networks: appnet: name: ${DOCKER_NETWORK:-1panel-network} external: true