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.

VariableRequiredWhat it does
YEKE_DB_URLRequired for PG modePostgreSQL connection string (postgres://user:pass@host:5432/db). If unset, core uses SQLite.
YEKE_PG_POOL_SIZEOptionalPool 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:

  1. Core connects to PostgreSQL first (a plain connection).
  2. It checks the schema_migrations table read-only; if it does not exist, the install is "virgin".
  3. It reads the license (from the file; with no file and an existing schema, from the database record).
  4. 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.
  5. 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-migrate tool.

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.