Graph-go – 零配置,全面可见
Graph-go – zero config, full visibility

原始链接: https://github.com/guilherme-grimm/graph-go

## graph-info:基础设施可视化与监控 graph-info 自动发现并可视化您的基础设施,提供服务、数据库和存储的实时交互式图形。它需要最少的配置——只需将其指向您的堆栈(通过 Docker socket 或 Kubernetes 集群),它就会自动发现所有内容,并显示实时健康监控。 **主要特性:** * **自动发现:** 从 Docker、Kubernetes、PostgreSQL、MongoDB、MySQL、Redis、Elasticsearch、S3/MinIO 和 HTTP 服务中检测基础设施。 * **交互式图形:** 提供泳道布局,具有平移/缩放、过滤和搜索功能。 * **实时健康状态:** 通过 WebSocket 提供每 5 秒更新一次的状态信息。 * **可扩展性:** 通过 YAML 配置文件支持自定义连接,用于未自动发现的服务。 **入门:** 可以通过 Docker Compose 或直接运行容器进行部署。挂载 Docker socket 是最简单的设置。部署后,前端可在 `http://localhost:3000` 访问。 **重要提示:** 此工具仅用于授权的基础设施监控。未经授权的扫描是被禁止的。 更多详细信息,包括贡献指南和高级配置,请访问 [GitHub 仓库](https://github.com/guilherme-grimm/graph-go)。

## Graph-go:可视化系统连接 开发者 devGrimm 更新了“graph-go”,这是一款用于可视化系统组件之间关系的工具。最初创建的目的是为了帮助理解复杂的系统架构,graph-go 现在具有**完全自动发现**功能,最大限度地减少了手动配置的需求。 目前,该工具专注于映射**Docker 网络**内的连接,提供了一个用户界面来轻松理解环境。此次更新旨在使 UI 更加流畅和可靠。 未来的开发计划包括扩展对 **Kubernetes 和其他编排器**的支持,将其适用性扩展到 Docker 环境之外。该项目是开源的,并欢迎社区贡献。本质上,graph-go 为理解系统的不同部分如何交互提供了一个视觉辅助工具。
相关文章

原文

See your infrastructure. Instantly.

Point graph-info at your stack and get a live, interactive map of every database, table, service, and storage bucket — with real-time health monitoring.

License: AGPL v3 graph-info demo


graph-info auto-discovers your infrastructure by connecting to the Docker daemon, inspecting running containers, and probing databases and storage services. No manual inventory needed — it builds the graph for you.

Capability Details
Auto-discovery Detects infrastructure from Docker containers and Kubernetes clusters — no manual inventory needed
Kubernetes Namespaces, Deployments, StatefulSets, DaemonSets, Pods, Services — with informer-based real-time watching
Docker Classifies running containers, extracts credentials, watches Docker events for live topology changes
PostgreSQL Tables, foreign key relationships, schema topology
MongoDB Databases and collections
MySQL Tables, foreign key relationships
Redis Keyspaces and key distribution
Elasticsearch Indices, cluster health, shard status
S3 / MinIO Buckets and top-level prefixes
HTTP services Health endpoints, dependency mapping between services
Real-time health WebSocket-powered live status updates every 5 seconds
Interactive graph Swimlane layout, namespace group containers, pan/zoom, filter by type/health, search nodes

Point graph-info at your existing infrastructure — no config file needed. Auto-discovery handles the rest:

# Backend — mount the Docker socket for auto-discovery
docker run -d -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/guilherme-grimm/graph-go-backend:latest

# Frontend
docker run -d -p 3000:80 \
  ghcr.io/guilherme-grimm/graph-go-frontend:latest

Open http://localhost:3000 and your infrastructure graph will appear automatically.

To add connections that aren't in Docker (e.g., remote databases, external S3), mount a config file:

docker run -d -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ./conf/config.yaml:/app/conf/config.yaml \
  ghcr.io/guilherme-grimm/graph-go-backend:latest

Download the latest release for your platform from GitHub Releases:

# Example: Linux amd64
curl -sL https://github.com/guilherme-grimm/graph-go/releases/latest/download/graph-info_linux_amd64.tar.gz | tar xz
./graph-info

The backend starts on http://localhost:8080. You'll need to serve the frontend separately (see Local Development Setup).


Quick Start (Docker Compose demo)

To try graph-info with sample data (PostgreSQL, MongoDB, MinIO, and mock services):

git clone https://github.com/guilherme-grimm/graph-go.git
cd graph-go
make docker-up

# Services will be available at:
# - Frontend:      http://localhost:3000
# - Backend API:   http://localhost:8080
# - MinIO Console: http://localhost:9001

To stop:

To rebuild after code changes:

make docker-build && make docker-up

  • Go 1.25.6+
  • Node.js 24+ (or Bun)
  • Docker (required for integration tests)
# Install Go dependencies
cd binary
go mod download

# Copy sample config and edit connection strings
cp ../conf/config.sample.yaml ../conf/config.yaml
# Edit conf/config.yaml with your connection details

# Run the backend
go run ./cmd/app/main.go

The backend API will start on http://localhost:8080.

# Install dependencies
cd webui
npm install

# Start dev server
npm run dev

The frontend dev server will start on http://localhost:5173.

make install       # Install all dependencies
make dev          # Run backend + frontend concurrently
make build        # Build production binaries
make test         # Run all tests

Auto-discovery is the preferred way to use graph-info. Mount the Docker socket and/or run inside a Kubernetes cluster, and graph-info will automatically detect your infrastructure — no configuration needed. Both discoverers activate via auto-detection and run in parallel.

The YAML config file (conf/config.yaml) is only needed for services that aren't reachable via Docker or Kubernetes, such as remote databases, managed cloud services, or external endpoints. When both are used, graph-info merges discovered services with the config file.

See conf/config.sample.yaml for examples.

Kubernetes discovery activates automatically when it detects an in-cluster service account or a ~/.kube/config. Override with:

kubernetes:
  enabled: true          # nil = auto-detect
  kubeconfig: ""         # path override; empty = default lookup
  context: ""            # empty = current context
  namespaces: []         # empty = all namespaces
docker:
  enabled: true          # nil = auto-detect
  socket: "/var/run/docker.sock"
  network: ""            # limit to specific Docker network
  ignore_images: []      # images to skip during classification
connections:
  - name: postgres
    type: postgres
    dsn: "postgres://user:password@localhost:5432/mydb?sslmode=disable"
connections:
  - name: mongodb
    type: mongodb
    uri: "mongodb://user:password@localhost:27017"
connections:
  - name: s3
    type: s3
    region: us-east-1
    access_key_id: "YOUR_ACCESS_KEY"
    secret_access_key: "YOUR_SECRET_KEY"

MinIO / S3-Compatible Adapter

connections:
  - name: minio
    type: s3
    region: us-east-1
    endpoint: "http://localhost:9000"
    access_key_id: minioadmin
    secret_access_key: minioadmin
connections:
  - name: mysql
    type: mysql
    dsn: "root:password@tcp(localhost:3306)/mydb"
connections:
  - name: redis
    type: redis
    uri: "redis://localhost:6379"

Or with host/port (useful for Docker discovery):

connections:
  - name: redis
    type: redis
    host: localhost
    port: 6379
    password: ""
connections:
  - name: elasticsearch
    type: elasticsearch
    endpoint: "http://localhost:9200"
    username: elastic
    password: changeme

Important: This tool is intended for authorized infrastructure visualization and monitoring of systems you own or have permission to access. Do not use it to scan or access systems without authorization.


                          ┌─────────────────────────────────────┐
                          │         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)

Key Components:

  • Discoverer Interface: Uniform contract (Discover, Watch, Close) for all discovery backends — Docker and Kubernetes run in parallel, results are concatenated
  • Docker Discovery: Inspects containers, classifies images, extracts credentials from env vars, watches Docker events for live topology changes
  • Kubernetes Discovery: Uses client-go informers with debounced event handling; discovers Namespaces, Deployments, StatefulSets, DaemonSets, Pods, and Services with health mapping
  • Adapters: Implement the Adapter interface to probe databases and storage services
  • Registry: Manages adapters and topology sets, creates service-level parent nodes, aggregates graph data
  • Cache: 30-second TTL with singleflight pattern to prevent thundering herd
  • WebSocket: Streams health updates every 5 seconds

Frontend (React + TypeScript)

  • Swimlane Layout: Namespace-aware layout with zone classification (system, infra, application namespaces)
  • Group Containers: K8s namespaces render as collapsible bounding boxes via React Flow grouping
  • Node Inspector: Side panel showing detailed metadata and connections
  • WebSocket Hook: Real-time health updates without polling
Adapter-discovered:
  Service Node (postgres/mongodb/s3)
      └─ Database/Bucket Node
          └─ Table/Collection/Prefix Node

Kubernetes-discovered:
  Namespace (group container)
      └─ Deployment / StatefulSet / DaemonSet
          └─ Pod
      └─ K8sService ──routes_to──→ Pod

Edges represent relationships (contains, foreign_key, routes_to, etc.).


Backend:

  • Go 1.25.6
  • gorilla/mux (HTTP routing)
  • k8s.io/client-go (Kubernetes discovery + informers)
  • pgxpool (PostgreSQL)
  • mongo-driver v2 (MongoDB)
  • go-sql-driver/mysql (MySQL)
  • go-redis/v9 (Redis)
  • go-elasticsearch/v8 (Elasticsearch)
  • AWS SDK v2 (S3)
  • coder/websocket (WebSocket)
  • testcontainers-go (integration tests)

Frontend:

  • TypeScript
  • React 18
  • React Flow (graph visualization)
  • Vite (build tool)

Infrastructure:

  • Docker + Docker Compose
  • PostgreSQL 17
  • MongoDB 7
  • MySQL 8
  • Redis 7
  • Elasticsearch 8
  • MinIO (S3-compatible)

cd binary && go test ./...

Runs without Docker. Includes pure function tests and HTTP handler tests.

cd binary && go test -tags=integration -v -timeout=5m ./internal/adapters/...

Requires Docker. Uses testcontainers-go to spin up real database instances (PostgreSQL, MongoDB, MySQL, Redis, Elasticsearch, MinIO) — no mocks.

Every adapter runs through the contract test suite (adaptertest.RunContractTests) which validates:

  • Connect/disconnect lifecycle
  • Node/edge discovery (unique IDs, valid parent refs, correct types)
  • Health metrics (status key, required keys)

Run a single adapter's tests:

cd binary && go test -tags=integration -v ./internal/adapters/redis/
make test  # unit + type-check
cd binary && go test -tags=integration -timeout=5m ./internal/adapters/...  # integration

Returns the full infrastructure graph (nodes + edges).

Response:

{
  "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"
      }
    ]
  }
}

Returns details for a specific node.

Returns adapter health status (ok/degraded/error).

Streams real-time health updates.

Message format:

{
  "type": "health_update",
  "nodeId": "postgres",
  "status": "healthy",
  "timestamp": "2026-02-09T10:30:00Z"
}

  1. Create adapter package in binary/internal/adapters/{name}/
  2. Implement the Adapter interface:
    type Adapter interface {
        Connect(config ConnectionConfig) error
        Discover() ([]nodes.Node, []edges.Edge, error)
        Health() (HealthMetrics, error)
        Close() error
    }
  3. Self-register via init() with adapters.RegisterFactory("name", ...)
  4. Add integration tests (required) — create {name}_integration_test.go with:
    • Build tag //go:build integration
    • TestMain using testcontainers-go to start a real instance
    • Seed representative data
    • Call adaptertest.RunContractTests to validate the interface contract
    • Add adapter-specific tests (filtering, ID format, metadata, etc.)
  5. Import adapter in binary/internal/server/server.go (blank import for init())
  6. Add node type in binary/internal/graph/nodes/nodes.go
  7. Update frontend types in webui/src/types/graph.ts
  8. Add icon in webui/src/components/graph/CustomNode.tsx

Discoverers live in binary/internal/discovery/{name}/ and implement the Discoverer interface:

type Discoverer interface {
    Name() string
    Discover(ctx context.Context) ([]ServiceInfo, error)
    Watch(ctx context.Context, onChange func()) error
    Close() error
}
  1. Create discoverer package in binary/internal/discovery/{name}/
  2. Implement the Discoverer interface — return []ServiceInfo from Discover(). Topology-producing discoverers (like K8s) populate Nodes/Edges directly; adapter-oriented ones (like Docker) populate Config for adapter bridging.
  3. Wire into server in binary/internal/server/server.go — add a build{Name}Discovery() function and call it alongside the existing discoverers.
  4. Add integration tests with //go:build integration — use real infrastructure (kind/k3d for K8s, testcontainers for others). No mocks.

See CONTRIBUTING.md for detailed guidance.


We welcome contributions! See CONTRIBUTING.md for guidelines on:

  • Development setup
  • Code style conventions
  • How to add new adapters
  • Submitting pull requests

Intended Use:

  • Visualizing and monitoring infrastructure you own or have authorization to access
  • DevOps dashboards and topology mapping
  • Infrastructure documentation and onboarding
  • Exploring database schemas and relationships

Not Intended For:

  • Unauthorized system scanning or reconnaissance
  • Security testing without explicit permission
  • Accessing systems you don't own or control

Users are responsible for ensuring they have proper authorization before connecting graph-info to any infrastructure.


This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).

See the LICENSE file for details. AGPL requires that modified versions used over a network must also be open-sourced.


The project uses GitHub Actions for continuous integration and automated releases.

  • CI runs on every push/PR to main — backend unit tests, integration tests (testcontainers), and frontend build
  • Releases are triggered by version tags (v*) and produce:
    • Cross-platform binaries (Linux, macOS, Windows) via GoReleaser
    • Docker images pushed to ghcr.io/guilherme-grimm/graph-go-backend and -frontend

To create a release:

git tag v0.1.0
git push --tags



Built with ❤️ for DevOps and infrastructure engineers

联系我们 contact @ memedata.com