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
mysqlMySQL and MariaDB
sqliteSQLite 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}"