graph-go 是一个 CLI 优先的基础设施映射工具。它通过连接 Docker 守护进程、检查运行中的容器以及探测数据库和存储服务来自动发现你的基础设施。UI 由后端提供,反映实时的后端状态——无需手动清单。
| 能力 | 详情 |
|---|---|
| 自动发现 | 从 Docker 容器和 Kubernetes 集群中检测基础设施——无需手动清单 |
| Kubernetes | 命名空间、Deployments、StatefulSets、DaemonSets、Pods、Services——基于 informer 的实时监控 |
| Docker | 对运行中的容器进行分类、提取凭据、监控 Docker 事件、支持 graphgo.* 标签以覆盖类型/DSN/节点类型/名称或忽略某个容器 |
| PostgreSQL | 表、外键关系、模式拓扑 |
| MongoDB | 数据库和集合 |
| MySQL | 表、外键关系 |
| Redis | Keyspaces 和键分布 |
| Elasticsearch | 索引、集群健康、分片状态 |
| S3 / MinIO | 存储桶和顶级前缀 |
| HTTP 服务 | 健康端点、服务间的依赖映射 |
| 实时健康 | 基于 WebSocket 的实时状态更新,每 5 秒一次 |
| 交互式图 | 泳道布局、命名空间组容器、平移/缩放、按类型/健康过滤、搜索节点 |
graph-go 支持一小部分 graphgo.* 容器标签(可设置在你的任何容器上):
使用这些标签可以挽救被错误分类的容器、将 graph-go 指向自定义 DSN,或者在不移除容器的情况下将其从图中隐藏。
使用 CLI 启动预填充的演示堆栈。这是以真实环境看到 graph-go 的最快方式,也是首次用户的推荐入门路径:
git clone https://github.com/guilherme-grimm/graph-go.git
cd graph-go
go run ./cmd/app demo
打开 **http://localhost:8080**。该命令通过 Docker Compose 以附加模式运行。按 Ctrl+C 停止附加会话。
在冷机器上首次运行可能需要几分钟,因为 Docker 可能需要拉取基础镜像并构建本地演示镜像。后续运行会快得多。
演示堆栈需要以下主机端口空闲:8080, 5432, 27017, 9000, 和 9001。
如果需要显式清理:
docker compose -f docker-compose.demo.yml down
一个容器,一个端口。以只读方式挂载 Docker 套接字,graph-go 会自动发现主机上运行的所有内容:
docker run -d -p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
ghcr.io/guilherme-grimm/graph-go:latest
graph-go 只从 Docker 套接字读取数据。
ro标志强制执行此规则——请保留它。
打开 **http://localhost:8080**。自动发现处理 Docker 容器,并且(当存在 kubeconfig 或集群内服务账户时)无需任何配置文件即可处理 Kubernetes 资源。
对于 Docker/Kubernetes 之外的服务(远程数据库、托管云服务),请挂载一个配置文件——参见配置。
单个自包含二进制文件——UI 已嵌入,但入口点仍然是 CLI。
# Linux amd64(需要 GitHub CLI;其他平台请浏览 Releases)
gh release download --repo guilherme-grimm/graph-go --pattern 'graph-go_*_linux_amd64.tar.gz' --clobber
tar xzf graph-go_*_linux_amd64.tar.gz
./graph-go serve # 或者直接 `./graph-go` - 效果相同
打开 **http://localhost:8080**。其他平台请访问 Releases 页面。
全局标志(适用于每个子命令):--config, --log-level, --log-format。参见 graph-go <command> --help 获取每个命令的完整参数。
典型流程:
graph-go demo 进行一个真实的本地演练。graph-go serve 针对你自己的基础设施运行。graph-go scan 用于一次性自动化、导出或 CI 检查。| 端口 | 用途 |
|---|---|
8080 | graph-go(UI + API + WebSocket — 生产环境) |
5173 | Vite 开发服务器(仅开发环境 — 参见 CONTRIBUTING.md) |
9001 | MinIO 控制台(仅演示堆栈) |
自动发现是主要路径。挂载 Docker 套接字和/或在 Kubernetes 集群内运行——graph-go 会发现你的基础设施,无需配置文件。
只有在服务无法通过发现访问时(远程数据库、托管云服务、外部端点),才将 YAML 配置文件(conf/config.yaml)作为逃生舱口使用。完整的模式请参见 conf/config.sample.yaml——包含每个适配器和每个配置块(server, docker, kubernetes, connections)的示例。
要在上述 Docker 运行中使用配置文件:
docker run -d -p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v $(pwd)/conf/config.yaml:/app/conf/config.yaml:ro \
ghcr.io/guilherme-grimm/graph-go:latest
仅限授权使用: graph-go 用于可视化你拥有或有权访问的基础设施。不要将其指向未经授权的系统。
┌─────────────────────────────────────┐
│ Discoverer Interface │
│ Discover() · Watch() · Close() │
└──────────┬──────────┬───────────────┘
│ │
┌──────────▼──┐ ┌────▼──────────────┐
│ Docker │ │ Kubernetes │
│ Discoverer │ │ Discoverer │
│ (containers,│ │ (informers, pods, │
│ classify, │ │ deployments, │
│ events) │ │ services, health) │
└──────┬──────┘ └────┬──────────────┘
│ │
┌──────▼───────────────▼──────┐
│ Parallel Discovery + Merge │
│ (concatenate ServiceInfo) │
└──────────────┬──────────────┘
│
Config (YAML) ──→ YAML Merge ───────────▶│
▼
┌─────────────────────────────┐
│ Adapter Registry │
│ ├─ PostgreSQL → Tables + FK│
│ ├─ MongoDB → Collections │
│ ├─ MySQL → Tables + FK │
│ ├─ Redis → Keyspaces │
│ ├─ Elasticsearch → Indices │
│ ├─ S3 → Buckets │
│ └─ HTTP → Health + deps│
│ │
│ + Topology (K8s nodes/edges) │
└──────────────┬───────────────┘
▼
Graph Model (Nodes + Edges)
▼
REST API + WebSocket (Real-time)
关键组件:
Discover, Watch, Close)——Docker 和 Kubernetes 并行运行,结果合并Adapter 接口,用于探测数据库和存储服务适配器发现:
服务节点 (postgres/mongodb/s3)
└─ 数据库/存储桶节点
└─ 表/集合/前缀节点
Kubernetes 发现:
命名空间(组容器)
└─ Deployment / StatefulSet / DaemonSet
└─ Pod
└─ K8sService ──routes_to──→ Pod
边表示关系(contains, foreign_key, routes_to 等)。
后端:
前端:
基础设施:
go test ./...
无需 Docker。包含纯函数测试和 HTTP 处理器测试。
go test -tags=integration -v -timeout=5m ./internal/adapters/...
需要 Docker。使用 testcontainers-go 启动真实的数据库实例(PostgreSQL, MongoDB, MySQL, Redis, Elasticsearch, MinIO)——无模拟。
每个适配器都运行契约测试套件(adaptertest.RunContractTests),该套件验证:
运行单个适配器的测试:
go test -tags=integration -v ./internal/adapters/redis/
make test # 单元测试 + 类型检查
go test -tags=integration -timeout=5m ./internal/adapters/... # 集成测试
/api/graph返回完整的基础设施图(节点 + 边)。
响应:
{
"data": {
"nodes": [
{
"id": "service-postgres",
"type": "postgres",
"name": "postgres",
"metadata": { "adapter": "postgres" },
"health": "healthy"
}
],
"edges": [
{
"id": "edge-1",
"source": "service-postgres",
"target": "pg-mydb",
"type": "contains",
"label": "contains"
}
]
}
}
/api/node/{id}返回特定节点的详细信息。
/api/health返回适配器健康状态(ok/degraded/error)。
/websocket流式传输实时更新。发出两种消息类型,均包装为 { "type": "...", "payload": { ... } }。没有 timestamp 字段——客户端通过到达顺序推断顺序。
health_update——每轮扫描(每 5 秒)为每个节点发送一次。适配器拥有的节点通过适配器查找获取健康状态;拓扑节点(如 Kubernetes 资源)直接在节点上携带健康状态。
{
"type": "health_update",
"payload": {
"nodeId": "service-postgres",
"health": "healthy"
}
}
health 为以下之一:healthy, degraded, unhealthy。
graph_update——当节点 ID 集合发生变化(发现过程中添加或移除节点)时发送。payload 为空;客户端应重新获取 /api/graph。
{
"type": "graph_update",
"payload": {}
}
internal/adapters/{name}/Adapter 接口:
type Adapter interface {
Connect(config ConnectionConfig) error
Discover() ([]nodes.Node, []edges.Edge, error)
Health() (HealthMetrics, error)
Close() error
}
init() 自注册,使用 adapters.RegisterFactory("name", ...){name}_integration_test.go,包含:
//go:build integrationTestMainadaptertest.RunContractTests 验证接口契约internal/server/server.go 中导入适配器(为 init() 进行空白导入)Discoverer 位于 internal/discovery/{name}/ 并实现 Discoverer 接口:
type Discoverer interface {
Name() string
Discover(ctx context.Context) ([]ServiceInfo, error)
Watch(ctx context.Context, onChange func()) error
Close() error
}
internal/discovery/{name}/ 创建 discoverer 包Discoverer 接口——从 Discover() 返回 []ServiceInfo。产生拓扑的 discoverer(如 K8s)直接填充 Nodes/Edges;面向适配器的 discoverer(如 Docker)填充 Config 用于适配器桥接。internal/server/server.go 中接入服务器——添加一个 build{Name}Discovery() 函数并与现有 discoverer 一起调用。//go:build integration——使用真实基础设施(K8s 用 kind/k3d,其他用 testcontainers)。无模拟。详细指南请参见 CONTRIBUTING.md。
我们欢迎贡献!详见 CONTRIBUTING.md 了解以下指南:
预期用途:
非预期用途:
用户有责任确保在将 graph-go 连接到任何基础设施之前已获得适当的授权。
本项目采用 GNU Affero General Public License v3.0 (AGPL-3.0) 许可证。
详情参见 LICENSE 文件。AGPL 要求通过网络使用的修改版本也必须开源。
项目使用 GitHub Actions 进行持续集成和自动发布。
main 或发起 PR 时运行——后端单元测试、集成测试(testcontainers)和前端构建v*)触发,并生成:
ghcr.io/guilherme-grimm/graph-go 的单个 Docker 镜像创建发布版本:
git tag v0.1.0
git push --tags
为 DevOps 和基础设施工程师打造 ❤️
| 标签 | 效果 |
|---|
graphgo.ignore=true | 完全跳过该容器 |
graphgo.type=postgres | 强制适配器类型(postgres, mongodb, mysql, redis, elasticsearch, s3, http) |
graphgo.dsn=... | 注入连接字符串(postgres/mysql 用 DSN,mongodb 用 URI,其他情况回退到 dsn) |
graphgo.node-type=gateway | 覆盖可视化节点类型(service, gateway, auth, api, queue, cache) |
graphgo.name=... | 覆盖图中显示的节点名称,也用于节点 ID/日志 |
| 命令 | 功能 |
|---|
graph-go demo | 从仓库启动预填充的 Docker Compose 演示堆栈,并在前台流式输出结果。 |
graph-go serve | 启动 HTTP 服务器,包含自动发现和实时更新(默认——与无参数运行效果相同)。 |
graph-go scan | 执行一次发现,并将图以 JSON 格式输出到 stdout。适用于通过 jq 管道处理、CI 检查或一次性导出。 |
graph-go version | 打印版本、提交和构建日期。 |
graph-go --health-check | 命中本地 /health 并退出 0/1。用于容器 HEALTHCHECK;不适用于交互式使用。 |
internal/graph/nodes/nodes.go 中添加节点类型webui/src/types/graph.ts 中更新前端类型webui/src/components/graph/CustomNode.tsx 中添加图标