Files
qiming/qiming-rcoder/docker/README.md
2026-06-01 13:54:52 +08:00

16 KiB
Raw Permalink Blame History

Docker 本地测试配置说明

本文档说明如何在本地使用 Docker Compose 启动 RCoder 开发环境包含完整的监控服务Pyroscope、Prometheus、Grafana和 eBPF 诊断工具。

📑 目录


快速开始

一键启动

# 1. 构建镜像
make dev-build

# 2. 启动所有服务(包含监控)
make dev-up

# 3. 查看日志
make dev-logs

访问服务

服务 地址 用途
Pyroscope http://localhost:4040 CPU 性能分析火焰图
Prometheus http://localhost:9091 时序指标查询
Grafana http://localhost:3000 进程监控 Dashboard (admin/admin)

创建测试容器

# 发送聊天请求,自动创建 agent_runner 容器
curl -X POST http://127.0.0.1:8088/computer/chat \
  -H "Content-Type: application/json" \
  -d '{"user_id": "user_123", "prompt": "hello"}'

💻 环境要求

必需组件

组件 版本要求 用途
Docker 20.10+ 容器运行时
Docker Compose 2.0+ 多容器编排
Make 任意 构建自动化
Rust 1.75+ 编译项目(本地开发)

可选组件

组件 用途
Python 3 启动测试页面 HTTP 服务器
cURL API 测试

端口占用检查

启动前请确保以下端口未被占用:

# 检查端口占用
lsof -i :4040   # Pyroscope
lsof -i :9091   # Prometheus
lsof -i :3000   # Grafana
lsof -i :8088   # RCoder API

🏗️ 架构概览

整体架构

flowchart TB
    subgraph Docker["🐳 Docker Compose 环境"]
        direction TB

        RCoder["RCoder 主服务<br/>端口: 8088<br/>镜像: master-rcoder:latest<br/>功能: HTTP API + 容器管理"]
        
        subgraph Agent["Agent Runner 子容器(动态创建)"]
            Runner["AI 代理运行时<br/>gRPC 服务端<br/>镜像: master-rcoder:latest"]
        end
        
        subgraph Monitoring["📊 监控服务"]
            direction LR
            Pyro["Pyroscope<br/>:4040"]
            Prom["Prometheus<br/>:9091"]
            Graf["Grafana<br/>:3000"]
            Pyro --> Prom --> Graf
        end
        
        RCoder ==>|"gRPC<br/>内部网络"| Runner
    end
    
    style RCoder fill:#e1f5fe
    style Runner fill:#fff3e0
    style Pyro fill:#f3e5f5
    style Prom fill:#e8f5e9
    style Graf fill:#fce4ec

提示: 在支持 Mermaid 的平台GitHub、GitLab、IDE 插件)上,上图会渲染为交互式流程图。

数据流向

flowchart LR
    subgraph AgentRunner["Agent Runner 容器"]
        direction TB
        Alloy["Grafana Alloy"]
        
        subgraph Collectors["数据采集器"]
            EBPF["eBPF Profiler<br/>97 Hz"]
            PE["Process Exporter<br/>15s"]
        end
        
        Alloy --> EBPF
        Alloy --> PE
    end
    
    subgraph Storage["存储与分析"]
        Pyro["Pyroscope<br/>火焰图 + Top 函数"]
        Prom["Prometheus<br/>时序数据存储"]
    end
    
    subgraph Viz["可视化"]
        Graf["Grafana<br/>统一 Dashboard"]
    end
    
    EBPF -->|"CPU 性能数据"| Pyro
    PE -->|"进程指标"| Prom
    Pyro --> Graf
    Prom --> Graf
    
    style AgentRunner fill:#e3f2fd
    style Pyro fill:#f3e5f5
    style Prom fill:#e8f5e9
    style Graf fill:#fce4ec

📊 监控服务

服务概览

服务 端口 登录信息 数据源 用途
Pyroscope 4040 无需登录 Alloy eBPF (97 Hz) CPU 性能分析火焰图
Prometheus 9091 无需登录 Alloy Process Exporter (15s) 时序指标存储
Grafana 3000 admin / admin Prometheus 可视化 Dashboard

Grafana Dashboard

Dashboard 名称: Agent Runner 进程监控

包含面板:

  • 概览: RSS/VSZ 内存、CPU 使用率、文件描述符
  • 内存趋势: RSS 和 VSZ 的时间序列图
  • I/O 监控: 读取/写入速率
  • 上下文切换: 自愿/非自愿切换速率
  • 线程详情: 线程数量、FD 使用率
  • 缺页错误: 次要/主要缺页错误速率

可用变量:

  • project_id: 过滤项目 ID
  • instance: 过滤实例
  • process_name: 过滤进程名称
  • resolution: 查询分辨率 (15s, 30s, 1m, 5m, 15m)

⚙️ 配置说明

核心配置文件

docker-compose.yml

监控服务配置,定义所有服务容器。

服务列表:

services:
  rcoder:          # 主 RCoder 服务
  pyroscope:       # CPU 性能分析服务器
  prometheus:      # 时序指标数据库
  grafana:         # 可视化平台

config.yml

本地 Docker 容器测试专用配置,用于在 docker-compose 启动的容器中测试动态启动子容器。

镜像配置

所有容器使用相同的镜像,确保环境一致性:

# 主容器和子容器使用相同镜像
image: "master-rcoder:latest"

路径配置

类型 容器内路径 宿主机映射路径 说明
项目工作目录 /app/project_workspace ./docker/project_workspace 项目代码存放
日志目录 /app/logs ./docker/logs 容器日志输出
规范目录 /app/specs - 规范文件存放

与生产环境对比

配置项 本地测试 生产环境
镜像 master-rcoder:latest registry.yichamao.com/rcoder:latest-arm64
配置文件 docker/config.yml config.yml
项目路径 /app/project_workspace ./project_workspace
监控服务 完整Pyroscope + Prometheus + Grafana 按需部署

🔧 常用命令

Make 命令

# 构建镜像
make dev-build

# 启动服务
make dev-up

# 查看日志
make dev-logs

# 重启服务(代码修改后)
make dev-restart

# 停止服务
make dev-down

Docker 命令

# 查看运行中的容器
docker ps | grep rcoder

# 查看容器日志
docker logs -f <container_id>

# 进入容器
docker exec -it <container_id> bash

# 检查容器资源使用
docker stats <container_id>

# 检查挂载点
docker inspect <container_id> | grep Mounts -A 20

API 测试

# 发送聊天请求(创建容器)
curl -X POST http://127.0.0.1:8088/computer/chat \
  -H "Content-Type: application/json" \
  -d '{"user_id": "user_123", "prompt": "hello"}'

# 查询 Agent 状态
curl http://127.0.0.1:8088/agent/status/user_123

# 取消会话
curl -X POST http://127.0.0.1:8088/agent/session/cancel \
  -H "Content-Type: application/json" \
  -d '{"session_id": "<session_id>"}'

💚 健康检查

快速验证所有服务

# 一键检查所有服务状态
curl -s http://localhost:4040/health  # Pyroscope
curl -s http://localhost:9091/-/healthy  # Prometheus
curl -s http://localhost:3000/api/health  # Grafana
curl -s http://localhost:8088/health  # RCoder

检查脚本

# 保存为 check-health.sh
#!/bin/bash
services=(
    "Pyroscope:4040:/health"
    "Prometheus:9091:/-/healthy"
    "Grafana:3000:/api/health"
    "RCoder:8088:/health"
)

for service in "${services[@]}"; do
    IFS=':' read -r name port endpoint <<< "$service"
    if curl -s "http://localhost:${port}${endpoint}" > /dev/null 2>&1; then
        echo "✅ $name (${port})"
    else
        echo "❌ $name (${port}) - 未响应"
    fi
done

监控数据验证

# 检查 Prometheus 是否接收指标
curl -s 'http://localhost:9091/api/v1/query?query=up' | jq '.data.result[]'

# 检查 Pyroscope 是否有应用数据
curl -s 'http://localhost:4040/ingest?name=agent_runner' | jq

# 检查 Grafana 数据源连接
curl -s 'http://admin:admin@localhost:3000/api/datasources' | jq '.[] | select(.name=="Prometheus") | .isDefault'

🧪 测试页面

test-page/ 目录提供 VNC、音频和输入法透传功能的集成测试。

文件说明

文件 说明
vnc-test.html 集成测试页面VNC + 音频 + IME
opus-decoder.min.js Opus 音频解码库86KB

支持功能

  • VNC 远程桌面: WebSocket 连接到容器的 noVNC 服务
  • 音频流播放: 接收并播放容器的音频输出Opus 编码)
  • 输入法透传: 使用本地输入法输入到远程桌面

使用步骤

1. 启动 HTTP 服务器

# 进入测试页面目录(从项目根目录执行)
cd docker/test-page

# 或者直接指定绝对路径
# cd $(git rev-parse --show-toplevel)/docker/test-page

# 使用 Python 启动服务器
python3 -m http.server 8000

2. 访问测试页面

在浏览器打开:http://127.0.0.1:8000/vnc-test.html

3. 配置连接参数

推荐使用 RCoder 代理模式:

  • RCoder 服务地址: http://127.0.0.1:8088
  • User ID: user_123
  • Project ID: 留空或填写实际项目 ID

4. 创建测试容器

curl -X POST http://127.0.0.1:8088/computer/chat \
  -H "Content-Type: application/json" \
  -d '{"user_id": "user_123", "prompt": "hello"}'

🔬 eBPF 诊断工具

概述

RCoder 集成 eBPF 诊断工具,用于开发环境中快速定位进程阻塞和性能问题。

详细文档: /docker/rcoder-agent-runner/ebpf-tools/README.md

⚠️ 安全警告

模式 Feature 容器特权 安全性 调试能力
make dev-restart ebpf-debug 启用 特权 (SYS_ADMIN) ⚠️ 降低 完整
生产模式 默认关闭 限制

仅在受信任的调试环境使用 eBPF 模式!

监控能力

工具 类型 频率 输出位置
Alloy eBPF 持续 CPU 监控 97 Hz Pyroscope Web UI
Alloy Process Exporter 进程指标 15 秒 Grafana Dashboard
offcpu-monitor 阻塞火焰图 60 秒 /app/container-logs/diag/*.svg
syscall-monitor 系统调用追踪 60 秒 /app/container-logs/diag/*.log

快捷诊断命令

# 1. 进入容器
docker exec -it <container> bash

# 2. 获取 agent_runner 进程 PID
PID=$(pgrep agent_runner)

# 3. 执行诊断命令
e-offcpu $PID       # CPU 性能分析(显示耗时函数)
e-flame $PID 60     # 生成 60 秒火焰图
e-profile $PID      # 性能分析
e-all $PID          # 综合诊断(包含所有分析)

导出诊断数据

# 导出所有诊断数据
docker cp <container>:/app/container-logs/diag ./diag-results

# 导出单个火焰图
docker cp <container>:/app/container-logs/diag/flame-<pid>.svg ./

🐛 故障排查

按症状分类

症状:子容器无法启动

可能原因: 镜像不存在

# 检查镜像
docker images | grep master-rcoder

# 解决方案:重新构建
make dev-build

症状:配置文件未生效

可能原因: 挂载路径错误

# 检查配置文件挂载
docker exec -it <container_id> cat /app/config.yml

# 检查日志
make dev-logs

症状:监控服务无数据

诊断步骤:

# 1. 检查监控服务状态
docker ps | grep -E "pyroscope|prometheus|grafana"

# 2. 检查 agent_runner 容器
docker ps | grep agent_runner

# 3. 检查 Prometheus 指标
curl -s 'http://localhost:9091/api/v1/query?query=up' | jq

# 4. 检查 Alloy 日志
docker exec <container> tail -f /app/container-logs/diag/alloy.log

症状Grafana 显示 "No Data"

可能原因: 没有 agent_runner 容器运行

解决方案:

  1. 创建容器(发送聊天请求)
  2. 等待 15-30 秒让数据采集
  3. 刷新 Dashboard

症状:端口冲突

Prometheus 端口冲突9090 → 9091:

# docker-compose.yml 已配置端口映射
prometheus:
  ports:
    - "9091:9090"  # 宿主机 9091 → 容器 9090

检查端口占用:

lsof -i :4040  # Pyroscope
lsof -i :9091  # Prometheus
lsof -i :3000  # Grafana
lsof -i :8088  # RCoder

系统化诊断流程

flowchart TD
    Start["🐛 问题发生"]
    Step1["1⃣ 检查容器状态<br/>docker ps"]
    Step2["2⃣ 查看容器日志<br/>docker logs"]
    Step3["3⃣ 检查网络连通性<br/>docker network inspect"]
    Step4["4⃣ 检查资源使用<br/>docker stats"]
    Step5["5⃣ 进入容器调试<br/>docker exec"]
    Solve["✅ 问题解决"]

    Start --> Step1
    Step1 --> Step2
    Step2 --> Step3
    Step3 --> Step4
    Step4 --> Step5
    Step5 --> Solve

    style Start fill:#ffcdd2
    style Step1 fill:#e1f5fe
    style Step2 fill:#e1f5fe
    style Step3 fill:#e1f5fe
    style Step4 fill:#fff3e0
    style Step5 fill:#f3e5f5
    style Solve fill:#c8e6c9

常见问题

Q1: 如何修改镜像名称?

编辑 docker-compose.yml:

services:
  rcoder:
    image: "your-custom-image:tag"

然后运行 make dev-restart

Q2: 如何持久化监控数据?

编辑 docker-compose.yml,添加数据卷:

services:
  prometheus:
    volumes:
      - ./prometheus/data:/prometheus
  grafana:
    volumes:
      - ./grafana/data:/var/lib/grafana

Q3: 如何禁用某个监控服务?

注释掉 docker-compose.yml 中对应的服务配置。

Q4: 如何调整资源限制?

编辑 docker-compose.yml:

services:
  rcoder:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 4G

Q5: 容器间通信超时怎么办?

检查 Docker 网络:

# 查看网络
docker network ls

# 检查网络详情
docker network inspect rcoder_agent-network

# 测试连通性
docker exec <container1> ping <container2_ip>

Q6: 如何清理所有容器和数据?

# 停止并删除所有容器
make dev-down

# 删除数据卷(谨慎操作)
docker volume prune

# 完全清理
docker system prune -a

📚 附录

Prometheus 查询示例

# 内存使用趋势
process_resident_memory_bytes{project_id="user_123"}

# CPU 使用率
rate(process_cpu_seconds_total{project_id="user_123"}[30s]) * 100

# I/O 读取速率
rate(process_read_bytes_total{project_id="user_123"}[30s])

# 文件描述符使用率
process_open_fds{project_id="user_123"} / process_max_fds{project_id="user_123"}

# 上下文切换速率
rate(process_context_switches_total{project_id="user_123",context_switch_type="voluntary"}[30s])

目录结构

docker/
├── README.md                        # 本文档
├── config.yml                       # 容器内配置
├── docker-compose.yml               # 服务编排配置
├── computer-cache/                  # 计算机缓存
├── computer-project-workspace/      # 计算机项目工作区
├── grafana/                         # Grafana 配置
│   └── provisioning/                # 自动配置
│       ├── dashboards/              # Dashboard 定义
│       └── datasources/             # 数据源配置
├── logs/                            # 日志目录
├── project_workspace/               # 项目工作区
├── prometheus/                      # Prometheus 配置
│   └── prometheus.yml               # 规则文件
├── rcoder-agent-runner/             # Agent Runner 配置
│   └── ebpf-tools/                  # eBPF 工具
│       └── README.md                # 详细文档
├── rcoder-master/                   # 主服务配置
├── start-rcoder.sh                  # 启动脚本
└── test-page/                       # 测试页面
    ├── vnc-test.html                # VNC 测试页面
    └── opus-decoder.min.js          # Opus 解码库

注意: Make 命令在项目根目录的 Makefile 中定义,使用 make -C docker 或从项目根目录执行。

相关文档


最后更新: 2026-01-13 维护者: RCoder Team