Skip to content

Configuration

Codex Pooler keeps boot-time release settings in environment variables and day-to-day operator settings in the database-backed admin UI.

For Docker Compose, scripts/self-host/generate-env.sh writes a local .env file with generated secrets and local defaults. Keep that file private. Don’t reuse generated values across public installs.

The local web URL is http://localhost:4000.

The generator writes CODEX_POOLER_IMAGE_TAG=latest unless you set a tag first. For self-hosted installs, set it to a tagged stable release from GitHub Releases before running the generator. The latest tag follows the most recently published release, but a version tag keeps the selected installation reproducible:

Terminal window
export CODEX_POOLER_IMAGE_TAG=<release-tag>
scripts/self-host/generate-env.sh

If port 4000 is already in use, set CODEX_POOLER_HTTP_PORT before generation or edit the generated .env before starting the stack. Use the Compose URL above even if the Phoenix startup banner prints an endpoint URL such as https://localhost; the port mapping is the local URL to open.

Set release environment variables for values the app needs before it can read database settings.

VariablePurpose
CODEX_POOLER_IMAGERelease image name used by the Compose flow
CODEX_POOLER_IMAGE_TAGRelease image tag used by the Compose flow
CODEX_POOLER_HTTP_PORTLocal host port, default 4000
DATABASE_URLPostgres connection URL
SECRET_KEY_BASEPhoenix signing and encryption secret
PHX_HOSTPublic host used by the HTTP endpoint
PORTHTTP port inside the release container
PHX_SERVERSet to true so the release serves HTTP
OBAN_MODERelease role, such as web, worker, scheduler, or all
OBAN_JOBS_QUEUE_LIMITJob queue limit for the release role
DNS_CLUSTER_QUERYDNS clustering query when clustering is enabled
CODEX_POOLER_TOTP_ENCRYPTION_KEYTOTP encryption root key
CODEX_POOLER_TOTP_KEY_VERSIONTOTP key version
CODEX_POOLER_UPSTREAM_SECRET_KEYUpstream secret encryption root key
CODEX_POOLER_UPSTREAM_SECRET_KEY_VERSIONUpstream secret key version

The upstream secret key must decode to 32 raw bytes. The TOTP and upstream key versions let operators rotate encrypted secret roots deliberately.

Official release images include the OS IANA timezone database used for operator timezone display. Custom runtime images or hosts must provide zoneinfo files at /usr/share/zoneinfo or set TZDIR.

After the app boots, manage operational settings from the admin UI instead of editing code. Instance settings cover areas such as file limits, ingress trust, gateway diagnostics, route-class admission, circuit thresholds, metrics auth, operator email, model metadata, upstream timeouts, pricing catalog settings, and SMTP delivery.

Secret settings stay write-only in the UI. For example, metrics bearer material is stored as a keyed digest and SMTP credentials are stored encrypted for mail delivery and credential checks.

Gateway websocket upgrades use two separate admin-managed idle settings:

  • websocket_idle_timeout_ms controls downstream idle close behavior for new backend Codex websocket upgrades and the narrow public /v1/responses websocket route. It also bounds owner-forwarded full-turn submit waits for new websocket requests. It is separate from upstream receive timeouts.
  • websocket_owner_idle_timeout_ms controls how long an owner and its upstream websocket may remain available after the final downstream detaches and no turn is active. Reattaching before expiry cancels that owner’s retention timer.

Both settings default to 1_800_000 ms and accept 60_000..3_600_000 ms. Each new or recovered owner captures websocket_owner_idle_timeout_ms from the node where it starts. An existing owner retains its captured value when the setting changes; later owners capture the new value.

A longer owner-retention window can improve the chance of reusing an upstream connection, but keeps owner processes and connections allocated longer after clients detach. A shorter window releases those resources sooner, with less opportunity for reuse. To roll back a change, restore the previous value in the admin UI. New and recovered owners use the restored value; replace existing owners as part of the rollback only when immediate convergence is required.

During a mixed-release transition, owners started by the previous release retain the legacy five-minute behavior and do not provide upstream connection lifecycle metadata. Owners started or recovered by the current release use the 30-minute default. Native websocket attachment remains compatible with previous-release owners, while an HTTP-to-websocket bridge that needs the option-carrying attachment fails closed to plain HTTP when its owner is still on the previous release.

Use only the surface that matches your client.

Client typeLocal URLDeployed example
Codex backend clienthttp://localhost:4000/backend-api/codexhttps://codex-pooler.example.com/backend-api/codex
Narrow OpenAI-compatible SDK clienthttp://localhost:4000/v1https://codex-pooler.example.com/v1
Operator MCP hosthttp://localhost:4000/mcphttps://codex-pooler.example.com/mcp

Use Authorization: Bearer <pool-api-key> for /backend-api and /v1. Use Authorization: Bearer <operator-mcp-token> for /mcp.

The operator MCP endpoint is metadata-only and read-only. It doesn’t accept Pool API keys, browser sessions, cookies, invite tokens, upstream tokens, or query tokens.

Use these checks for a local instance:

Terminal window
curl -fsS http://localhost:4000/healthz
curl -fsS http://localhost:4000/readyz

For a deployed instance, use the same paths on https://codex-pooler.example.com.

The support boundary is intentionally narrow. Public docs can help you start the service, configure supported route surfaces, and understand metadata-only behavior. They can’t decide whether your organization may use a provider account, share a Pool, or connect a given MCP host.

For responsible operation:

  • Operate only accounts you are allowed to use
  • Keep Pool API keys separate from operator MCP tokens
  • Rotate exposed credentials immediately
  • Connect MCP only to hosts you trust with operator metadata
  • Don’t send raw prompts, request bodies, response bodies, file bytes, audio, images, cookies, bearer tokens, Pool API keys, MCP tokens, upstream secrets, or auth.json material in support messages

The Codex backend compatibility route is rooted at /backend-api/codex/*. The /v1 surface provides narrow OpenAI-compatible support for selected SDK routes, then routes supported requests through the same Pool policy and accounting path.

It does not provide full OpenAI API parity. OpenAI Realtime SDK websocket and session routes are not supported. GET /v1/responses is narrow Responses websocket compatibility, not /v1/realtime support.