Environment Variables

connect and defineConfig do not read the environment. okm reads OKM_DEBUG. Local Postgres reads POSTGRES_VERSION and REQUIRE_DOCKER.

connect and defineConfig do not read the environment. okm reads OKM_DEBUG. Local Postgres reads POSTGRES_VERSION, REQUIRE_DOCKER, and the three host ports.

Client

The client takes the URL you pass. Target is that argument. Database is the field in okmodel.config.ts.

db.ts
import { connect } from "okmodel/pg/postgresjs";
import { schema, table, t } from "okmodel/pg";

const notes = table("notes", {
  id: t.identity(),
  title: t.text(),
});

const app = schema({ tables: [notes] });

const url = process.env.DATABASE_URL;
if (url === undefined || url.length === 0) throw new Error("DATABASE_URL is not set");

export const db = connect(url, { schema: app });

DATABASE_URL is the name in the handbook. connect does not look it up. A missing or empty value is passed through. Check it before the call.

okmodel.config.ts
import { defineConfig } from "okmodel/migrate";

export default defineConfig({
  schema: "./schema.ts",
  database: process.env.DATABASE_URL!,
});

A missing or empty database is OKM1845. Target default has no url. The config loader does not fill it from the environment.

NameResult
NODE_ENVNot read. It does not select a target, set protected, or turn on requireMeta.
OKM_ALLOW_PROTECTEDNot read. --allow-protected is that invocation. Setting the variable leaves OKM1850 in place.

A replica URL is the same kind of argument. Topology takes the strings you pass.

The URL

connect and defineConfig receive the string you pass. They do not read DATABASE_URL.

CLI

okm reads one variable, and only when a command throws.

VariableRead byAcceptedDefaultUnset
OKM_DEBUGthe okm bin1noneerror <code>: <message>, then the fix. No stack.

1 appends the stack after those two lines. Any other string leaves the stack off. --verbose prints the stack for that invocation.

OKM_DEBUG=1 okm check

Migrate commands read the config and the flags. The target, protection, and the apply timeouts are those fields. See Database and Timeouts.

Tests and local Postgres

bun run db:up, bun run db:down, bun run test:postgres, and bun run verify read these. The published client does not. PGlite has no server and does not read them.

Version

VariableRead byAcceptedDefaultUnset
POSTGRES_VERSIONdb:up, db:down, verify, test:postgres15, 16, 17, 181717. The image is postgres:17.

Any other string, including "", throws Postgres version '<value>' is outside 15–18. bun run db:up and bun run db:down print that after [db] and exit 1.

bun run verify uses this major. bun run verify --all runs 15, 16, 17, and 18, and sets POSTGRES_VERSION to the major it is starting. bun run test:postgres uses the major for the suite plan. It does not start Docker.

Docker

VariableRead byAcceptedDefaultUnset
REQUIRE_DOCKERPostgres tests1noneSkip when Docker or the topology is down.

Only 1 fails the test. true and 0 skip.

Probe1Unset
Docker is not runningREQUIRE_DOCKER=1 but Docker is not running.Skipping Postgres tests: Docker is not running.
Docker is running, Postgres is closedREQUIRE_DOCKER=1 but Postgres is not accepting connections. Run bun run db:up.Skipping Postgres tests: Docker is running but Postgres is not up. Run bun run db:up.
The primary accepts connectionsThe test runs.The test runs.

bun run test:postgres and bun run verify set REQUIRE_DOCKER=1 for the test process. The probe opens the topology primary. A DATABASE_URL in the environment does not move it.

Ports

The primary URL is postgres://okm:okm@127.0.0.1:<port>/okm. Replica a and replica b use the same user, password, host, and database.

VariableRead byAcceptedDefaultUnset
OKM_PRIMARY_PORTdb:up and the primary URLa host port5543255432 when that port is free
OKM_REPLICA_A_PORTdb:up and the replica a URLa host port5543355433 when that port is free
OKM_REPLICA_B_PORTdb:up and the replica b URLa host port5543455434 when that port is free

When all three are unset and one of 55432–55434 is taken, db:up binds three free ports and prints [db] Postgres <version> topology is up (primary <port>, replicas <a> and <b>). Tests still open 55432–55434 until you set the variables to the printed ports.

Setting any one of the three pins all three. An omitted name stays at its default, and the free-port choice does not run.

When GITHUB_ENV is set, db:up appends the three ports for the next step. Locally that file is unset, and the shell that ran db:up is unchanged.

POSTGRES_VERSION=16 bun run db:up
REQUIRE_DOCKER=1 bun test