Hang Zhengyang

Docker 路线(仓库实现剖析)

本文不是 Docker 入门,而是解释本仓库在 Docker 路线中“如何工作、由谁负责、边界在哪里”。

0. 基础概念速记(高密度)

  • Image:不可变运行模板;本仓库关键镜像是 app-service 构建产物与 nginx/postgres/prometheus/grafana 官方镜像。
  • Container:镜像的运行实例;本仓库通过 container_name 固定了核心实例名。
  • Volume:容器外持久化层;postgres_data/grafana_data 承担状态留存。
  • Network(Compose 默认桥接网络):服务间 DNS 与连通边界;app-service 通过 postgres:5432 访问数据库。
  • Compose:多容器声明式编排器;负责本地拓扑一次性拉起/停止。
  • Port mapping vs expose:ports 对宿主机开放,expose 仅容器网络内可见;本仓库 app-service 只 expose 3000,不直接暴露主机端口。

1. 拓扑与责任切分

serving-lab/docker-compose.yml 定义了 5 个运行单元与 2 个持久卷:

  • app-service:FastAPI 应用容器,内部承载模块化单体(orchestrator/retriever/llm_adapter/repository)。
  • postgres:业务持久化存储(聊天记录、会话等)。
  • edge-proxy(Compose service 名为 nginx,容器名 edge-proxy):统一入口,处理对 app-service 的反向代理。
  • prometheus:抓取 app-service 的 /metrics。
  • grafana:消费 Prometheus 数据并加载预置 dashboard/alert 规则。
  • postgres_data、grafana_data:分别持久化数据库和 Grafana 状态。

这条路线的本质:单机编排 + 容器网络内服务发现 + 明确的 north-south 单入口(edge-proxy)。

2. 数据面流量路径

外部请求路径:

  1. Client -> localhost:8080 -> edge-proxy。
  2. edge-proxy 根据 nginx/default.conf 转发到 app-service:3000。
  3. app-service 在内部模块链路处理请求:
    • retriever 取上下文(当前是轻量规则检索);
    • llm_adapter 产出 mock 推理结果;
    • repository 写入 PostgreSQL。
  4. 应用同时暴露 /metrics 给 Prometheus;Grafana 从 Prometheus 查询并渲染。

这意味着:业务数据平面和观测平面并行,互不阻塞;即 Prometheus/Grafana 故障不应阻断主请求链路。

3. 控制面行为(Compose 如何驱动)

  • docker compose up --build 同时完成构建 + 网络/卷创建 + 进程编排。
  • depends_on 只保证“启动顺序”,不保证“服务可用”;真正可用性由应用自身重试/探针兜底。
  • Compose 网络默认提供 service-name DNS(如 postgres, app-service),因此应用通过内部主机名访问依赖。

4. 状态与一致性

  • 容器是易失的,持久状态放在 volume:
    • PostgreSQL -> postgres_data
    • Grafana -> grafana_data
  • 配置即挂载:
    • Prometheus 配置文件挂载为只读;
    • Grafana provisioning/dashboards/alert rules 均走文件挂载;
    • Nginx 配置挂载为只读。

这一设计的关键收益:行为可复现(镜像+配置固定),并且配置变更可审计(在 Git 中)。

5. 失效模式与排障优先级

高频故障顺序:

  1. edge-proxy 502:先看 app-service 是否启动成功、是否监听 3000。
  2. 应用 5xx:看 DATABASE_URL 与 postgres 连接。
  3. 指标缺失:确认 /metrics 正常、Prometheus target 状态。
  4. Grafana 空面板:确认 datasource/provisioning 挂载路径与权限。

建议固定排障序列:

  • docker compose ps
  • docker compose logs app-service edge-proxy postgres
  • curl /health -> curl /api/chat -> curl /metrics
  • Prometheus Targets 页面 -> Grafana 数据源测试

6. 与 K8s/Terraform 的边界关系

  • Docker 路线是本地运行时与镜像产出入口,不是最终集群交付入口。
  • 镜像 tag(如 serving-lab-app-service:latest)会被后续 Kind/K8s/Terraform 路线复用。
  • 因此 Docker 路线提供的是:
    • 快反馈开发回路;
    • 最小可运行基线;
    • 为集群部署提供可验证镜像。

7. 结论(仓库语义)

在本仓库里,Docker 不是“演示容器”,而是本地标准运行平面:

  • 它定义了真实的服务边界(入口/业务/存储/观测);
  • 它提供了最快的系统级回归路径;
  • 它是上层 K8s/Terraform 交付前的契约验证层。