feat(falkordb): install FalkorDB

This commit is contained in:
Masaki Yatsu
2025-11-30 16:22:19 +09:00
parent 0032b0c4b4
commit 162d4241cd
15 changed files with 915 additions and 0 deletions

2
falkordb/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
falkordb-password-external-secret.yaml
falkordb-values.yaml

255
falkordb/README.md Normal file
View File

@@ -0,0 +1,255 @@
# FalkorDB
FalkorDB is a high-performance graph database with vector similarity search capabilities, designed for knowledge graphs and GraphRAG applications. It uses OpenCypher as its query language and is Redis-compatible.
## Table of Contents
- [Installation](#installation)
- [Prerequisites](#prerequisites)
- [Connection Information](#connection-information)
- [Usage](#usage)
- [Configuration](#configuration)
- [Cognee Integration](#cognee-integration)
- [Management](#management)
- [Troubleshooting](#troubleshooting)
## Installation
Install FalkorDB with interactive configuration:
```bash
just falkordb::install
```
This will:
- Create the `falkordb` namespace with Pod Security Standards (baseline)
- Generate and store a password in Vault (or Kubernetes Secret)
- Deploy FalkorDB using the custom Helm chart
- Optionally enable Prometheus monitoring
## Prerequisites
- Kubernetes cluster with Longhorn storage
- For secret management: Vault and External Secrets Operator (optional but recommended)
- For monitoring: kube-prometheus-stack (optional)
## Connection Information
| Property | Value |
| -------- | ------------------------------------- |
| Host | `falkordb.falkordb.svc.cluster.local` |
| Port | `6379` |
| Protocol | Redis (Bolt not supported) |
## Usage
### Get Password
```bash
just falkordb::get-password
```
### Health Check
Requires [telepresence](https://www.telepresence.io/) connection:
```bash
telepresence connect
just falkordb::health-check
```
### Test Graph Operations
Run a basic test that creates nodes, relationships, and queries:
```bash
just falkordb::test
```
### Redis CLI
Connect directly using redis-cli:
```bash
PASSWORD=$(just falkordb::get-password)
redis-cli -h falkordb.falkordb.svc.cluster.local -p 6379 -a "$PASSWORD"
```
### Cypher Queries
FalkorDB uses OpenCypher query language via Redis commands:
```bash
# Create a node
redis-cli -a "$PASSWORD" GRAPH.QUERY mygraph "CREATE (:Person {name: 'Alice', age: 30})"
# Create a relationship
redis-cli -a "$PASSWORD" GRAPH.QUERY mygraph \
"MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) CREATE (a)-[:KNOWS]->(b)"
# Query the graph
redis-cli -a "$PASSWORD" GRAPH.QUERY mygraph \
"MATCH (p:Person)-[:KNOWS]->(friend) RETURN p.name, friend.name"
# Delete a graph
redis-cli -a "$PASSWORD" GRAPH.DELETE mygraph
```
### Python Client
```python
from falkordb import FalkorDB
db = FalkorDB(
host='falkordb.falkordb.svc.cluster.local',
port=6379,
password='<password>'
)
graph = db.select_graph('knowledge')
# Create nodes
graph.query("CREATE (:Concept {name: 'Machine Learning'})")
graph.query("CREATE (:Concept {name: 'Neural Networks'})")
# Create relationship
graph.query("""
MATCH (a:Concept {name: 'Neural Networks'}), (b:Concept {name: 'Machine Learning'})
CREATE (a)-[:PART_OF]->(b)
""")
# Query
result = graph.query("MATCH (c:Concept) RETURN c.name")
for record in result.result_set:
print(record)
```
## Configuration
### Environment Variables
| Variable | Default | Description |
| ---------------------- | ----------- | ----------------------- |
| `FALKORDB_NAMESPACE` | `falkordb` | Kubernetes namespace |
| `FALKORDB_VERSION` | `v4.14.8` | FalkorDB image version |
| `FALKORDB_STORAGE_SIZE`| `8Gi` | Persistent volume size |
### Pod Security Standards
The namespace is configured with:
- `enforce=baseline` - Required for FalkorDB (runs as root)
- `warn=restricted` - Shows warnings for restricted violations
## Cognee Integration
FalkorDB can serve as both graph and vector store for [Cognee](https://github.com/topoteretes/cognee), enabling knowledge graph construction and RAG without separate vector database.
### Configuration
```bash
# .env for Cognee
GRAPH_DATABASE_PROVIDER=falkordb
GRAPH_DATABASE_URL=falkordb.falkordb.svc.cluster.local
GRAPH_DATABASE_PORT=6379
VECTOR_DB_PROVIDER=falkordb
VECTOR_DB_URL=falkordb.falkordb.svc.cluster.local
VECTOR_DB_PORT=6379
```
### Usage with Cognee
```python
import cognee
# Add documents
await cognee.add("documents/", dataset_name="knowledge_base")
# Generate knowledge graph (automatic)
await cognee.cognify()
# Search with RAG
results = await cognee.search("What is the relationship between X and Y?")
```
## Management
### Uninstall
```bash
just falkordb::uninstall
```
### Cleanup Vault Secrets
```bash
just falkordb::cleanup
```
### Available Commands
```bash
just falkordb # List all commands
just falkordb::install # Install FalkorDB
just falkordb::uninstall # Uninstall FalkorDB
just falkordb::get-password # Get password
just falkordb::health-check # Check health (requires telepresence)
just falkordb::test # Run graph operation tests
just falkordb::cleanup # Clean up Vault secrets
```
## Troubleshooting
### Pod Not Starting
Check pod status and logs:
```bash
kubectl get pods -n falkordb
kubectl logs falkordb-0 -n falkordb
kubectl describe pod falkordb-0 -n falkordb
```
### Authentication Issues
Verify password is correctly configured:
```bash
# Check secret exists
kubectl get secret falkordb-password -n falkordb
# Test authentication from within cluster
kubectl exec falkordb-0 -n falkordb -- redis-cli -a "$PASSWORD" PING
```
### Connection Refused
Ensure service is running:
```bash
kubectl get svc -n falkordb
```
For external access, use telepresence or port-forward:
```bash
kubectl port-forward svc/falkordb -n falkordb 6379:6379
```
### Memory Issues
FalkorDB stores graphs in memory. Monitor usage:
```bash
kubectl top pod -n falkordb
```
If running out of memory, increase limits in `falkordb-values.gomplate.yaml`.
## References
- [FalkorDB Documentation](https://docs.falkordb.com/)
- [FalkorDB GitHub](https://github.com/FalkorDB/FalkorDB)
- [OpenCypher Query Language](https://opencypher.org/)
- [Cognee Documentation](https://docs.cognee.ai/)

View File

@@ -0,0 +1,18 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: falkordb-password-external-secret
namespace: {{ .Env.FALKORDB_NAMESPACE }}
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-secret-store
kind: ClusterSecretStore
target:
name: falkordb-password
creationPolicy: Owner
data:
- secretKey: redis-password
remoteRef:
key: falkordb/auth
property: password

View File

@@ -0,0 +1,19 @@
image:
tag: {{ .Env.FALKORDB_VERSION }}
auth:
enabled: true
existingSecret: falkordb-password
existingSecretPasswordKey: redis-password
persistence:
enabled: true
size: {{ .Env.FALKORDB_STORAGE_SIZE }}
resources:
requests:
cpu: 25m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi

193
falkordb/justfile Normal file
View File

@@ -0,0 +1,193 @@
set fallback := true
export FALKORDB_NAMESPACE := env("FALKORDB_NAMESPACE", "falkordb")
export FALKORDB_VERSION := env("FALKORDB_VERSION", "v4.14.8")
export FALKORDB_STORAGE_SIZE := env("FALKORDB_STORAGE_SIZE", "8Gi")
export EXTERNAL_SECRETS_NAMESPACE := env("EXTERNAL_SECRETS_NAMESPACE", "external-secrets")
export PROMETHEUS_NAMESPACE := env("PROMETHEUS_NAMESPACE", "monitoring")
export MONITORING_ENABLED := env("MONITORING_ENABLED", "")
[private]
default:
@just --list --unsorted --list-submodules
# Create FalkorDB namespace
create-namespace:
@kubectl get namespace ${FALKORDB_NAMESPACE} &>/dev/null || \
kubectl create namespace ${FALKORDB_NAMESPACE}
@kubectl label namespace ${FALKORDB_NAMESPACE} \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/warn=restricted \
--overwrite
# Delete FalkorDB namespace
delete-namespace:
@kubectl delete namespace ${FALKORDB_NAMESPACE} --ignore-not-found
# Create FalkorDB password secret
create-password-secret:
#!/bin/bash
set -euo pipefail
echo "Setting up FalkorDB password..."
PASSWORD=$(just utils::random-password)
if helm status external-secrets -n ${EXTERNAL_SECRETS_NAMESPACE} &>/dev/null; then
echo "External Secrets available. Storing password in Vault and creating ExternalSecret..."
just vault::put falkordb/auth password="$PASSWORD"
gomplate -f falkordb-password-external-secret.gomplate.yaml -o falkordb-password-external-secret.yaml
kubectl apply -f falkordb-password-external-secret.yaml
echo "Waiting for password secret to be ready..."
kubectl wait --for=condition=Ready externalsecret/falkordb-password-external-secret \
-n ${FALKORDB_NAMESPACE} --timeout=60s
else
echo "External Secrets not available. Creating Kubernetes Secret directly..."
kubectl delete secret falkordb-password -n ${FALKORDB_NAMESPACE} --ignore-not-found
kubectl create secret generic falkordb-password -n ${FALKORDB_NAMESPACE} \
--from-literal=redis-password="$PASSWORD"
if helm status vault -n vault &>/dev/null; then
just vault::put falkordb/auth password="$PASSWORD"
fi
fi
echo "FalkorDB password setup completed"
# Delete FalkorDB password secret
delete-password-secret:
@kubectl delete secret falkordb-password -n ${FALKORDB_NAMESPACE} --ignore-not-found
@kubectl delete externalsecret falkordb-password-external-secret -n ${FALKORDB_NAMESPACE} --ignore-not-found
# Install FalkorDB
install:
#!/bin/bash
set -euo pipefail
just create-namespace
just create-password-secret
METRICS_ENABLED="false"
SERVICEMONITOR_ENABLED="false"
if helm status kube-prometheus-stack -n ${PROMETHEUS_NAMESPACE} &>/dev/null; then
if [ -z "${MONITORING_ENABLED}" ]; then
if gum confirm "Enable Prometheus monitoring?"; then
MONITORING_ENABLED="true"
else
MONITORING_ENABLED="false"
fi
fi
if [ "${MONITORING_ENABLED}" = "true" ]; then
METRICS_ENABLED="true"
SERVICEMONITOR_ENABLED="true"
kubectl label namespace ${FALKORDB_NAMESPACE} buun.channel/enable-monitoring=true --overwrite
fi
fi
gomplate -f falkordb-values.gomplate.yaml -o falkordb-values.yaml
helm upgrade --install falkordb ../charts/falkordb \
-n ${FALKORDB_NAMESPACE} --create-namespace --wait \
-f falkordb-values.yaml \
--set metrics.enabled=${METRICS_ENABLED} \
--set metrics.serviceMonitor.enabled=${SERVICEMONITOR_ENABLED} \
--set metrics.serviceMonitor.labels.release=kube-prometheus-stack
echo ""
echo "FalkorDB installed successfully!"
echo "Connection: falkordb.${FALKORDB_NAMESPACE}.svc.cluster.local:6379"
# Uninstall FalkorDB
uninstall:
#!/bin/bash
set -euo pipefail
if gum confirm "Are you sure you want to uninstall FalkorDB?"; then
helm uninstall falkordb -n ${FALKORDB_NAMESPACE} --wait --ignore-not-found
just delete-password-secret
just delete-namespace
echo "FalkorDB uninstalled"
else
echo "Uninstall cancelled"
fi
# Get FalkorDB password
get-password:
@kubectl get secret falkordb-password -n ${FALKORDB_NAMESPACE} \
-o jsonpath="{.data.redis-password}" | base64 -d
@echo
# Get FalkorDB service URL
[private]
get-service-url:
@echo "redis://falkordb.${FALKORDB_NAMESPACE}.svc.cluster.local:6379"
# Check if telepresence is connected
[private]
check-telepresence:
#!/bin/bash
set -euo pipefail
if ! command -v telepresence &>/dev/null; then
echo "Error: telepresence is not installed" >&2
exit 1
fi
if ! telepresence status &>/dev/null; then
echo "Error: telepresence is not connected" >&2
echo "Please run: telepresence connect" >&2
exit 1
fi
# Check FalkorDB health
health-check:
#!/bin/bash
set -euo pipefail
just check-telepresence
PASSWORD=$(just get-password)
HOST="falkordb.${FALKORDB_NAMESPACE}.svc.cluster.local"
echo "Checking FalkorDB health at ${HOST}:6379..."
redis-cli -h ${HOST} -p 6379 -a "${PASSWORD}" --no-auth-warning PING
# Test FalkorDB with basic graph operations
test:
#!/bin/bash
set -euo pipefail
just check-telepresence
PASSWORD=$(just get-password)
HOST="falkordb.${FALKORDB_NAMESPACE}.svc.cluster.local"
GRAPH_NAME="test_graph_$(date +%s)"
echo "Testing FalkorDB at ${HOST}:6379"
echo "Using graph: ${GRAPH_NAME}"
echo
echo "1. Creating nodes..."
redis-cli -h ${HOST} -p 6379 -a "${PASSWORD}" --no-auth-warning \
GRAPH.QUERY ${GRAPH_NAME} "CREATE (:Person {name: 'Alice', age: 30})"
redis-cli -h ${HOST} -p 6379 -a "${PASSWORD}" --no-auth-warning \
GRAPH.QUERY ${GRAPH_NAME} "CREATE (:Person {name: 'Bob', age: 25})"
echo
echo "2. Creating relationship..."
redis-cli -h ${HOST} -p 6379 -a "${PASSWORD}" --no-auth-warning \
GRAPH.QUERY ${GRAPH_NAME} "MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) CREATE (a)-[:KNOWS {since: 2020}]->(b)"
echo
echo "3. Querying graph..."
redis-cli -h ${HOST} -p 6379 -a "${PASSWORD}" --no-auth-warning \
GRAPH.QUERY ${GRAPH_NAME} "MATCH (p:Person)-[:KNOWS]->(friend) RETURN p.name, friend.name"
echo
echo "4. Deleting test graph..."
redis-cli -h ${HOST} -p 6379 -a "${PASSWORD}" --no-auth-warning \
GRAPH.DELETE ${GRAPH_NAME}
echo
echo "Test completed successfully!"
# Clean up FalkorDB resources
cleanup:
#!/bin/bash
set -euo pipefail
echo "This will delete all FalkorDB resources and secrets."
if gum confirm "Are you sure you want to proceed?"; then
echo "Cleaning up FalkorDB resources..."
just vault::delete falkordb/auth || true
echo "Cleanup completed"
else
echo "Cleanup cancelled"
fi