Skip to main content

Prerequisites

Before you begin, ensure you have:

Docker & Docker Compose

Version 20.10+ with Docker Compose v2

Google Gemini API key

Free API key from Google AI Studio
No Python installation required! Everything runs in Docker containers.

Installation

1

Clone the repository

git clone https://github.com/truthixify/ekg
cd ekg
2

Configure environment variables

Copy the example environment file and add your Gemini API key:
cp .env.example .env
Edit .env and set your API key:
.env
GEMINI_API_KEY=your_gemini_api_key_here
NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=password
Keep your .env file secure and never commit it to version control. The .gitignore file already excludes it.
3

Start the system

Launch Neo4j and the EKG application:
docker-compose up
This will:
  • Start Neo4j graph database on ports 7474 (web UI) and 7687 (bolt)
  • Parse configuration files from the data/ directory
  • Build the knowledge graph
  • Start the web interface at http://localhost:8000
First startup takes 1-2 minutes while Docker builds the images and Neo4j initializes.
4

Verify the installation

Check that all services are healthy:
curl http://localhost:8000/api/health
Expected response:
{
  "status": "healthy",
  "components": {
    "storage": true,
    "query_engine": true,
    "query_parser": true,
    "neo4j": true
  }
}

Your first query

Now that EKG is running, let’s explore the system with natural language queries.

Using the web interface

Open http://localhost:8000 in your browser and try these queries:
Who owns the payment service?

Using the API

You can also query via the REST API:
curl -X POST http://localhost:8000/api/query \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What does order-service depend on?",
    "session_id": "demo"
  }'
{
  "response": "The order-service depends on:\n\n• orders-db (database) - PostgreSQL database for orders\n• payment-service (service) - Processes payments\n• inventory-service (service) - Manages inventory\n• notification-service (service) - Sends notifications\n\nOwned by: orders-team (oncall: @dave)",
  "query_type": "downstream",
  "confidence": 0.95,
  "raw_result": [
    {
      "id": "database:orders-db",
      "type": "database",
      "name": "orders-db",
      "distance": 1
    },
    {
      "id": "service:payment-service",
      "type": "service",
      "name": "payment-service",
      "distance": 1
    }
  ]
}

Understanding the data

EKG parsed the sample configuration files in the data/ directory:

Docker Compose services

The system loaded 7 services from data/docker-compose.yml:
api-gateway:
  build: ./services/api-gateway
  ports:
    - "8080:8080"
  environment:
    - AUTH_SERVICE_URL=http://auth-service:8081
    - ORDER_SERVICE_URL=http://order-service:8082
    - PAYMENT_SERVICE_URL=http://payment-service:8083
  depends_on:
    - auth-service
    - order-service
    - payment-service
  labels:
    team: platform-team
    oncall: "@alice"
EKG extracts:
  • Service names and types
  • Dependencies from depends_on and environment variables
  • Team ownership and oncall information from labels
  • Port mappings and configuration

Team ownership

From data/teams.yaml, EKG knows which teams own which services:
data/teams.yaml
teams:
  - name: platform-team
    contact: "@alice"
    owns:
      - api-gateway
      - notification-service
      - redis-main
  
  - name: payments-team
    contact: "@frank"
    owns:
      - payment-service
      - payments-db

Exploring the graph

You can visualize the knowledge graph in Neo4j Browser:
1

Open Neo4j Browser

Navigate to http://localhost:7474Login with:
  • Username: neo4j
  • Password: password
2

Run Cypher queries

Try these queries to explore the graph:
// Show all services
MATCH (n {type: 'service'})
RETURN n
LIMIT 25
// Show service dependencies
MATCH (s {type: 'service'})-[r]->(d)
RETURN s, r, d
LIMIT 50
// Show team ownership
MATCH (t {type: 'team'})-[:OWNS]->(asset)
RETURN t, asset

Example queries to try

Now that you understand the data, try these natural language queries:
  • “Who owns the payment service?”
  • “What does the orders team own?”
  • “Who should I page if orders-db is down?”
  • “List all teams”
  • “What does order-service depend on?”
  • “What services use redis-main?”
  • “What databases does the orders team manage?”
  • “Show me everything that depends on auth-service”
  • “What breaks if redis-main goes down?”
  • “What’s the blast radius of users-db?”
  • “If auth-service fails, what’s affected?”
  • “What teams are impacted if payments-db fails?”
  • “How does api-gateway connect to orders-db?”
  • “What’s between order-service and notification-service?”
  • “Show the path from api-gateway to redis-main”
  • “List all services”
  • “Show me all databases”
  • “What teams are there?”
  • “Find all cache nodes”

Adding your own data

To analyze your own infrastructure:
1

Replace the sample data

Put your configuration files in the data/ directory:
data/
├── docker-compose.yml    # Your Docker Compose services
├── teams.yaml            # Your team ownership info
└── k8s-deployments.yaml  # (Optional) Kubernetes resources
2

Reload the data

Trigger a reload via the API:
curl -X POST http://localhost:8000/api/reload
Or restart the Docker containers:
docker-compose restart ekg-app
3

Verify the new data

Check that your services were loaded:
curl http://localhost:8000/api/entities

Next steps

Architecture

Learn how connectors, storage, queries, and chat work together

API reference

Explore all available API endpoints and query methods

Custom Connectors

Build custom connectors for your infrastructure sources

Configuration

Configure environment variables and system settings

Troubleshooting

Check Docker logs:
docker-compose logs ekg-app
docker-compose logs neo4j
Common issues:
  • Missing GEMINI_API_KEY in .env file
  • Port 8000 or 7687 already in use
  • Insufficient Docker memory (Neo4j needs ~512MB)
Wait for Neo4j to fully initialize (30-60 seconds on first start), then check:
docker-compose ps
All services should show “healthy” status.
Verify data was loaded:
docker-compose logs ekg-app | grep "Total loaded"
You should see: Total loaded: X nodes and Y edgesIf not, check that your configuration files exist in data/.
Verify your Gemini API key is valid:
curl https://generativelanguage.googleapis.com/v1/models?key=YOUR_API_KEY
Check rate limits at Google AI Studio.

Build docs developers (and LLMs) love