# 局域网远端部署 SOP

适用：经局域网 SSH / 远控在 Windows 机器上部署并让服务长期存活，尤其包含浏览器/扩展/GUI 依赖链路。

## 已验证关键前置

- 若服务经 SSH 前台启动后“短暂可用又消失”，优先怀疑 **SSH 会话结束回收子进程**；不要先怀疑代码崩溃。
- 后台化优先顺序：
  1. **复用目标机上已验证可工作的计划任务**
  2. 其次新建计划任务/本机脚本
  3. 最后才尝试普通 `Start-Process`
- GUI/浏览器/扩展相关任务，优先保持在 **已验证成功的交互用户会话** 中运行；不要想当然切到 `SYSTEM`。

## 稳定承载原则

- 远端 PowerShell 中调用计划任务时，`schtasks` 若报“找不到文件”，优先改用绝对路径：
  - `C:\Windows\System32\schtasks.exe`
- 本地 → SSH → PowerShell 多层链路下，避免直接拼复杂 `/TR`；更稳做法：
  - 先把启动逻辑落到远端 `.cmd` / `.ps1`
  - 再由计划任务调用该脚本
- 某些依赖用户 profile / 浏览器 profile / 扩展态的任务，即使前台可跑，换成其他用户或 `SYSTEM` 后会秒失败；应优先复用 **与前台验证一致的用户身份**。

## 浏览器/扩展类特殊规则

- 若目标链路依赖浏览器扩展、tab 会话、用户登录态，优先：
  - 找现成的浏览器启动任务
  - 找现成的服务启动任务
  - 按原有组合重新拉起
- 仅看到进程存在不算成功；至少同时验证以下之一：
  - 目标监听端口存在
  - 运行日志出现 tab / bridge 接入
  - 本地健康接口返回 OK
- 若源码显示主服务端口旁还有 `port+1` 配套监听，需先读源码确认用途，**不要把伴随端口误判为异常残留**。

## 排障顺序

1. **先查监听**
   - 看目标端口是否真的 `LISTENING`
2. **再查 PID 归属**
   - 把端口映射到具体 PID 和命令行
3. **再查日志**
   - 看是启动失败、权限问题、还是会话链路未接入
4. **最后才重启/重跑**
   - 没有新信息时不要重复触发同一命令

## 常见真因（已验证）

- 旧用户残留进程仍在占端口，会让“新任务已运行”看似成功、实际未接管。
- 浏览器扩展实际连接的端口与服务当前监听端口不一致，会表现为服务在跑但会话没恢复。
- 服务本体健康正常时，应以 **健康接口 / OpenAPI / 实际路由** 为准，不要被其他无关监听端口误导。

## 精确清理原则

- 禁止无条件杀 `python.exe`。
- 先找：
  - 端口 → PID
  - PID → 命令行 / 用户归属
- 仅精确结束确认属于旧残留、且正在干扰部署目标的那个进程。

## 验收标准

满足以下条件才算部署完成：

- 服务由稳定承载方式启动（优先计划任务或已验证交互会话）
- 目标端口监听正常
- 若有健康接口，返回成功
- 若依赖浏览器/扩展，会话已重新接入
- 日志与监听状态一致，无“进程在但链路未通”的假成功

## 复盘时优先记忆的信息

只记录跨会话仍重要的内容：

- 哪类任务不能脱离交互用户
- 哪类任务必须复用现成计划任务
- 哪类失败根因来自 SSH 会话回收、端口占用、用户身份不一致

不要记录：

- 临时 PID
- 某次会话的瞬时端口占用状态
- 一次性日志片段