Skip to content

Configuration

PondPilot Proxy is configured through YAML files and environment variables. Environment variables take precedence over YAML configuration.

Environment Variables (highest priority)
│
▼
YAML Config File
│
▼
Default Values (lowest priority)
# Server configuration
server:
port: 8080 # HTTP server port
grpc_port: 8081 # gRPC (Flight SQL) port
host: "0.0.0.0" # Listen address
# Container orchestration
containers:
image: "ghcr.io/pondpilot/sqlflite:latest" # SQLFlite container image
idle_timeout: 5m # Stop containers after this idle period
memory_limit: "512m" # Memory limit per container
cpu_limit: 0.5 # CPU limit per container (0.5 = half a core)
max_per_host: 100 # Maximum containers per host
network: "pondpilot" # Docker network name
# DuckDB configuration
duckdb:
extensions: # Extensions to load in containers
- arrow
- postgres
- mysql
attached_databases: # Pre-attached databases (see below)
- alias: "mydb"
type: "postgres"
connection_string: "${DATABASE_URL}"
# Security configuration
security:
rate_limit:
requests_per_minute: 100 # Rate limit per user
burst_size: 200 # Burst allowance
# AI integration
ai:
claude_api_key: "${CLAUDE_API_KEY}"
openai_api_key: "${OPENAI_API_KEY}"
default_model: "claude-sonnet-4-20250514"
VariableDescription
JWT_SECRETJWT signing secret (minimum 32 characters)
VariableDescriptionDefault
PORTHTTP server port8080
GRPC_PORTgRPC server port8081
HOSTListen address0.0.0.0
VariableDescriptionDefault
CONTAINER_IMAGESQLFlite container imageghcr.io/pondpilot/sqlflite:latest
CONTAINER_IDLE_TIMEOUTIdle timeout in milliseconds300000 (5 min)
CONTAINER_MEMORY_LIMITMemory limit per container512m
CONTAINER_CPU_LIMITCPU limit per container0.5
CONTAINER_MAX_PER_HOSTMaximum containers100
CONTAINER_NETWORKDocker network namebridge
VariableDescriptionDefault
CLAUDE_API_KEYAnthropic API key—
OPENAI_API_KEYOpenAI API key—
AI_DEFAULT_MODELDefault AI modelclaude-sonnet-4-20250514

Configure databases to attach automatically when user containers start.

duckdb:
attached_databases:
# PostgreSQL
- alias: "analytics"
type: "postgres"
connection_string: "postgresql://user:pass@host:5432/analytics"
# MySQL
- alias: "customers"
type: "mysql"
connection_string: "mysql://user:pass@host:3306/customers"
# SQLite
- alias: "local"
type: "sqlite"
connection_string: "/data/local.db"
TypeAliasesNotes
postgrespostgresqlPostgreSQL and compatible databases
mysql—MySQL and MariaDB
sqlite—SQLite files

PostgreSQL:

postgresql://user:password@host:port/database
postgresql://user:password@host:port/database?sslmode=require

MySQL:

mysql://user:password@host:port/database

SQLite:

/absolute/path/to/database.db

Connection strings support environment variable substitution:

attached_databases:
- alias: "prod"
type: "postgres"
connection_string: "${DATABASE_URL}"

All requests require JWT authentication. The JWT must include a sub claim identifying the user.

ClaimRequiredDescription
subYesUser identifier (used for container isolation)
expYesExpiration timestamp
iatNoIssued-at timestamp

The JWT_SECRET must be at least 32 characters:

Terminal window
# Generate a secure secret
openssl rand -base64 32

For testing, the proxy can issue demo tokens:

Terminal window
curl -X POST http://localhost:8080/auth/demo-token

Demo tokens have:

  • Short expiration (1 hour)
  • Stricter rate limits
  • Restricted features

Configure per-user rate limits:

security:
rate_limit:
requests_per_minute: 100 # Sustained rate
burst_size: 200 # Temporary burst allowance

Rate limits apply per-user (identified by JWT sub claim).

Control resource usage per container:

containers:
memory_limit: "512m" # Memory limit
cpu_limit: 0.5 # CPU cores (0.5 = half core)
  • 256m — 256 megabytes
  • 1g — 1 gigabyte
  • 2g — 2 gigabytes

Fractional values allowed:

  • 0.5 — Half a CPU core
  • 1.0 — One full core
  • 2.0 — Two cores

Containers run with hardened security settings:

SettingValuePurpose
UserUID 1000Non-root execution
CapabilitiesAll droppedMinimal privileges
no-new-privilegesEnabledPrevent privilege escalation

The proxy automatically manages container lifecycle:

containers:
idle_timeout: 5m # Stop after 5 minutes idle
max_per_host: 100 # Maximum concurrent containers
  1. Background reaper runs every minute
  2. Checks each container’s last-used timestamp
  3. Stops containers idle longer than idle_timeout
  4. Containers respawn on next request
ScenarioLatency
Container cached~10-50ms
Container respawn~2-5 seconds

Set longer idle timeouts for frequently-used systems to avoid respawn latency.

EndpointPurpose
GET /healthBasic health check
GET /readyReadiness probe (for k8s)
GET /health/detailedDetailed component status
server:
port: 8080
grpc_port: 8081
containers:
idle_timeout: 30m # Longer timeout for dev
memory_limit: "1g"
duckdb:
attached_databases:
- alias: "dev"
type: "postgres"
connection_string: "postgresql://postgres:postgres@localhost:5432/dev"
server:
port: 8080
grpc_port: 8081
containers:
image: "ghcr.io/pondpilot/sqlflite:v1.2.3" # Pin version
idle_timeout: 5m
memory_limit: "512m"
cpu_limit: 0.5
max_per_host: 50
security:
rate_limit:
requests_per_minute: 60
burst_size: 100
duckdb:
attached_databases:
- alias: "prod"
type: "postgres"
connection_string: "${DATABASE_URL}"