跳到主要内容

部署排查

部署问题基本只有两类:CLI 命令执行时报错,或者 Runtime 一直没变成 ready。这一页先教你收集诊断信息,再按症状对照处理。

下面所有命令都在部署所在的那台主机上、部署目录里执行(服务器是 /opt/soln-tenant-runtime,本机是 $HOME/soln-tenant-runtime)。

第 1 步:收集诊断信息​

cd /opt/soln-tenant-runtime
soln status --dir .
  • 输出 Release:、Runtime: ready|not ready、Tunnel: …,如果有没走完的生命周期操作还会打印 Operation:
  • 加 --json 可以看到完整记录:各容器状态、隧道状态、更新检查结果,以及 deploymentId
  • DEPLOYMENT_NOT_INSTALLED —— 这个目录不是部署目录,检查路径
soln doctor --dir .
  • 每项检查一行:docker、compose、buildx、cosign、files、environment、tunnel、storage-security、disk、compose-config
  • 每条失败都会指明缺的是哪个变量、文件或工具;先把带 ✗ 的行修掉再看别的
docker compose ps
  • 列出全部服务:tenant-runtime-service、tenant-runtime-web、tenant-workflow-worker、reverse-proxy,单机模式下还有 postgres、temporal、minio、document-parser
  • 当前模式涉及的服务,State 应该是 running(有健康检查的显示 healthy)
docker compose logs --tail=200 tenant-runtime-service tenant-workflow-worker
  • Runtime Service 的日志里是心跳和 Lease 相关消息;Workflow Worker 的日志里是 Temporal 连接问题
  • 想看 TLS 或上游错误就加上 reverse-proxy,想看迁移输出就换成 tenant-database-migrator
docker compose exec tenant-runtime-service cat /tmp/soln-agent-health.json
  • Runtime 会把自己的状态写在这里:businessRuntimeReadyAt、lunaTemporalReadyAt、lastHeartbeatAt、lastHeartbeatError、runtimeLeaseExpiresAt、stoppingAt,以及最近一次发布通知
  • 没有 lastHeartbeatAt、或者 lastHeartbeatError 非空,比翻日志更快定位「离线」的原因

第 2 步:按症状对照​

现象先看哪一节
soln install 或 soln upgrade 报错退出安装与升级报错
soln status 显示 Runtime: not readyRuntime 未就绪
控制面显示离线,但 /health/ready 返回 200控制面显示 Runtime 离线
生命周期操作卡住(status 里有 Operation:)升级或回滚卡住
浏览器打不开 Runtime Origin浏览器打不开地址
隧道状态是 not ready隧道未就绪
之前一直正常,主机重启后就不行主机层面的问题

安装与升级报错​

错误码含义怎么办
DEPLOYMENT_ALREADY_INSTALLED这个目录里已经有一次部署直接用它,或者换一个空目录;不要在已有部署上重装
DEPLOYMENT_ENV_INCOMPLETE.env 里还缺必填值或还是占位符报错里会列出变量名,见环境变量
DEPLOYMENT_ENV_NOT_FOUND.env 不存在在部署目录里执行命令,它会从 .env.example 生成 .env
LOCAL_ENCRYPTED_STORAGE_CONFIRMATION_REQUIRED本机安装没有带 --confirm-encrypted-storage先开启 FileVault / BitLocker / LUKS,再加上这个参数
LOCAL_RUNTIME_ORIGIN_INVALID本机 Origin 不是 https://*.localhost:8443重新执行 soln prepare --deployment-target local,用生成的地址
DEPLOYMENT_BINDING_MISMATCH租户、Runtime 或 Agent 与已记录状态不一致重新从控制面复制命令,不要复用旧的
DEPLOYMENT_DISK_INSUFFICIENT可用空间不足 10 GiB先清理磁盘;升级期间会同时存在两个发布和一份数据库备份
DEPLOYMENT_COMMAND_NOT_FOUND缺 Docker、Compose、Buildx 或 Cosign按服务器环境准备安装
DEPLOYMENT_COMMAND_TIMEOUT某条 Compose 命令超时用 docker compose ps 看有没有卡住的容器,再重跑命令
REGISTRY_ACCESS_TOKEN_FAILED控制面没有签发 Registry 凭据检查到控制面的出站 HTTPS,并确认 Agent 密钥是当前这一个
RELEASE_MANIFEST_SIGNATURE_INVALID发布签名校验失败不要绕过;这个发布没有授权给本租户,联系管理员
MISSING_ARGUMENT粘贴的命令缺了必填参数整段命令重新复制
DEPLOYMENT_MODE_INVALID / DEPLOYMENT_TARGET_INVALID.env 里的值不是 singleMachine/externalServices,或不是 local/server用匹配的参数重新执行 soln prepare
DEPLOYMENT_SETUP_FILE_MISMATCH.env 里的模式和安装时传入的模式不一致两边改成同一个值

安装中途失败时数据库还没有迁移:把报错的原因修掉,再执行同一条命令即可。但安装成功后不要再执行 soln install,后续统一用 soln upgrade。

Runtime 未就绪​

/health/ready 只有在 Runtime 完成初始化、持有有效 Lease、且不处于维护模式时才返回 200。按顺序检查这三个条件:

curl -fsS https://runtime.customer.example.com/health/live
curl -fsS https://runtime.customer.example.com/health/ready
  • 进程活着时 /health/live 返回 {"status":"ok"};connection refused 说明容器或反向代理没起来
  • /health/ready 返回的错误体里会写明条件:TENANT_RUNTIME_INITIALIZING、TENANT_RUNTIME_MAINTENANCE_MODE,或某个 Lease 错误

接着看 Runtime 自己的状态文件:

docker compose exec tenant-runtime-service cat /tmp/soln-agent-health.json
字段含义
businessRuntimeReadyAt业务运行时完成初始化;缺失说明还在启动,或者访问数据库失败
lunaTemporalReadyAt智能体任务队列已连上 Temporal;缺失说明 TEMPORAL_ADDRESS 或 namespace 不对
lastHeartbeatAt最近一次成功向控制面发心跳的时间
lastHeartbeatError最近一次心跳失败的原因,Lease 或 Origin 问题会出现在这里
runtimeLeaseExpiresAt当前 Lease 的到期时间;已过期会让 /health/ready 一直失败
stoppingAt进程正在退出时会有值

对应的处理:

  • TENANT_RUNTIME_INITIALIZING 持续几分钟以上:检查数据库连通性(DATABASE_URL),并看 docker compose logs --tail=200 tenant-runtime-service
  • 缺 lunaTemporalReadyAt:核对 TEMPORAL_ADDRESS、namespace;用了 TLS 还要确认 CA 和客户端证书挂在 /run/secrets 且权限 0600
  • runtimeLeaseExpiresAt 已过期:继续看下一节
  • 修完之后等 20~30 秒再刷新控制面,控制面状态是跟着心跳走的

控制面显示 Runtime 离线​

心跳被拒时会有明确的错误类型,常见原因如下:

原因怎么确认怎么办
RUNTIME_ORIGIN 与注册值不一致(AGENT_RUNTIME_ORIGIN_MISMATCH)对比 .env 里的 RUNTIME_ORIGIN 和sl deployment status --json 显示的地址改成完全一致,再执行一次 soln install/soln upgrade 让新值进入容器
Agent 密钥被轮换或已过期lastHeartbeatError 里会提到 agent 或密钥有计划地通过 sl deployment register --force 替换登记,重新生成配置并安排 Runtime 重连;不要因普通检查失败轮换密钥
发布没有授权给本租户(AGENT_RUNTIME_RELEASE_NOT_AUTHORIZED)Runtime 日志里会写明发布版本联系管理员发布或授权该发布
发布低于强制最低版本(AGENT_RUNTIME_RELEASE_UNSUPPORTED)soln status 会打印 Update required升级到控制面要求的版本
Runtime 未注册(AGENT_RUNTIME_RUNTIME_NOT_REGISTERED)控制面不认识这个注册 ID先执行 sl deployment status --json 核对,再通过 sl deployment register 登记并准备安装
主机时间漂移date -u 与现实时间差了几分钟打开时间同步(timedatectl status)后重启部署
主机访问不到 CP_URL在主机上执行 curl -I "$CP_URL"放通到控制面和镜像 Registry 的出站 HTTPS

不要通过改 .soln/deployment.json、关检查、或把状态文件拷到别的主机来绕过 Lease 失败。修好原因后执行 soln install、soln upgrade 或 soln rollback 之一。

升级或回滚卡住​

soln status --dir .
  • 出现 Operation: upgrade -> <版本> 或 Operation: rollback -> <版本>,说明上一次生命周期命令没走完;在清除之前 Runtime 一直处于恢复状态
  • 未完成的操作也记录在 .soln/deployment.json 的 operation.phase、startedAt 里,迁移前的备份在 .soln/backups
soln rollback --dir .
  • 恢复上一个发布和它的数据库备份,然后清除未完成状态。这是官方支持的恢复方式;soln upgrade 报 DEPLOYMENT_RECOVERY_REQUIRED 也是同一个意思
  • DEPLOYMENT_ROLLBACK_UNAVAILABLE —— 没有可用的上一版本或备份。先确认是不是上一次回滚已经用掉了,再决定是否重装(重装会丢数据)

如果是 Migrator 本身失败,它的输出会保留:

docker compose run --rm tenant-database-migrator
  • 成功:打印已应用的迁移并返回 0
  • 这里失败属于数据库问题,不是发布问题:看输出里失败的那条迁移名,以及数据库账号权限

浏览器打不开地址​

现象怎么办
完全打不开,连接被拒绝用 docker compose ps 看 reverse-proxy 和 tenant-runtime-service;用 docker compose up -d 启动它们
反向代理返回 502 Bad Gateway上游 Runtime 没就绪,按 Runtime 未就绪排查
服务器部署报 DNS_PROBE_FINISHED_NXDOMAIN为 Runtime Origin 添加 DNS 记录,等解析生效
SSL certificate problem 或证书告警用覆盖确切 Runtime Origin 主机名的证书;Linux 本机还要导入本机根证书,见 Linux
页面能开,但请求返回 401 或 403在 Runtime Origin 上重新登录;会话 Cookie 只属于那个确切主机名
外网连不上端口在主机防火墙或安全组放通;反向代理只监听回环地址,前面需要你自己的 TLS 终结器或隧道

本机部署的地址是 https://soln-<租户子域名>.localhost:8443,只有这台机器能访问,且 8443 必须空闲;被别的进程占用时反向代理会报 port is already allocated。

隧道未就绪​

soln status --dir .
docker compose logs --tail=100 cloudflared
  • Tunnel: not ready 且报 TUNNEL_CREDENTIALS_INVALID:凭据 JSON 缺失或格式不对;把 Named Tunnel 凭据放到 secrets/cloudflared-credentials.json,权限 0600
  • TUNNEL_ID_INVALID:CLOUDFLARE_TUNNEL_ID 不是 UUID,从 Cloudflare 控制台重新复制
  • TUNNEL_SERVICE_MISSING:Compose 文件里没有 cloudflared 服务,重新执行 soln prepare 生成
  • 连接器挂掉时公网访问失败、但本地 /health/ready 仍然正常,这是预期行为:控制面不会转发任何业务流量

主机层面的问题​

df -h /opt/soln-tenant-runtime
timedatectl status
systemctl is-active docker
  • 可用空间不足 10 GiB:镜像、备份和升级时新旧版本共存都占用这块盘;清掉不属于当前发布的旧备份
  • System clock synchronized: no:先把时间同步修好;时间偏差会让 Lease 校验和 TLS 握手都失败
  • Docker 未运行:启动守护进程;主机重启后如果 Docker 没有开机自启,容器不会自己起来
  • Docker Hub 拉取公共依赖镜像报 i/o timeout:检查 Docker 守护进程能否访问 registry-1.docker.io 和 auth.docker.io;如使用云厂商镜像加速,采用当前账号提供的地址。网络恢复后保留原 setup 文件重试 sl install,无需重新登记
  • 主机重启后:先确认 findmnt /srv/soln/data 显示加密卷已挂载,再启动 Docker、检查容器,最后执行 soln status --dir .;不要让数据写入未挂载的目录

求助前需要收集的信息​

  1. 执行的完整命令和它的全部输出,包含错误码
  2. soln status --dir . --json
  3. soln doctor --dir .
  4. docker compose ps
  5. tenant-runtime-service 容器里的 /tmp/soln-agent-health.json
  6. Runtime Service 和 Workflow Worker 日志的末尾部分
  7. 租户 ID、Runtime ID、部署目标、部署模式、当前发布版本

不要把 .env、Agent 密钥、数据库密码或数据库备份发给任何人。.soln/deployment.json 不含密钥,可以放心提供。

注意事项​

  • 不要手改 .soln/deployment.json 和 .soln/docker-compose.release.yml:它们记录当前发布、镜像摘要和未完成的操作
  • 不要绕过签名校验和 Lease 校验,也不要手改控制面同样记录的那些 .env 值
  • 复用同一个部署目录,不要在已有部署上再装一次
  • 页面和接口报错都带 code、reason、domain 三个字段,含义见错误码