975 lines
20 KiB
Markdown
975 lines
20 KiB
Markdown
|
|
# SurrealDB 2.3 Setup & Deployment Guide
|
||
|
|
|
||
|
|
**Version**: 2.3
|
||
|
|
**Status**: Production Ready
|
||
|
|
**Last Updated**: November 15, 2025
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
This guide covers deploying and configuring SurrealDB 2.3 for the syntaxis project in three deployment contexts:
|
||
|
|
|
||
|
|
1. **Local Development** - Server mode for development/testing
|
||
|
|
2. **Docker Container** - Production containerized deployment
|
||
|
|
3. **Kubernetes** - Enterprise orchestration with HA/scaling
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Part 1: Local Development Setup
|
||
|
|
|
||
|
|
### 1.1 Install SurrealDB
|
||
|
|
|
||
|
|
#### macOS (via Homebrew)
|
||
|
|
```bash
|
||
|
|
brew install surrealdb
|
||
|
|
# Verify installation
|
||
|
|
surreal version
|
||
|
|
# Output: surrealdb version X.X.X
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Linux (via Cargo)
|
||
|
|
```bash
|
||
|
|
cargo install surreal
|
||
|
|
# Or download binary from https://github.com/surrealdb/surrealdb/releases
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Windows (via Chocolatey)
|
||
|
|
```powershell
|
||
|
|
choco install surrealdb
|
||
|
|
```
|
||
|
|
|
||
|
|
### 1.2 Start SurrealDB Server (Local Development)
|
||
|
|
|
||
|
|
#### Basic In-Memory Server
|
||
|
|
```bash
|
||
|
|
# Start SurrealDB listening on localhost:8000
|
||
|
|
surreal start --bind 127.0.0.1:8000 memory
|
||
|
|
|
||
|
|
# Surreal outputs:
|
||
|
|
# 2025-11-15T10:00:00.000Z INFO surreal::cli: Starting SurrealDB server...
|
||
|
|
# 2025-11-15T10:00:00.123Z INFO surreal::net: Database server now listening on 0.0.0.0:8000
|
||
|
|
```
|
||
|
|
|
||
|
|
#### File-Based RocksDB Server
|
||
|
|
```bash
|
||
|
|
# Persistent storage in local directory
|
||
|
|
surreal start --bind 127.0.0.1:8000 file:///tmp/surrealdb.db
|
||
|
|
|
||
|
|
# Or with expanded home path
|
||
|
|
surreal start --bind 127.0.0.1:8000 file://~/.local/share/surrealdb/workspace.db
|
||
|
|
```
|
||
|
|
|
||
|
|
#### With Authentication
|
||
|
|
```bash
|
||
|
|
# Start with credentials (recommended for production-like testing)
|
||
|
|
surreal start \
|
||
|
|
--bind 127.0.0.1:8000 \
|
||
|
|
--username admin \
|
||
|
|
--password secure_password_123 \
|
||
|
|
file:///tmp/surrealdb.db
|
||
|
|
```
|
||
|
|
|
||
|
|
### 1.3 Configure Application to Connect
|
||
|
|
|
||
|
|
**Configuration File**: `configs/database.toml`
|
||
|
|
```toml
|
||
|
|
# Database Configuration - syntaxis
|
||
|
|
engine = "surrealdb" # or "sqlite" for testing
|
||
|
|
|
||
|
|
# SQLite Configuration (Default for development)
|
||
|
|
[sqlite]
|
||
|
|
path = "~/.local/share/core/workspace.db"
|
||
|
|
max_connections = 5
|
||
|
|
timeout_secs = 30
|
||
|
|
wal_mode = true
|
||
|
|
pragma_synchronous = "NORMAL"
|
||
|
|
pragma_cache_size = 2000
|
||
|
|
|
||
|
|
# SurrealDB Configuration (Optional - requires server running)
|
||
|
|
[surrealdb]
|
||
|
|
# Connection modes (choose one)
|
||
|
|
# In-Memory (embedded, no server needed):
|
||
|
|
url = "mem://"
|
||
|
|
|
||
|
|
# File-based (embedded RocksDB, no server needed):
|
||
|
|
# url = "file:///tmp/surrealdb.db"
|
||
|
|
|
||
|
|
# Remote Server (requires surreal start):
|
||
|
|
url = "ws://localhost:8000"
|
||
|
|
|
||
|
|
# Optional: ws:// for WebSocket or http:// for HTTP
|
||
|
|
# url = "http://localhost:8000"
|
||
|
|
|
||
|
|
# Namespace and Database selection
|
||
|
|
namespace = "syntaxis"
|
||
|
|
database = "projects"
|
||
|
|
|
||
|
|
# Authentication (if server started with --username/--password)
|
||
|
|
# username = "admin"
|
||
|
|
# password = "secure_password_123"
|
||
|
|
|
||
|
|
# Connection pooling
|
||
|
|
max_connections = 10
|
||
|
|
timeout_secs = 30
|
||
|
|
|
||
|
|
# TLS Configuration (for production)
|
||
|
|
# tls_enabled = true
|
||
|
|
# tls_ca_cert = "/path/to/ca.pem"
|
||
|
|
# tls_client_cert = "/path/to/client.pem"
|
||
|
|
# tls_client_key = "/path/to/client.key"
|
||
|
|
```
|
||
|
|
|
||
|
|
### 1.4 Enable SurrealDB in Application
|
||
|
|
|
||
|
|
**In Rust Code** (syntaxis-core):
|
||
|
|
```rust
|
||
|
|
use workspace_core::persistence::{Database, SurrealDatabase};
|
||
|
|
|
||
|
|
#[tokio::main]
|
||
|
|
async fn main() -> Result<()> {
|
||
|
|
// Embedded mode (no server required)
|
||
|
|
let db = SurrealDatabase::new_memory().await?;
|
||
|
|
// or
|
||
|
|
let db = SurrealDatabase::new_file("/tmp/surrealdb.db").await?;
|
||
|
|
|
||
|
|
// Server mode (requires `surreal start` running)
|
||
|
|
// let db = SurrealDatabase::new_server(
|
||
|
|
// "ws://localhost:8000",
|
||
|
|
// "syntaxis",
|
||
|
|
// "projects",
|
||
|
|
// None, // username
|
||
|
|
// None, // password
|
||
|
|
// ).await?;
|
||
|
|
|
||
|
|
Ok(())
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 1.5 Verify Connection
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Test if server is running
|
||
|
|
curl http://localhost:8000/health
|
||
|
|
# Expected: {"status":"ok"}
|
||
|
|
|
||
|
|
# Check with surreal CLI
|
||
|
|
surreal sql --endpoint ws://localhost:8000
|
||
|
|
# Then at prompt:
|
||
|
|
# > SELECT 1;
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Part 2: Docker Container Deployment
|
||
|
|
|
||
|
|
### 2.1 Create Dockerfile
|
||
|
|
|
||
|
|
**File**: `Dockerfile.surrealdb`
|
||
|
|
```dockerfile
|
||
|
|
# Multi-stage build for minimal image size
|
||
|
|
FROM surrealdb/surrealdb:latest AS surrealdb
|
||
|
|
|
||
|
|
# Production runtime image
|
||
|
|
FROM debian:bookworm-slim
|
||
|
|
|
||
|
|
# Install minimal dependencies
|
||
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||
|
|
ca-certificates \
|
||
|
|
curl \
|
||
|
|
&& rm -rf /var/lib/apt/lists/*
|
||
|
|
|
||
|
|
# Copy SurrealDB binary from builder
|
||
|
|
COPY --from=surrealdb /usr/local/bin/surreal /usr/local/bin/surreal
|
||
|
|
|
||
|
|
# Create data directory
|
||
|
|
RUN mkdir -p /data && chmod 755 /data
|
||
|
|
|
||
|
|
# Health check
|
||
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||
|
|
CMD curl -f http://localhost:8000/health || exit 1
|
||
|
|
|
||
|
|
# Expose port
|
||
|
|
EXPOSE 8000
|
||
|
|
|
||
|
|
# Labels for container metadata
|
||
|
|
LABEL maintainer="syntaxis"
|
||
|
|
LABEL version="2.3"
|
||
|
|
LABEL description="SurrealDB 2.3 for syntaxis"
|
||
|
|
|
||
|
|
# Run SurrealDB
|
||
|
|
ENTRYPOINT ["surreal", "start"]
|
||
|
|
CMD ["--bind", "0.0.0.0:8000", "file:///data/surrealdb.db"]
|
||
|
|
|
||
|
|
# Volume for data persistence
|
||
|
|
VOLUME ["/data"]
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.2 Docker Compose Configuration
|
||
|
|
|
||
|
|
**File**: `docker-compose.surrealdb.yml`
|
||
|
|
```yaml
|
||
|
|
version: "3.9"
|
||
|
|
|
||
|
|
services:
|
||
|
|
surrealdb:
|
||
|
|
# Option 1: Use official SurrealDB image
|
||
|
|
image: surrealdb/surrealdb:latest
|
||
|
|
|
||
|
|
# Option 2: Build from local Dockerfile
|
||
|
|
# build:
|
||
|
|
# context: .
|
||
|
|
# dockerfile: Dockerfile.surrealdb
|
||
|
|
|
||
|
|
container_name: workspace-surrealdb
|
||
|
|
|
||
|
|
# Port mapping
|
||
|
|
ports:
|
||
|
|
- "8000:8000"
|
||
|
|
|
||
|
|
# Volume for persistent data
|
||
|
|
volumes:
|
||
|
|
- surrealdb-data:/data
|
||
|
|
|
||
|
|
# Environment variables
|
||
|
|
environment:
|
||
|
|
# SURREAL_LOG: debug # Enable debug logging
|
||
|
|
TZ: UTC
|
||
|
|
|
||
|
|
# Command override
|
||
|
|
command:
|
||
|
|
- start
|
||
|
|
- --bind
|
||
|
|
- "0.0.0.0:8000"
|
||
|
|
- --username
|
||
|
|
- "admin"
|
||
|
|
- --password
|
||
|
|
- "workspace_password_123"
|
||
|
|
- file:///data/surrealdb.db
|
||
|
|
|
||
|
|
# Resource limits
|
||
|
|
deploy:
|
||
|
|
resources:
|
||
|
|
limits:
|
||
|
|
cpus: "2"
|
||
|
|
memory: 2G
|
||
|
|
reservations:
|
||
|
|
cpus: "1"
|
||
|
|
memory: 1G
|
||
|
|
|
||
|
|
# Restart policy
|
||
|
|
restart: unless-stopped
|
||
|
|
|
||
|
|
# Health check
|
||
|
|
healthcheck:
|
||
|
|
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
||
|
|
interval: 30s
|
||
|
|
timeout: 10s
|
||
|
|
retries: 3
|
||
|
|
start_period: 5s
|
||
|
|
|
||
|
|
# Network
|
||
|
|
networks:
|
||
|
|
- workspace-net
|
||
|
|
|
||
|
|
# Optional: Redis cache layer (for performance)
|
||
|
|
redis:
|
||
|
|
image: redis:7-alpine
|
||
|
|
container_name: workspace-redis
|
||
|
|
ports:
|
||
|
|
- "6379:6379"
|
||
|
|
volumes:
|
||
|
|
- redis-data:/data
|
||
|
|
restart: unless-stopped
|
||
|
|
networks:
|
||
|
|
- workspace-net
|
||
|
|
|
||
|
|
volumes:
|
||
|
|
surrealdb-data:
|
||
|
|
driver: local
|
||
|
|
redis-data:
|
||
|
|
driver: local
|
||
|
|
|
||
|
|
networks:
|
||
|
|
workspace-net:
|
||
|
|
driver: bridge
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.3 Docker Compose Usage
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Start SurrealDB
|
||
|
|
docker-compose -f docker-compose.surrealdb.yml up -d
|
||
|
|
|
||
|
|
# View logs
|
||
|
|
docker-compose -f docker-compose.surrealdb.yml logs -f surrealdb
|
||
|
|
|
||
|
|
# Connect to database
|
||
|
|
docker-compose -f docker-compose.surrealdb.yml exec surrealdb \
|
||
|
|
surreal sql --endpoint ws://localhost:8000 \
|
||
|
|
--username admin \
|
||
|
|
--password workspace_password_123
|
||
|
|
|
||
|
|
# Stop services
|
||
|
|
docker-compose -f docker-compose.surrealdb.yml down
|
||
|
|
|
||
|
|
# Remove volumes (caution: deletes data)
|
||
|
|
docker-compose -f docker-compose.surrealdb.yml down -v
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.4 Multi-Environment Compose Override
|
||
|
|
|
||
|
|
**File**: `docker-compose.override.yml` (local development)
|
||
|
|
```yaml
|
||
|
|
version: "3.9"
|
||
|
|
|
||
|
|
services:
|
||
|
|
surrealdb:
|
||
|
|
# Expose debug port
|
||
|
|
ports:
|
||
|
|
- "8000:8000"
|
||
|
|
- "8001:8001" # Debug port
|
||
|
|
|
||
|
|
# Use memory backend for faster development
|
||
|
|
command:
|
||
|
|
- start
|
||
|
|
- --bind
|
||
|
|
- "0.0.0.0:8000"
|
||
|
|
- memory
|
||
|
|
|
||
|
|
# Less resource restriction for dev
|
||
|
|
deploy:
|
||
|
|
resources:
|
||
|
|
limits:
|
||
|
|
cpus: "4"
|
||
|
|
memory: 4G
|
||
|
|
```
|
||
|
|
|
||
|
|
**File**: `docker-compose.prod.yml` (production)
|
||
|
|
```yaml
|
||
|
|
version: "3.9"
|
||
|
|
|
||
|
|
services:
|
||
|
|
surrealdb:
|
||
|
|
image: surrealdb/surrealdb:2.3.0 # Pin version for prod
|
||
|
|
|
||
|
|
# Stricter resource limits
|
||
|
|
deploy:
|
||
|
|
resources:
|
||
|
|
limits:
|
||
|
|
cpus: "1"
|
||
|
|
memory: 1.5G
|
||
|
|
reservations:
|
||
|
|
cpus: "0.5"
|
||
|
|
memory: 1G
|
||
|
|
|
||
|
|
# Stricter restart policy
|
||
|
|
restart: on-failure:5
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Part 3: Kubernetes Deployment
|
||
|
|
|
||
|
|
### 3.1 Kubernetes ConfigMap
|
||
|
|
|
||
|
|
**File**: `k8s/surrealdb-config.yaml`
|
||
|
|
```yaml
|
||
|
|
apiVersion: v1
|
||
|
|
kind: ConfigMap
|
||
|
|
metadata:
|
||
|
|
name: surrealdb-config
|
||
|
|
namespace: workspace
|
||
|
|
spec:
|
||
|
|
database.toml: |
|
||
|
|
engine = "surrealdb"
|
||
|
|
|
||
|
|
[surrealdb]
|
||
|
|
url = "ws://surrealdb:8000"
|
||
|
|
namespace = "syntaxis"
|
||
|
|
database = "projects"
|
||
|
|
max_connections = 20
|
||
|
|
timeout_secs = 60
|
||
|
|
|
||
|
|
init-schema.sql: |
|
||
|
|
-- SurrealDB schema initialization
|
||
|
|
DEFINE TABLE projects SCHEMAFULL;
|
||
|
|
DEFINE TABLE checklist_items SCHEMAFULL;
|
||
|
|
DEFINE TABLE phase_transitions SCHEMAFULL;
|
||
|
|
DEFINE TABLE security_assessments SCHEMAFULL;
|
||
|
|
DEFINE TABLE phase_history SCHEMAFULL;
|
||
|
|
DEFINE TABLE tool_configurations SCHEMAFULL;
|
||
|
|
DEFINE TABLE tool_dependencies SCHEMAFULL;
|
||
|
|
DEFINE TABLE security_assessment_details SCHEMAFULL;
|
||
|
|
DEFINE TABLE team_members SCHEMAFULL;
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.2 Kubernetes Secret
|
||
|
|
|
||
|
|
**File**: `k8s/surrealdb-secret.yaml`
|
||
|
|
```yaml
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Secret
|
||
|
|
metadata:
|
||
|
|
name: surrealdb-credentials
|
||
|
|
namespace: workspace
|
||
|
|
type: Opaque
|
||
|
|
stringData:
|
||
|
|
username: "admin"
|
||
|
|
password: "secure_kubernetes_password_here_at_least_32_chars_minimum"
|
||
|
|
# Note: In production, use external secret management (Vault, AWS Secrets Manager, etc)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.3 SurrealDB StatefulSet
|
||
|
|
|
||
|
|
**File**: `k8s/surrealdb-statefulset.yaml`
|
||
|
|
```yaml
|
||
|
|
apiVersion: apps/v1
|
||
|
|
kind: StatefulSet
|
||
|
|
metadata:
|
||
|
|
name: surrealdb
|
||
|
|
namespace: workspace
|
||
|
|
labels:
|
||
|
|
app: surrealdb
|
||
|
|
version: "2.3"
|
||
|
|
spec:
|
||
|
|
serviceName: surrealdb
|
||
|
|
replicas: 1 # For HA, scale to 3 with clustering (future)
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app: surrealdb
|
||
|
|
template:
|
||
|
|
metadata:
|
||
|
|
labels:
|
||
|
|
app: surrealdb
|
||
|
|
version: "2.3"
|
||
|
|
spec:
|
||
|
|
# Node affinity for stability
|
||
|
|
affinity:
|
||
|
|
nodeAffinity:
|
||
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||
|
|
- weight: 100
|
||
|
|
preference:
|
||
|
|
matchExpressions:
|
||
|
|
- key: node-type
|
||
|
|
operator: In
|
||
|
|
values: ["database"]
|
||
|
|
|
||
|
|
# Security context
|
||
|
|
securityContext:
|
||
|
|
runAsNonRoot: true
|
||
|
|
runAsUser: 999
|
||
|
|
fsGroup: 999
|
||
|
|
|
||
|
|
# Init containers for schema setup
|
||
|
|
initContainers:
|
||
|
|
- name: init-schema
|
||
|
|
image: surrealdb/surrealdb:2.3
|
||
|
|
command:
|
||
|
|
- /bin/sh
|
||
|
|
- -c
|
||
|
|
- |
|
||
|
|
# Wait for SurrealDB to be ready
|
||
|
|
surreal sql \
|
||
|
|
--endpoint ws://localhost:8000 \
|
||
|
|
--username admin \
|
||
|
|
--password $SURREALDB_PASSWORD \
|
||
|
|
< /config/init-schema.sql
|
||
|
|
env:
|
||
|
|
- name: SURREALDB_PASSWORD
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: surrealdb-credentials
|
||
|
|
key: password
|
||
|
|
volumeMounts:
|
||
|
|
- name: config
|
||
|
|
mountPath: /config
|
||
|
|
|
||
|
|
containers:
|
||
|
|
- name: surrealdb
|
||
|
|
image: surrealdb/surrealdb:2.3
|
||
|
|
imagePullPolicy: IfNotPresent
|
||
|
|
|
||
|
|
# Resource requests and limits
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
cpu: "500m"
|
||
|
|
memory: "512Mi"
|
||
|
|
limits:
|
||
|
|
cpu: "2000m"
|
||
|
|
memory: "2Gi"
|
||
|
|
|
||
|
|
# Port exposure
|
||
|
|
ports:
|
||
|
|
- name: http
|
||
|
|
containerPort: 8000
|
||
|
|
protocol: TCP
|
||
|
|
|
||
|
|
# Environment variables
|
||
|
|
env:
|
||
|
|
- name: SURREALDB_USER
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: surrealdb-credentials
|
||
|
|
key: username
|
||
|
|
- name: SURREALDB_PASS
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: surrealdb-credentials
|
||
|
|
key: password
|
||
|
|
|
||
|
|
# Startup probe (for slow startup)
|
||
|
|
startupProbe:
|
||
|
|
httpGet:
|
||
|
|
path: /health
|
||
|
|
port: 8000
|
||
|
|
initialDelaySeconds: 5
|
||
|
|
periodSeconds: 10
|
||
|
|
timeoutSeconds: 5
|
||
|
|
successThreshold: 1
|
||
|
|
failureThreshold: 30
|
||
|
|
|
||
|
|
# Liveness probe
|
||
|
|
livenessProbe:
|
||
|
|
httpGet:
|
||
|
|
path: /health
|
||
|
|
port: 8000
|
||
|
|
initialDelaySeconds: 10
|
||
|
|
periodSeconds: 30
|
||
|
|
timeoutSeconds: 5
|
||
|
|
successThreshold: 1
|
||
|
|
failureThreshold: 3
|
||
|
|
|
||
|
|
# Readiness probe
|
||
|
|
readinessProbe:
|
||
|
|
httpGet:
|
||
|
|
path: /health
|
||
|
|
port: 8000
|
||
|
|
initialDelaySeconds: 5
|
||
|
|
periodSeconds: 10
|
||
|
|
timeoutSeconds: 5
|
||
|
|
successThreshold: 1
|
||
|
|
failureThreshold: 3
|
||
|
|
|
||
|
|
# Volume mounts
|
||
|
|
volumeMounts:
|
||
|
|
- name: config
|
||
|
|
mountPath: /etc/surrealdb
|
||
|
|
- name: data
|
||
|
|
mountPath: /data
|
||
|
|
|
||
|
|
# Security context for container
|
||
|
|
securityContext:
|
||
|
|
allowPrivilegeEscalation: false
|
||
|
|
readOnlyRootFilesystem: true
|
||
|
|
capabilities:
|
||
|
|
drop:
|
||
|
|
- ALL
|
||
|
|
|
||
|
|
# Startup command
|
||
|
|
args:
|
||
|
|
- start
|
||
|
|
- --bind
|
||
|
|
- 0.0.0.0:8000
|
||
|
|
- --username
|
||
|
|
- $(SURREALDB_USER)
|
||
|
|
- --password
|
||
|
|
- $(SURREALDB_PASS)
|
||
|
|
- file:///data/surrealdb.db
|
||
|
|
|
||
|
|
# Volumes
|
||
|
|
volumes:
|
||
|
|
- name: config
|
||
|
|
configMap:
|
||
|
|
name: surrealdb-config
|
||
|
|
|
||
|
|
# Persistent volume claim
|
||
|
|
volumeClaimTemplates:
|
||
|
|
- metadata:
|
||
|
|
name: data
|
||
|
|
spec:
|
||
|
|
accessModes: ["ReadWriteOnce"]
|
||
|
|
storageClassName: standard # Change to appropriate storage class
|
||
|
|
resources:
|
||
|
|
requests:
|
||
|
|
storage: 10Gi # Adjust based on data needs
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.4 Kubernetes Service
|
||
|
|
|
||
|
|
**File**: `k8s/surrealdb-service.yaml`
|
||
|
|
```yaml
|
||
|
|
---
|
||
|
|
# Headless service for StatefulSet
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: surrealdb
|
||
|
|
namespace: workspace
|
||
|
|
labels:
|
||
|
|
app: surrealdb
|
||
|
|
spec:
|
||
|
|
clusterIP: None # Headless service
|
||
|
|
selector:
|
||
|
|
app: surrealdb
|
||
|
|
ports:
|
||
|
|
- name: http
|
||
|
|
port: 8000
|
||
|
|
targetPort: 8000
|
||
|
|
protocol: TCP
|
||
|
|
|
||
|
|
---
|
||
|
|
# Load balancer service for external access (optional)
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: surrealdb-lb
|
||
|
|
namespace: workspace
|
||
|
|
labels:
|
||
|
|
app: surrealdb
|
||
|
|
spec:
|
||
|
|
type: LoadBalancer
|
||
|
|
selector:
|
||
|
|
app: surrealdb
|
||
|
|
ports:
|
||
|
|
- name: http
|
||
|
|
port: 8000
|
||
|
|
targetPort: 8000
|
||
|
|
protocol: TCP
|
||
|
|
|
||
|
|
---
|
||
|
|
# ClusterIP for internal access
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Service
|
||
|
|
metadata:
|
||
|
|
name: surrealdb-internal
|
||
|
|
namespace: workspace
|
||
|
|
labels:
|
||
|
|
app: surrealdb
|
||
|
|
spec:
|
||
|
|
type: ClusterIP
|
||
|
|
selector:
|
||
|
|
app: surrealdb
|
||
|
|
ports:
|
||
|
|
- name: http
|
||
|
|
port: 8000
|
||
|
|
targetPort: 8000
|
||
|
|
protocol: TCP
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.5 Kubernetes Deployment Script
|
||
|
|
|
||
|
|
**File**: `k8s/deploy.sh`
|
||
|
|
```bash
|
||
|
|
#!/bin/bash
|
||
|
|
set -e
|
||
|
|
|
||
|
|
NAMESPACE="workspace"
|
||
|
|
CONTEXT="kubernetes-cluster" # Change to your context
|
||
|
|
|
||
|
|
echo "📦 Deploying SurrealDB to Kubernetes..."
|
||
|
|
|
||
|
|
# Switch context
|
||
|
|
kubectl config use-context $CONTEXT
|
||
|
|
echo "✓ Using context: $CONTEXT"
|
||
|
|
|
||
|
|
# Create namespace if needed
|
||
|
|
kubectl create namespace $NAMESPACE --dry-run=client -o yaml | kubectl apply -f -
|
||
|
|
echo "✓ Namespace: $NAMESPACE"
|
||
|
|
|
||
|
|
# Apply resources
|
||
|
|
echo "📝 Applying ConfigMap..."
|
||
|
|
kubectl apply -f k8s/surrealdb-config.yaml
|
||
|
|
|
||
|
|
echo "🔐 Applying Secrets..."
|
||
|
|
kubectl apply -f k8s/surrealdb-secret.yaml
|
||
|
|
|
||
|
|
echo "📊 Applying StatefulSet..."
|
||
|
|
kubectl apply -f k8s/surrealdb-statefulset.yaml
|
||
|
|
|
||
|
|
echo "🌐 Applying Services..."
|
||
|
|
kubectl apply -f k8s/surrealdb-service.yaml
|
||
|
|
|
||
|
|
# Wait for rollout
|
||
|
|
echo "⏳ Waiting for SurrealDB to be ready..."
|
||
|
|
kubectl rollout status statefulset/surrealdb -n $NAMESPACE --timeout=5m
|
||
|
|
|
||
|
|
# Verify
|
||
|
|
echo "✓ Checking pod status..."
|
||
|
|
kubectl get pods -n $NAMESPACE -l app=surrealdb
|
||
|
|
|
||
|
|
echo "✓ Checking services..."
|
||
|
|
kubectl get svc -n $NAMESPACE -l app=surrealdb
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo "🎉 SurrealDB deployed successfully!"
|
||
|
|
echo ""
|
||
|
|
echo "Access information:"
|
||
|
|
echo " Internal: ws://surrealdb:8000"
|
||
|
|
echo " External: kubectl port-forward -n $NAMESPACE svc/surrealdb-lb 8000:8000"
|
||
|
|
echo ""
|
||
|
|
echo "To connect:"
|
||
|
|
echo " kubectl -n $NAMESPACE exec -it surrealdb-0 -- surreal sql"
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.6 Kubernetes Values for Helm (Optional)
|
||
|
|
|
||
|
|
**File**: `k8s/helm-values.yaml` (if using Helm)
|
||
|
|
```yaml
|
||
|
|
# SurrealDB Helm Chart Values
|
||
|
|
# Install: helm install surrealdb surrealdb/surrealdb -f helm-values.yaml
|
||
|
|
|
||
|
|
replicaCount: 1
|
||
|
|
|
||
|
|
image:
|
||
|
|
repository: surrealdb/surrealdb
|
||
|
|
pullPolicy: IfNotPresent
|
||
|
|
tag: "2.3"
|
||
|
|
|
||
|
|
imagePullSecrets: []
|
||
|
|
nameOverride: ""
|
||
|
|
fullnameOverride: ""
|
||
|
|
|
||
|
|
serviceAccount:
|
||
|
|
create: true
|
||
|
|
annotations: {}
|
||
|
|
name: "surrealdb"
|
||
|
|
|
||
|
|
podAnnotations: {}
|
||
|
|
|
||
|
|
podSecurityContext:
|
||
|
|
runAsNonRoot: true
|
||
|
|
runAsUser: 999
|
||
|
|
fsGroup: 999
|
||
|
|
|
||
|
|
securityContext:
|
||
|
|
allowPrivilegeEscalation: false
|
||
|
|
readOnlyRootFilesystem: true
|
||
|
|
capabilities:
|
||
|
|
drop:
|
||
|
|
- ALL
|
||
|
|
|
||
|
|
service:
|
||
|
|
type: ClusterIP
|
||
|
|
port: 8000
|
||
|
|
|
||
|
|
resources:
|
||
|
|
limits:
|
||
|
|
cpu: 2000m
|
||
|
|
memory: 2Gi
|
||
|
|
requests:
|
||
|
|
cpu: 500m
|
||
|
|
memory: 512Mi
|
||
|
|
|
||
|
|
persistence:
|
||
|
|
enabled: true
|
||
|
|
storageClassName: standard
|
||
|
|
size: 10Gi
|
||
|
|
path: /data
|
||
|
|
|
||
|
|
auth:
|
||
|
|
username: admin
|
||
|
|
password: "secure_password_here"
|
||
|
|
|
||
|
|
config:
|
||
|
|
namespace: "syntaxis"
|
||
|
|
database: "projects"
|
||
|
|
logLevel: info
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Part 4: Production Considerations
|
||
|
|
|
||
|
|
### 4.1 High Availability Setup
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# For HA, scale replicas to 3 and configure clustering
|
||
|
|
# k8s/surrealdb-statefulset.yaml (updated for HA)
|
||
|
|
spec:
|
||
|
|
replicas: 3 # Scale to 3 nodes
|
||
|
|
|
||
|
|
# In container args, add clustering:
|
||
|
|
args:
|
||
|
|
- start
|
||
|
|
- --bind
|
||
|
|
- 0.0.0.0:8000
|
||
|
|
- --auth
|
||
|
|
- enable
|
||
|
|
- --log
|
||
|
|
- debug
|
||
|
|
- --clock
|
||
|
|
- "2ms" # Clock precision for clustering
|
||
|
|
# Enable clustering for multi-node setup
|
||
|
|
# Note: Requires SurrealDB enterprise or cloud version
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4.2 Backup and Recovery
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Backup SurrealDB data
|
||
|
|
kubectl -n workspace exec surrealdb-0 -- \
|
||
|
|
tar czf /tmp/backup.tar.gz /data/
|
||
|
|
|
||
|
|
# Extract backup
|
||
|
|
kubectl -n workspace cp surrealdb-0:/tmp/backup.tar.gz ./backup.tar.gz
|
||
|
|
|
||
|
|
# Restore from backup
|
||
|
|
kubectl -n workspace cp backup.tar.gz surrealdb-0:/tmp/
|
||
|
|
kubectl -n workspace exec surrealdb-0 -- \
|
||
|
|
tar xzf /tmp/backup.tar.gz -C /
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4.3 Monitoring and Logging
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# Prometheus ServiceMonitor (if using Prometheus)
|
||
|
|
apiVersion: monitoring.coreos.com/v1
|
||
|
|
kind: ServiceMonitor
|
||
|
|
metadata:
|
||
|
|
name: surrealdb
|
||
|
|
namespace: workspace
|
||
|
|
spec:
|
||
|
|
selector:
|
||
|
|
matchLabels:
|
||
|
|
app: surrealdb
|
||
|
|
endpoints:
|
||
|
|
- port: http
|
||
|
|
interval: 30s
|
||
|
|
path: /metrics
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4.4 Network Security
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# NetworkPolicy to restrict access
|
||
|
|
apiVersion: networking.k8s.io/v1
|
||
|
|
kind: NetworkPolicy
|
||
|
|
metadata:
|
||
|
|
name: surrealdb-netpol
|
||
|
|
namespace: workspace
|
||
|
|
spec:
|
||
|
|
podSelector:
|
||
|
|
matchLabels:
|
||
|
|
app: surrealdb
|
||
|
|
policyTypes:
|
||
|
|
- Ingress
|
||
|
|
- Egress
|
||
|
|
ingress:
|
||
|
|
- from:
|
||
|
|
- podSelector:
|
||
|
|
matchLabels:
|
||
|
|
app: workspace-app
|
||
|
|
ports:
|
||
|
|
- protocol: TCP
|
||
|
|
port: 8000
|
||
|
|
egress:
|
||
|
|
- to:
|
||
|
|
- podSelector: {}
|
||
|
|
ports:
|
||
|
|
- protocol: TCP
|
||
|
|
port: 53 # DNS
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Part 5: Troubleshooting
|
||
|
|
|
||
|
|
### Issue: Connection Refused
|
||
|
|
**Error**: `connection refused` when connecting to localhost:8000
|
||
|
|
|
||
|
|
**Solution**:
|
||
|
|
```bash
|
||
|
|
# Check if SurrealDB is running
|
||
|
|
ps aux | grep surreal
|
||
|
|
|
||
|
|
# If not running, start it
|
||
|
|
surreal start --bind 127.0.0.1:8000 memory
|
||
|
|
|
||
|
|
# Test connection
|
||
|
|
curl http://localhost:8000/health
|
||
|
|
```
|
||
|
|
|
||
|
|
### Issue: Permission Denied in Docker
|
||
|
|
**Error**: `permission denied` when accessing `/data`
|
||
|
|
|
||
|
|
**Solution**:
|
||
|
|
```bash
|
||
|
|
# Fix file permissions
|
||
|
|
docker-compose exec surrealdb chmod 755 /data
|
||
|
|
docker-compose exec surrealdb chown -R 999:999 /data
|
||
|
|
```
|
||
|
|
|
||
|
|
### Issue: Kubernetes Pod CrashLoopBackOff
|
||
|
|
**Error**: Pod keeps restarting
|
||
|
|
|
||
|
|
**Solution**:
|
||
|
|
```bash
|
||
|
|
# Check logs
|
||
|
|
kubectl logs -n workspace surrealdb-0 --previous
|
||
|
|
|
||
|
|
# Check events
|
||
|
|
kubectl describe pod -n workspace surrealdb-0
|
||
|
|
|
||
|
|
# Common causes:
|
||
|
|
# 1. Credentials incorrect in secret
|
||
|
|
# 2. PVC not available
|
||
|
|
# 3. Insufficient resources
|
||
|
|
```
|
||
|
|
|
||
|
|
### Issue: Slow Queries
|
||
|
|
**Solution**:
|
||
|
|
```bash
|
||
|
|
# Enable query logging
|
||
|
|
surreal start --log debug --bind 127.0.0.1:8000 file:///tmp/surrealdb.db
|
||
|
|
|
||
|
|
# Check query performance in logs
|
||
|
|
# Optimize indexes if needed
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Summary
|
||
|
|
|
||
|
|
### Quick Start
|
||
|
|
|
||
|
|
**Local Development**:
|
||
|
|
```bash
|
||
|
|
# Terminal 1: Start SurrealDB
|
||
|
|
surreal start --bind 127.0.0.1:8000 memory
|
||
|
|
|
||
|
|
# Terminal 2: Run your application
|
||
|
|
cargo run -p syntaxis-cli
|
||
|
|
```
|
||
|
|
|
||
|
|
**Docker Development**:
|
||
|
|
```bash
|
||
|
|
docker-compose -f docker-compose.surrealdb.yml up -d
|
||
|
|
# Update configs/database.toml to use:
|
||
|
|
# url = "ws://localhost:8000"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Kubernetes Production**:
|
||
|
|
```bash
|
||
|
|
cd k8s
|
||
|
|
./deploy.sh
|
||
|
|
# Access: kubectl port-forward -n workspace svc/surrealdb 8000:8000
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
- [SurrealDB Official Docs](https://surrealdb.com/docs)
|
||
|
|
- [SurrealDB Docker Hub](https://hub.docker.com/r/surrealdb/surrealdb)
|
||
|
|
- [Kubernetes Documentation](https://kubernetes.io/docs/)
|
||
|
|
- [syntaxis PERSISTENCE_QUICK_START.md](PERSISTENCE_QUICK_START.md)
|
||
|
|
- [SURREALDB_2_3_MIGRATION.md](SURREALDB_2_3_MIGRATION.md)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Last Updated**: November 15, 2025
|
||
|
|
**Version**: SurrealDB 2.3
|
||
|
|
**Status**: Production Ready
|
||
|
|
|