Skip to main content

Docker Deployment

ScramDB ships as a single Docker image that runs both single-node and cluster deployments. This page covers running one node. For a multi-node cluster, see Clustering (requires an Enterprise license).

Quick Start​

docker pull scramdb/scramdb:latest

docker run -d \
--name scramdb \
-p 5432:5432 \
-p 9090:9090 \
-p 9191:9191 \
-v scramdb-data:/var/lib/scramdb \
scramdb/scramdb:latest

Connect with any PostgreSQL client:

psql "host=127.0.0.1 port=5432 user=scramdb dbname=scramdb"

Port 5432 is the PostgreSQL wire protocol port, and 9090 serves Prometheus metrics at /metrics and a plain health check at /health.

Securing a node​

The published image's container command is --pg-address 0.0.0.0:5432 --pg-no-auth. That last flag trusts every incoming connection with no password check, and it also disables hba_file-based rules. This is intentional for a fast local start, but it means the container listens on every interface with no authentication until you change it.

The engine itself does not default this way: with no flags and no config file, ScramDB binds to 127.0.0.1:5432 only and authentication is on. The 0.0.0.0 bind and the disabled auth both come from the image's own startup command, not from the engine.

To run with authentication in Docker, override the container command and drop --pg-no-auth:

docker run -d \
--name scramdb \
-p 5432:5432 \
-p 9090:9090 \
-p 9191:9191 \
-v scramdb-data:/var/lib/scramdb \
-v $(pwd)/scramdb.toml:/etc/scramdb/config.toml:ro \
scramdb/scramdb:latest \
--config /etc/scramdb/config.toml --pg-address 0.0.0.0:5432

With --pg-no-auth absent, ScramDB uses its built-in rules by default: connections from localhost are trusted, everything else requires a password. To use your own rules, point hba_file at a mounted pg_hba.conf-style file. To add TLS, set tls_cert and tls_key to mounted PEM files. All three keys live under [general]:

[general]
pg_address = "0.0.0.0:5432"
hba_file = "/etc/scramdb/pg_hba.conf"
tls_cert = "/etc/scramdb/server.crt"
tls_key = "/etc/scramdb/server.key"

There is no environment variable or CLI flag that turns authentication on; it is on by default and only --pg-no-auth (or pg_no_auth = true in the config) turns it off.

Configuration​

ScramDB is configured with a TOML file. The image ships a working single-node configuration, so no file is required to get started. To customize a node, mount your own configuration and point the container at it:

docker run -d \
--name scramdb \
-p 5432:5432 \
-p 9090:9090 \
-p 9191:9191 \
-v scramdb-data:/var/lib/scramdb \
-v $(pwd)/scramdb.toml:/etc/scramdb/config.toml:ro \
scramdb/scramdb:latest

A minimal configuration file:

[general]
pg_address = "0.0.0.0:5432"
metrics_port = 9090
jit_enabled = true

[storage]
prod_name = "tundra"
shard_id = 0
basedir = "/var/lib/scramdb"
buffer_pool_percent = 60
execution_memory_percent = 15

buffer_pool_percent and execution_memory_percent size the buffer pool and query execution memory as a share of the RAM ScramDB detects (see the note on container-aware sizing below). You can pin an exact size instead with buffer_pool_size_bytes = "2GB".

If you don't need to change anything under [general], mounting your own file for [storage] tuning alone is fine; every field not set falls back to its default.

See Single Node for sizing guidance and Requirements for hardware.

Environment variables​

The container reads a handful of environment variables directly; all other tuning lives in the configuration file.

VariableDefaultDescription
SCRAMDB_LOGinfoLog level: off, trace, debug, info, warn, or error. An unrecognized value silently falls back to info.
SCRAMDB_LOG_FORMATtextSet to json for structured JSON logs
SCRAMDB_LICENSE_KEYunset (Community)Enterprise or Trial license key. Required to enable clustering; also available as license_key under [general] in the config file. The environment variable wins if both are set.
SCRAMDB_GPU_FORCEunset (false)Set to 1 or true to force GPU acceleration on

Cluster mode is selected by three additional variables (NODE_NAME, ADVERTISE_ADDR, and SEEDS), read by the container's entrypoint script rather than the engine itself, plus two optional geo-placement variables (REGION and ZONE) the same script renders straight into the node's config. See Clustering.

GPU acceleration​

[gpu] enabled = true is the shipped default, and it is safe with no GPU hardware at all: on a plain cloud VM or a laptop with no device, ScramDB detects that no GPU is present, logs one line, and falls back to CPU execution. Nothing extra needs to be mounted or added.

If a GPU is passed through to the container, ScramDB pins host memory on demand for GPU transfers. If the container's capability set already allows that (a Kubernetes pod without a capability drop, or a container that already has CAP_IPC_LOCK), nothing further is needed. If it doesn't, ScramDB automatically falls back to a pre-allocated pinned memory pool (256 MB by default, [gpu] pinned_memory_pool) at startup and keeps running: GPU queries still execute, with one extra memory copy per transfer instead of a zero-copy path.

You only need to act if you see a GPU memory-pinning error in the logs, which happens only when the pinned pool itself fails to allocate. The fix is one of:

# Option 1: raise the pinned pool
[gpu]
pinned_memory_pool = "512MB"
# Option 2: grant the capability for a zero-copy path
docker run --cap-add=IPC_LOCK ...

No other Docker capability, --privileged flag, or --shm-size setting is needed for GPU acceleration in any configuration.

Volumes​

Mount a persistent volume at /var/lib/scramdb so your data survives restarts and upgrades. It holds both the columnar storage and the write-ahead log.

docker volume create scramdb-data

docker run -d \
--name scramdb \
-p 5432:5432 \
-v scramdb-data:/var/lib/scramdb \
scramdb/scramdb:latest

The shipped image also archives the write-ahead log by default ([storage.wal.archive] enabled = true), writing to a wal-archive subdirectory inside the data volume so point-in-time recovery works out of the box with no extra setup. See Backup and restore for the CLI that reads it.

Resource limits​

Bound the container's CPU and memory with the standard Docker flags:

docker run -d \
--name scramdb \
-p 5432:5432 \
-p 9090:9090 \
-p 9191:9191 \
-v scramdb-data:/var/lib/scramdb \
--cpuset-cpus="0-7" \
--memory=16g \
scramdb/scramdb:latest

--cpuset-cpus is preferred: an exclusive cpuset pins ScramDB to specific cores with no CFS throttling jitter, while --cpus (a quota, shown below) now also resolves to the correct worker count but shares physical cores under CFS scheduling. See Parallelism for exactly how each resolves into a worker count and for the SCRAMDB_MAX_CORES override.

docker run -d \
--name scramdb \
-p 5432:5432 \
-p 9090:9090 \
-p 9191:9191 \
-v scramdb-data:/var/lib/scramdb \
--cpus=8 \
--memory=16g \
scramdb/scramdb:latest

ScramDB reads the container's own cgroup memory limit (falling back to host memory if none is set) and sizes the buffer pool and execution memory pools from it automatically when you use the percent-based keys (buffer_pool_percent, execution_memory_percent); pinning exact byte sizes in the config file is for when you want a fixed budget regardless of the container limit.

Docker Compose​

Single node:

services:
scramdb:
image: scramdb/scramdb:latest
ports:
- "5432:5432" # PostgreSQL clients
- "9090:9090" # Prometheus metrics and health
volumes:
- scramdb-data:/var/lib/scramdb
deploy:
resources:
limits:
cpus: '8'
memory: 16G

volumes:
scramdb-data:

For a multi-node Compose file, see Clustering.

Health Check​

The image includes a built-in health check using pg_isready:

pg_isready -h 127.0.0.1 -p 5432 -U scramdb -d scramdb

The metrics server also exposes a plain HTTP health endpoint, useful for a load balancer or a Kubernetes httpGet probe that shouldn't need a PostgreSQL client:

curl http://127.0.0.1:9090/health
# ok