# 执行计划 — Docker 容器巡检环境隔离问题修复

> 版本：1.0 ｜ 日期：2026-07-29 ｜ 关联 PRD：`PRD_Docker容器巡检环境隔离问题.md`

---

## 执行概览

| 阶段 | 任务 | 预估工时 | 状态 |
|------|------|----------|------|
| 阶段一 | 本级目标标记 + 前端警告提示 | 0.5h | 待开始 |
| 阶段二 | 本级巡检 SSH 到宿主机执行 | 2h | 待开始 |
| 阶段三 | Docker 部署配置调整 | 0.5h | 待开始 |
| 阶段四 | 测试验证 | 0.5h | 待开始 |

---

## 阶段一：本级目标标记 + 前端警告提示（P0）

### 1.1 目标服务增加类型判断

**文件**：`skill/code/web/service_monitor/services/target_service.py`

```python
def create_target(data):
    """创建目标时自动判断是否为本级"""
    host = data.get('host', '').strip()
    
    # 本级目标判断
    if host in ('localhost', '127.0.0.1', '::1', 'host.docker.internal'):
        data['is_local'] = True
        data['local_type'] = 'containerized'  # 标记容器化部署
    else:
        data['is_local'] = False
    
    # 原有逻辑...
```

### 1.2 目标列表返回警告信息

**文件**：`skill/code/web/service_monitor/services/target_service.py`

```python
def list_targets(role='admin'):
    targets = _load_targets()
    
    for t in targets:
        # 本级目标添加警告
        if t.get('is_local') and t.get('local_type') == 'containerized':
            t['warning'] = '容器化部署下本级巡检数据可能不准确，建议配置宿主机 SSH'
    
    return targets
```

### 1.3 前端目标列表显示警告

**文件**：`frontend/src/views/service-monitor/Targets.vue` 或 `Index.vue`

```vue
<template v-if="target.warning">
  <el-alert
    :title="target.warning"
    type="warning"
    :closable="false"
    show-icon
  />
</template>
```

### 1.4 前端目标创建页面提示

**文件**：`frontend/src/views/service-monitor/Run.vue` 或目标创建表单

当用户输入 `localhost` 或 `127.0.0.1` 时显示提示。

---

## 阶段二：本级巡检 SSH 到宿主机执行（P1）

### 2.1 获取 Docker 宿主机 IP

**文件**：`skill/code/web/service_monitor/utils/executor.py`

新增函数：

```python
def get_docker_host_ip():
    """获取 Docker 宿主机 IP
    
    优先级：
    1. 环境变量 DOCKER_HOST_IP
    2. 从 ip route 解析网关 IP
    3. 回退到 host.docker.internal
    """
    import os
    import subprocess
    
    # 1. 环境变量
    ip = os.environ.get('DOCKER_HOST_IP')
    if ip:
        return ip
    
    # 2. ip route 解析
    try:
        result = subprocess.run(
            ['ip', 'route'],
            capture_output=True, text=True, timeout=5
        )
        for line in result.stdout.split('\n'):
            if 'default' in line:
                parts = line.split()
                if len(parts) >= 3:
                    return parts[2]  # 网关 IP
    except Exception:
        pass
    
    # 3. 回退
    return 'host.docker.internal'
```

### 2.2 修改巡检执行器

**文件**：`skill/code/web/service_monitor/utils/executor.py`

修改 `LocalExecutor` 类：

```python
class LocalExecutor:
    """本级巡检执行器 - 通过 SSH 到宿主机"""
    
    def __init__(self):
        self.host_ip = get_docker_host_ip()
    
    def run_script(self, script_path, timeout=60):
        """执行巡检脚本
        
        本级目标通过 SSH 到宿主机执行
        """
        import os
        from .executor import SSHExecutor
        
        # 从环境变量获取宿主机 SSH 配置
        ssh_user = os.environ.get('LOCAL_SSH_USER', 'root')
        ssh_key = os.environ.get('LOCAL_SSH_KEY', '')
        ssh_password = os.environ.get('LOCAL_SSH_PASSWORD', '')
        
        if ssh_key:
            executor = SSHExecutor(
                host=self.host_ip,
                username=ssh_user,
                key_filename=ssh_key
            )
        else:
            executor = SSHExecutor(
                host=self.host_ip,
                username=ssh_user,
                password=ssh_password
            )
        
        return executor.run_script(script_path, timeout)
```

### 2.3 环境变量配置

**文件**：`.env`（服务器上）

```bash
# 本级巡检宿主机 SSH 配置
LOCAL_SSH_USER=root
LOCAL_SSH_PASSWORD=Ubains@123
# 或使用密钥
# LOCAL_SSH_KEY=/app/keys/host_key
```

---

## 阶段三：Docker 部署配置调整

### 3.1 Dockerfile 无需修改

SSH 客户端（paramiko）已在 requirements.txt 中。

### 3.2 Docker 启动参数调整

**文件**：`deploy/deploy_docker.py` 或手动执行

```bash
docker run -d --name troubleshoot \
  --add-host=host.docker.internal:host-gateway \
  -e LOCAL_SSH_USER=root \
  -e LOCAL_SSH_PASSWORD=Ubains@123 \
  -p 8088:80 \
  ...
```

### 3.3 docker-compose.yml 调整

```yaml
version: '3.8'
services:
  troubleshoot:
    image: troubleshoot:latest
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      - LOCAL_SSH_USER=root
      - LOCAL_SSH_PASSWORD=${LOCAL_SSH_PASSWORD}
    # ...
```

---

## 阶段四：测试验证

### 4.1 本级巡检测试

```bash
# 在容器内测试
docker exec -it troubleshoot bash

# 测试宿主机 IP 解析
python3 -c "
from service_monitor.utils.executor import get_docker_host_ip
print(get_docker_host_ip())
"

# 测试 SSH 连接宿主机
python3 -c "
import os
from service_monitor.utils.executor import LocalExecutor
executor = LocalExecutor()
print(executor.run_script('/app/web/service_monitor/assets/system/01_system_basic.sh'))
"
```

### 4.2 远程巡检测试

确保远程 SSH 巡检仍然正常工作。

### 4.3 前端测试

1. 本级目标显示警告
2. 本级巡检执行成功
3. 巡检报告数据为宿主机数据

---

## 文件变更清单

### 修改文件

| 文件 | 修改内容 |
|------|----------|
| `skill/code/web/service_monitor/services/target_service.py` | 本级目标标记 + 警告信息 |
| `skill/code/web/service_monitor/utils/executor.py` | 新增 `get_docker_host_ip()` + 修改 `LocalExecutor` |
| `frontend/src/views/service-monitor/Targets.vue` | 显示警告 |
| `frontend/src/views/service-monitor/Index.vue` | 显示警告 |
| `docker-compose.yml` | 添加 extra_hosts + 环境变量 |

### 新增文件

无

---

## 执行顺序

```
阶段一（标记警告）→ 阶段二（SSH 执行）→ 阶段三（Docker 配置）→ 阶段四（测试）
```

**建议**：
1. 先完成阶段一的快速修复（前端警告），让用户知道问题存在
2. 再实现阶段二的完整方案（SSH 到宿主机）
3. 最后更新部署配置并验证