yeke.io · docs · enterprise
PostgreSQL Connection
YEKE uses SQLite by default. Enterprise can connect to an existing PostgreSQL server. This guide covers connection settings, the snapshot key and licensing requirements.
Overview
Two drivers, one switch.
Set YEKE_DB_URL to use PostgreSQL. Otherwise, core uses the SQLite file at YEKE_DB_PATH. Setting both prevents startup. If PostgreSQL is unavailable, core stops with an error rather than falling back to SQLite.
PostgreSQL is used with the same type discipline as SQLite across the entire SQL surface: dates as ISO-8601 text, booleans as 0/1, JSON as text. The one difference that matters to your DBA is the connection shape: §3 below.
Setting up the connection
One environment variable; TLS settings live inside the connection string.
| Variable | Required | What it does |
|---|---|---|
YEKE_DB_URL | Required for PG mode | PostgreSQL connection string (postgres://user:pass@host:5432/db). If unset, core uses SQLite. |
YEKE_PG_POOL_SIZE | Optional | Pool size per replica, default 10. The right value is a conversation with your DBA; YEKE cannot know your organization's pooling policy. |
kubectl -n yeke-system create secret generic yeke-core-secrets \ --from-literal=YEKE_DB_URL="postgres://<user>:<password>@<pg-host>:5432/<db>" \ --from-literal=YEKE_SNAPSHOT_KEY="$(openssl rand -hex 32)"
The example above is for Kubernetes; the single-machine docker run command is in
Installation → Enterprise (PostgreSQL).
TLS and an internal CA. TLS settings are parameters of the connection string. If the
server certificate is signed by your organization's own CA, put the root certificate file at a path
core can read and add it to the string: ?sslmode=verify-full&sslrootcert=/etc/yeke/pg-ca.pem.
The certificate chain and the server name are verified together; if the file cannot be read or the
certificate does not verify, core does not start.
Unlike libpq, sslmode=require also verifies the certificate; the driver prints a warning that this will
change, so write verify-full explicitly. sslmode=disable is not rejected —
this connection is your own database network, and TLS-free internal PostgreSQL setups are a
legitimate organizational standard. YEKE_PUBLIC_CA_FILE on the
Internal CA page is for core's own certificate and does not cover
this connection.
No server configuration is required: everything the driver uses is a standard client capability (plain SQL, TLS, advisory locks). No extensions need to be installed.
Supported connection shape
The shape of the connection target is a contract; connecting to a corporate PostgreSQL through a pooler is the norm, not the exception.
YEKE_DB_URL must point at the postmaster directly or at a
session-mode pooler.
transaction/statement-mode pooling is not supported
With PgBouncer, use a dedicated session-mode pool or connect directly to PostgreSQL. Leader-election advisory locks and session settings require a persistent connection. transaction and statement pooling are not supported.
The startup probe catches this mismatch early: if the connection target does not have this shape, core stops with an explicit error rather than misbehaving silently.
Minimum version and pool
The floor is a support-policy boundary, not a technical one.
PostgreSQL 15 or later is supported. Set YEKE_PG_POOL_SIZE to configure the pg.Pool connection pool; the default is 10 connections per replica.
Snapshot key
Optional in SQLite mode, required in PostgreSQL mode.
The 32-byte YEKE_SNAPSHOT_KEY that encrypts stored credentials, AI keys, and
hook secrets is generated by core itself and written to the data directory if you leave it
unset in SQLite mode. PostgreSQL mode has no such fallback — core does not generate the
key, and it must be supplied externally through YEKE_SNAPSHOT_KEY (env) or
YEKE_SNAPSHOT_KEY_FILE (file path). On Kubernetes this is a Secret — the example
command in §2 above creates both together.
The reason is filesystem independence: in PostgreSQL mode core expects no directory to exist or be writable — having it generate and write a key to one would undo that independence from the start.
License gate: ha-postgres
What is gated is not multi-replica — it is the PostgreSQL connection itself.
The PostgreSQL driver sits behind the Enterprise ha-postgres feature — even a
single-replica PostgreSQL setup requires this flag; there is no separate flag for it. The
startup order is deliberate:
- Core connects to PostgreSQL first (a plain connection).
- It checks the
schema_migrationstable read-only; if it does not exist, the install is "virgin". - It reads the license (from the file; with no file and an existing schema, from the database record).
- If the flag is missing and the database has users: it fails with
LICENSE_FEATURE_LOCKED. On a database with no users (virgin), core starts without a license and creates the schema, and the setup form asks for the license block together with the first administrator; the license then lives in the database. - If the flag is present: normal startup (baseline/migrations) proceeds.
Managing the license as a file is optional (GitOps, HA): if YEKE_LICENSE_PATH is set, the license is read from the file, the setup screen doesn't ask for one and the License screen refuses uploads.
If the schema was already created by a previous startup, core never drops it — the objects in your database are yours; if the license flag is removed later, the error states that the schema is left in place and cleanup is your organization's call.
0.26.1 note: on an older install that has no archive table
(archived_operations), migration 38 no longer fails — if the table is missing it
skips that step and core starts; behaviour is unchanged when the table IS present. If the
table is missing, the startup log prints one line saying so, on EVERY startup until the
install is fixed. On the same install, the compliance
report no longer errors: it declares the archive as "unreadable" and keeps being produced
from live records. Do not turn on
YEKE_RETENTION_ARCHIVE until the table is
fixed — archive writing stops with archive_stalled.
Limits
YEKE is the side that connects, not the side that operates.
- YEKE does not install, cluster, back up, or operate PostgreSQL. It connects to a PostgreSQL your organization provides — its version, clustering, replication, backup policy, and tuning are your DBA's discipline.
- No server configuration is required. No extension installs or special GUC settings are needed.
- There is no PostgreSQL in Community. SQLite is, and remains, the first-class path for Community and single-node installs.
- Manually moving an existing SQLite install is not supported. The supported path
is the
yeke-migratetool.
Have an existing SQLite install?
Connecting to PostgreSQL does not automatically move an existing SQLite install. The
supported path is the yeke-migrate tool: offline, one-way, with integrity
verification.