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

# Configuration reference

> Every environment variable a self-hosted Entri instance reads, with defaults, plus the public config and health endpoints.

Entri is configured with environment variables only. With Docker Compose they go in `deploy/docker/.env`. With Helm, non-secret values go under `config:` and secret values under `secrets:` (or in your `existingSecret`). See [Kubernetes](https://docs.nt3.io/self-hosting/kubernetes.md#configuration-and-secrets).

At startup, Entri checks the required variables and exits with one error that lists everything missing. In production (`NODE_ENV=production`, the image default), it also logs warnings when `BETTER_AUTH_URL` or `APP_HOST` is unset or points at localhost, and when `ENCRYPTION_KEY` is missing or malformed.

Boolean flags are compared case-insensitively. Only the exact value shown (`true` or `false`) switches the behavior.

## Required

| Variable | Default | Description |
| - | - | - |
| `MONGO_URI` | — | MongoDB connection string. Must point at a **replica set** (or Atlas) and include the database name in the path, for example `mongodb://user:pass@mongo:27017/entri?authSource=admin&replicaSet=rs0`. See [Database](#database). |
| `REDIS_URI` | — | Redis connection string, for example `redis://:password@redis:6379`. |
| `BETTER_AUTH_SECRET` | — | Signs sessions. At least 32 characters: `openssl rand -base64 48`. Changing it signs everyone out. |

## Recommended

| Variable | Default | Description |
| - | - | - |
| `BETTER_AUTH_URL` | `http://localhost:3333` | Public base URL of the instance, without a trailing slash, for example `https://entri.example.com`. Used for auth redirects and OAuth callback URLs. |
| `APP_HOST` | `http://localhost:4200` | Public URL of the web app. With the single image, this is the same as `BETTER_AUTH_URL`. Used as the trusted origin for auth, in links in emails, for the GitHub App post-install redirect, and for the default GitHub sync committer email. |
| `ENCRYPTION_KEY` | — | 64 hex characters: `openssl rand -hex 32`. Encrypts organization AI keys and cached GitHub installation tokens at rest. Without it, organization AI keys and the GitHub integration do not work. **Back it up, and never change it** once data has been encrypted with it. |

## Server

| Variable | Default | Description |
| - | - | - |
| `PORT` | `3333` | HTTP port inside the container. The Helm chart sets it from `containerPort`. |
| `TRUST_PROXY` | `loopback, linklocal, uniquelocal` | Which proxies Entri trusts for `X-Forwarded-For` (the client IP, used by the rate limiter). The default trusts peers on loopback, link-local and private networks, such as a proxy in the Compose network or an in-cluster ingress. Accepts any Express `trust proxy` value: `true`, `false`, a hop count (`1`), or a list of addresses or CIDRs (`10.0.0.0/8, 172.16.0.0/12`). Change it only if the proxy in front of Entri has a public IP. |
| `ALLOWED_ORIGINS` | `http://localhost:4200` | Comma-separated origins allowed to make cross-origin (CORS) requests with credentials. Not needed when the web app is served by the same image, which is the default. |
| `NODE_ENV` | `production` (image) | `production` turns off the GraphQL playground and introspection and turns on the configuration warnings. Leave it as is. |
| `APP_VERSION` | `dev` | Version string reported by `GET /api/v1/config`. Release images set it to their version; you only need it for custom builds. |

## Auth and sign-up

| Variable | Default | Description |
| - | - | - |
| `DISABLE_SIGNUP` | `false` | `true` blocks self-service sign-up, for email and password and for social login. The first user on an empty instance and people with a pending, unexpired invitation can still sign up. |

Sessions last 7 days and are refreshed daily. This is not configurable.

## Email

Without a transport, emails (invitations, password resets) are written to the log. Users then cannot reset forgotten passwords themselves.

| Variable | Default | Description |
| - | - | - |
| `EMAIL_PROVIDER` | auto | `smtp` or `resend`. When unset, Entri uses SMTP if `SMTP_HOST` is set, otherwise Resend if `RESEND_API_KEY` is set, otherwise the log. Any other value stops startup. |
| `EMAIL_FROM` | `Entri <noreply@localhost>` | Sender address. **Required** for SMTP and Resend. Entri does not start without it. |
| `SMTP_HOST` | — | SMTP server. Required when `EMAIL_PROVIDER=smtp`. |
| `SMTP_PORT` | `587` | |
| `SMTP_SECURE` | `false` | `true` for implicit TLS. Port `465` always uses implicit TLS. |
| `SMTP_USER` | — | SMTP username |
| `SMTP_PASS` | — | SMTP password (secret) |
| `RESEND_API_KEY` | — | [Resend](https://resend.com) API key (secret). Required when `EMAIL_PROVIDER=resend`. |

## AI translation

Each organization can store its own OpenAI and Anthropic keys in its settings (encrypted with `ENCRYPTION_KEY`). The variables below are instance-wide **fallbacks**, used by every organization that has not set its own key.

| Variable | Default | Description |
| - | - | - |
| `OPENAI_API_KEY` | — | Fallback OpenAI key (secret) |
| `ANTHROPIC_API_KEY` | — | Fallback Anthropic key (secret) |
| `DEFAULT_AI_PROVIDER` | — | `openai` or `anthropic`. Picks that provider's default model when neither the request nor the project names a model. When unset, the default model is an Anthropic model. |

## Search

| Variable | Default | Description |
| - | - | - |
| `SEARCH_PROVIDER` | — | `typesense` or `algolia`. Unset: search uses MongoDB queries. If the provider's credentials are missing, Entri logs a warning and search indexing stays disabled. |
| `TYPESENSE_HOST` | — | Typesense host, for example `typesense` in the Compose network |
| `TYPESENSE_PORT` | `8108` | |
| `TYPESENSE_PROTOCOL` | `http` | |
| `TYPESENSE_API_KEY` | — | Typesense API key (secret) |
| `ALGOLIA_APP_ID` | — | Algolia application ID |
| `ALGOLIA_API_KEY` | — | Algolia API key with write access (secret) |

After you enable a provider, index existing projects once with `POST /api/v1/admin/search/sync/<projectId>` (session or API token of the project's organization). New changes are indexed automatically.

## Social login

A provider is enabled only when both its client ID and secret are set. Register an OAuth app with each provider and use these callback URLs:

* Google: `https://entri.example.com/api/auth/callback/google`
* GitHub: `https://entri.example.com/api/auth/callback/github`

| Variable | Default | Description |
| - | - | - |
| `GOOGLE_CLIENT_ID` | — | Google OAuth client ID |
| `GOOGLE_CLIENT_SECRET` | — | Google OAuth client secret (secret) |
| `GITHUB_CLIENT_ID` | — | GitHub OAuth app client ID, for "Sign in with GitHub" |
| `GITHUB_CLIENT_SECRET` | — | GitHub OAuth app client secret (secret) |

These are separate from the GitHub App variables below.

## GitHub App (translation sync)

The GitHub integration appears in the UI only when all six required variables are set, and it also needs `ENCRYPTION_KEY`. Follow [GitHub App setup](https://docs.nt3.io/platform/integrations/github-app-setup.md) to create the App.

| Variable | Default | Description |
| - | - | - |
| `GITHUB_APP_ID` | — | App ID |
| `GITHUB_APP_SLUG` | — | URL slug of the App (`github.com/apps/<slug>`) |
| `GITHUB_APP_CLIENT_ID` | — | App client ID |
| `GITHUB_APP_CLIENT_SECRET` | — | App client secret (secret) |
| `GITHUB_APP_PRIVATE_KEY` | — | PEM private key (secret). In a `.env` file, put it on one line with literal `\n` and wrap it in double quotes. |
| `GITHUB_STATE_SECRET` | — | HMAC secret that signs the install `state` (secret). `openssl rand -hex 32`. Do not reuse `ENCRYPTION_KEY`. |
| `GITHUB_BOT_EMAIL` | `noreply@<hostname of APP_HOST>` | Committer email for sync commits |

## Database

| Variable | Default | Description |
| - | - | - |
| `MONGO_TRANSACTIONS` | `true` | `false` turns off multi-document transactions in the auth layer, so Entri can run on a **standalone** `mongod`. Use it only as a last resort: sign-up and other auth writes lose their all-or-nothing guarantee. Prefer a single-node replica set. |
| `AUTO_INDEX` | `true` | `false` stops Entri from creating MongoDB indexes at startup. Use it only if you manage indexes yourself, for example on very large collections. |
| `MONGO_DB_NAME` | — | Read only by `migrate`. Overrides the database name for migrations. |

> [!WARNING]
>
> Always put the database name in the path of `MONGO_URI` (`.../entri?...`). The app uses that database. If the path is empty, the app falls back to MongoDB's default `test` database (and logs a warning in production), and `migrate` refuses to run unless `MONGO_DB_NAME` is set. `MONGO_DB_NAME` affects only `migrate`, so it cannot make the app use a different database.

## Docker Compose settings

These are read by `docker compose`, not by Entri:

| Variable | Default | Description |
| - | - | - |
| `ENTRI_VERSION` | `latest` | Image tag to run. Pin a version in production. |
| `ENTRI_PORT` | `3333` | Host port mapping for Entri. Use `127.0.0.1:3333` behind the bundled Caddy. |
| `ENTRI_DOMAIN` | `localhost` | Hostname Caddy gets a certificate for (`--profile tls`) |
| `MONGO_ROOT_USERNAME` | `entri` | Bundled MongoDB root user |
| `MONGO_ROOT_PASSWORD` | — | **Required.** Bundled MongoDB root password (URL-safe) |
| `REDIS_PASSWORD` | — | **Required.** Bundled Redis password (URL-safe) |
| `COMPOSE_PROFILES` | — | Standard Compose variable, for example `tls,search`, so you don't have to pass `--profile` on every command |

Compose builds `MONGO_URI` and `REDIS_URI` from these unless you set them yourself.

## CLI

The [`nt3` CLI](https://docs.nt3.io/developers/cli/overview) reads these on the machine where it runs:

| Variable | Description |
| - | - |
| `NT3_API_URL` | Base URL of your instance, for example `https://entri.example.com`. Overrides every configured URL. Without it, and without `api_url` in a config file, the CLI uses `https://app.nt3.io`. |
| `NT3_API_TOKEN` | API token. Overrides any stored token. It is only sent to `NT3_API_URL` (or `https://app.nt3.io` when that is unset). |
| `NT3_TRUST_PROJECT_URL` | `1` lets `NT3_API_TOKEN` go to the `api_url` from the repository's `.nt3.yml` or `.nt3.local.json`. |
| `NT3_ALLOW_INSECURE` | `1` allows plain-`http` API URLs to hosts other than localhost. |

To point a whole team at your instance, add `api_url: https://entri.example.com` to `.nt3.yml`. See [CLI configuration](https://docs.nt3.io/developers/cli/configuration.md).

## Instance endpoints

### Public configuration

`GET /api/v1/config` needs no authentication. The web app uses it to decide what to show:

```bash theme={null}
curl -s https://entri.example.com/api/v1/config
```

```json theme={null}
{
  "signupEnabled": false,
  "socialProviders": { "google": true, "github": false },
  "githubAppEnabled": true,
  "version": "1.2.3"
}
```

| Field | Derived from |
| - | - |
| `signupEnabled` | `DISABLE_SIGNUP` is not `true` |
| `socialProviders` | Both client ID and secret are set for that provider |
| `githubAppEnabled` | All six required `GITHUB_APP_*` / `GITHUB_STATE_SECRET` variables are set |
| `version` | `APP_VERSION`, or `dev` |

### Health

| Endpoint | Checks | Use |
| - | - | - |
| `GET /api/v1/health/liveness` | Process is up | Liveness and startup probes, the image `HEALTHCHECK` |
| `GET /api/v1/health/readiness` | MongoDB and Redis respond | Readiness probes, load balancer health checks |
| `GET /api/v1/health` | Same as readiness | Monitoring |

The health endpoints need no authentication. The OpenAPI explorer is served at `/api/docs`.


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