> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heylinger.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment variables

> Look up each environment variable that Linger documents, what it controls, and its default value.

Linger reads its settings from environment variables. For Docker Compose and for development, you set them in the `.env` file at the repository root. Copy `.env.example` to `.env` to start. The template starts every service with every feature that needs no personal key.

`.env.example` has two sections: **Required** and **Optional**, grouped by feature. Each entry holds the value that `pnpm dev` uses. An empty value turns its feature off. Entries that stay commented out use the code default.

Container images and other deployments do not read `.env.example`. They set their own environment. Rate limits, retry and timeout budgets, and optional tools use their code defaults.

## Change these first

Most setups change only a few variables. The first four let other computers on your network reach Linger. The two voice keys turn on the two voice paths.

| Variable | Set it when | Value |
| - | - | - |
| `WEB_BIND_ADDRESS` | Other computers must reach Linger. | `0.0.0.0` serves other computers on the network. The template value is `127.0.0.1`. |
| `WEB_PUBLIC_ORIGIN` | People open Linger at an address other than `localhost`. | The address people open, for example `http://192.168.1.10:3000`. |
| `AGENT_RUNNER_PUBLIC_GATEWAY_URL` | Computers connect from other machines. | The Runner Gateway at the same address, for example `ws://192.168.1.10:3000/v1/runner-gateway`. |
| `LINGER_SECRET_SEED` | `WEB_PUBLIC_ORIGIN` is not a loopback address. | A private seed from `openssl rand -base64 32`. |
| `SONIOX_API_KEY` | You want recording and dictation. | Your own Soniox API key. |
| `XAI_API_KEY` | You want Grok Live voice mode. It does not need Soniox. | Your own xAI API key. |

Here is a `.env` for a host at `192.168.1.10`:

```bash theme={null}
WEB_BIND_ADDRESS=0.0.0.0
WEB_PUBLIC_ORIGIN=http://192.168.1.10:3000
AGENT_RUNNER_PUBLIC_GATEWAY_URL=ws://192.168.1.10:3000/v1/runner-gateway
LINGER_SECRET_SEED=<output of: openssl rand -base64 32>
```

Run `docker compose up --detach --wait` again after you change `.env`. Browsers and computers then reach Linger through port 3000.

> [!WARNING]
>
> The `LINGER_SECRET_SEED` in `.env.example` is public. It works only with a loopback `WEB_PUBLIC_ORIGIN`. In production, generate your own seed and keep it in a secret store.

Browsers allow the microphone only on `localhost` or HTTPS. To use voice from another computer, put an HTTPS proxy in front of port 3000. [Serve other computers on your network](https://docs.heylinger.com/admin/network.md) covers the steps.

## Required variables

Every deployment needs these four variables.

| Variable | Purpose | Value in `.env.example` |
| - | - | - |
| `TEAMHUB_DATABASE_URL` | The PostgreSQL 17 database of TeamHub, with pgvector. | `postgres://simplexai:simplexai@localhost:5432/simplexai_dev?sslmode=disable`, which matches the `postgres` service of the root `docker-compose.yml`. |
| `WEB_PUBLIC_ORIGIN` | The origin that people open in the browser. Computer installers and links use it too. | `http://localhost:3000` |
| `LINGER_SECRET_SEED` | A seed of at least 32 characters. Every service derives the credential of each call direction from it. | A public development seed. |
| `AGENT_RUNNER_PUBLIC_GATEWAY_URL` | The Runner Gateway URL handed to computers. Without it, no computer connects, so no agent runs. | `ws://127.0.0.1:4319/v1/runner-gateway` |

The seed covers three call directions: TeamHub to node-services, node-services to TeamHub, and Voice Runtime to TeamHub. Each service derives its credential with HKDF-SHA256, a key derivation function. No override exists. A deployment sets a public `wss://` address for `AGENT_RUNNER_PUBLIC_GATEWAY_URL`.

## Addresses and network

Each service has one URL, and every caller of that service reads the same URL. Split deployments set their own. A CIDR (Classless Inter-Domain Routing) range names a block of IP addresses.

| Variable | Purpose | Value in `.env.example` |
| - | - | - |
| `TEAMHUB_BASE_URL` | The TeamHub URL. | `http://127.0.0.1:8080` |
| `TEAMHUB_NODE_SERVICES_URL` | The node-services URL. The Agent Service, Memory, and LLM Wiki share this listener. | `http://127.0.0.1:4319` |
| `TEAMHUB_DOCUMENT_RUNTIME_URL` | The Document Runtime URL. | `http://127.0.0.1:4321` |
| `TEAMHUB_TRUSTED_PROXIES` | Comma-separated proxy CIDR ranges whose `X-Forwarded-For` header TeamHub trusts. Behind a reverse proxy, set its range. | `127.0.0.1/32,::1/128` |
| `TEAMHUB_HTTP_ADDRESS`, `NODE_SERVICES_HTTP_ADDRESS`, `DOCUMENT_RUNTIME_HTTP_ADDRESS` | Move a listener, as `host:port`. Change the matching URL too. | Not set. Each process listens on loopback at the ports above. Images and Compose listen on every interface. |
| `TEAMHUB_DOCUMENT_PREVIEW_PUBLIC_ORIGIN` | The origin that serves Document previews to the browser. | Commented out. TeamHub itself serves them. Docker Compose uses `WEB_PUBLIC_ORIGIN` through the Web proxy. |

## Agents and computers

| Variable | Purpose | Value in `.env.example` |
| - | - | - |
| `AGENT_HOME` | The root folder for agent state and logs. A relative path starts from the repository root. | `.linger-runtime/agent`. Without a value, the root is `~/.mirror`. |
| `TEAMHUB_PERMISSION_REVIEW` | Turns on the rule checks and the permission review on each Computer. When on, an action that the rules do not allow waits for the review, and an action that the review cannot judge waits for a review card. When off, Computer actions run without these checks; confirmation cards still apply. | `false` |
| `TEAMHUB_CLI_BASE_URL` | The TeamHub origin that the computer's CLI calls when it cannot reach `TEAMHUB_BASE_URL`. | Commented out. `pnpm stack:up` sets it to `WEB_PUBLIC_ORIGIN`. |
| `COMPUTER_RELEASE_DIR` | The computer release that the Agent Service serves on `/install/`. `make computer-release-local` builds it. | `.linger-runtime/computer-release` |
| `COMPUTER_RELEASE_TARGETS` | The platform of the computer release, for example `linux-x64`. | Commented out, because the right value depends on the host. |

## Memory and the personal memory

| Variable | Purpose | Value in `.env.example` |
| - | - | - |
| `TZ` | The time zone in which Memory, Pocket Notes, and the wiki turn the day over at midnight. | Commented out. The host's zone applies. Compose containers use UTC. |

## Connected apps

| Variable | Purpose | Value in `.env.example` |
| - | - | - |
| `COMPOSIO_API_KEY` | Your Composio key. It turns on connected apps such as Gmail and GitHub. | Empty. People can save a key in **Apps** instead. |
| `TEAMHUB_SECRET_ENCRYPTION_KEY` | Encrypts the Composio key that people save in **Apps**: 32 bytes in standard base64. Empty turns off saving keys in the product. | A public development key. Generate your own with `openssl rand -base64 32`. |
| `TEAMHUB_COMPOSIO_ENVIRONMENT_KEY` | A prefix for Composio user IDs. Change it when deployments share one Composio project. | `default` |

The scoped Composio project key needs these permissions:

* Connected-account link and read.
* Auth-config read and create.
* Proxy execute.
* Tool catalog read and execute.

## Storage

| Variable | Purpose | Value in `.env.example` |
| - | - | - |
| `TEAMHUB_ARTIFACT_STORAGE_ROOT` | The local root for artifacts, relative to `apps/teamhub`. | `.local/teamhub/artifacts` |

## Voice

Voice has two paths with separate keys. Soniox turns on recording, dictation, and archive recovery. xAI turns on Grok Live. Recordings go to the artifact store through TeamHub, which needs `ffmpeg` and `ffprobe` on its `PATH`.

| Variable | Purpose | Value in `.env.example` |
| - | - | - |
| `SONIOX_API_KEY` | Your Soniox key. Empty keeps recording, dictation, and archive recovery off. | Empty |
| `XAI_API_KEY` | Turns on Grok Live, without Soniox. With this key, the **Voice Mode** button is Live. With only Soniox, it dictates. | Empty |
| `LIVEKIT_URL` | The LiveKit server. TeamHub and Voice Runtime read it, and browsers dial it. | `ws://127.0.0.1:17880` |
| `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET` | The LiveKit key pair. The LiveKit server takes the same pair, so change both sides together. | A local development pair. Production uses its own pair. |

The root `docker-compose.yml` runs LiveKit. `pnpm dev` runs `livekit-server` from your `PATH` on these values while a voice key is set.

## Local development

These variables apply to `pnpm dev` and `pnpm stack:up`. Leave them commented out until you need them.

| Variable | Purpose | Commented value in `.env.example` |
| - | - | - |
| `OWNER_EMAIL` | The owner email that `pnpm dev` and the native source account CLI use. | `owner@linger.local` |
| `POSTGRES_PORT` | The host port of PostgreSQL for `pnpm stack:up`. | `5432` |
| `TEAMHUB_HTTP_PORT` | The host port of TeamHub for `pnpm stack:up`. | `8080` |
| `WEB_HTTP_PORT` | The host port of the web app for `pnpm stack:up`. | `3000` |
| `WEB_BIND_ADDRESS` | The host address that the `pnpm stack:up` Web port binds. | `127.0.0.1` |
| `NODE_SERVICES_HTTP_PORT` | The host port of node-services for `pnpm stack:up`. | `4319` |
| `DOCUMENT_RUNTIME_HTTP_PORT` | The host port of the Document Runtime for `pnpm stack:up`. | `4321` |
| `COMPOSE_PROJECT_NAME` | A unique Compose project name for each checkout that runs at the same time. | `linger`. Without it, the folder name applies. |
| `NODE_ENV` | Images set `production`. Do not set a development value here, because Vite reads this file. | `development` |

The port variables move only the published ports. The containers keep listening on their default ports.

Every variable that runtime code reads must appear in `.env.example` or in `scripts/env-inventory.json`. `pnpm env:inventory:check` checks this.

## Other documented variables

These variables do not live in `.env`. Other tools and tests read them.

| Variable | Read by | Purpose |
| - | - | - |
| `TEAMHUB_URL`, `TEAMHUB_TOKEN` | `teamhub` CLI | Direct mode without a configuration file. Commands that need a Room or Task then return `configuration_error`. |
| `TEAMHUB_TEST_DATABASE` | TeamHub integration tests | Set to `isolated` to ignore the shared test database for one run. |
| `LOCALMODELS_KIT_HOME` | `stack.sh`, `stack.ps1` | The cache folder of the local model kit. The default is `~/.cache/linger-localmodels/kits`, or `%LOCALAPPDATA%\linger-localmodels\kits` on Windows. |
| `LOCALMODELS_KIT_BASE_URL` | `stack.sh`, `stack.ps1` | Download the same kit files from an internal mirror. SHA-256 is still checked against the pin in the script. |
| `LINGER_GO_LOCAL_DAEMON_PATH` | `linger-computer` | The Computer Daemon to start during source development. |
| `GITHUB_TOKEN`, `GH_TOKEN` | `skill-installer` Skill | Reach private GitHub repositories, or avoid anonymous rate limits. |

## Keep learning

> [card] [Serve other computers on your network](https://docs.heylinger.com/admin/network.md)
>
> Serve Linger to other computers on your network.

> [card] [Enable voice](https://docs.heylinger.com/admin/voice.md)
>
> Turn on recording, dictation, and voice mode.

> [card] [Contribute](https://docs.heylinger.com/developers/contribute.md)
>
> Use `.env` to run Linger from source.

> [card] [Install with Docker Compose](https://docs.heylinger.com/install/docker-compose.md)
>
> Run every service in containers from a checkout.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.