# How to Manage Kaneo's Configuration Files: Complete Environment Setup Guide

> Master Kaneo's configuration files with this guide. Learn how Kaneo centralizes settings in .env files for seamless environment setup and Docker integration.

- Repository: [kaneo.app/kaneo](https://github.com/usekaneo/kaneo)
- Tags: how-to-guide
- Published: 2026-08-08

---

**Kaneo centralizes all runtime settings in a single `.env` file at the repository root, which Docker Compose mounts into containers and the [`apps/web/env.sh`](https://github.com/usekaneo/kaneo/blob/main/apps/web/env.sh) script processes to inject values into static assets.**

Managing Kaneo's configuration files requires understanding its environment-variable-driven architecture. The usekaneo/kaneo repository uses a unified configuration approach where both the API and web frontend consume settings from one `.env` file or its template counterpart `.env.sample`. This design ensures consistency across local development, Docker Compose deployments, and Kubernetes environments.

## Understanding the Configuration Structure

Kaneo consolidates configuration into a single **`.env`** file located at the repository root. This file follows the conventional `key=value` format and serves as the source of truth for all runtime settings. The repository provides **`.env.sample`** as a comprehensive template listing every supported variable.

The configuration system handles two distinct runtimes:

- **API Layer**: Reads variables directly via Node's `process.env` without transformation
- **Web Frontend**: Processes variables through [`apps/web/env.sh`](https://github.com/usekaneo/kaneo/blob/main/apps/web/env.sh) to rewrite placeholders in built static assets

## Core Environment Variables

### Application Endpoints

Configure access URLs through these critical variables:

- **`KANEO_CLIENT_URL`**: The URL where the web UI is served (default: `http://localhost:5173`)
- **`KANEO_API_URL`**: The API service endpoint (defaults to `KANEO_CLIENT_URL/api` when omitted)

### Database and Authentication

Secure your instance with these required settings:

- **`DATABASE_URL`**: Direct PostgreSQL connection string. Alternatively, provide individual `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_HOST` variables, and Kaneo constructs the connection string automatically when a password or host is provided.
- **`AUTH_SECRET`**: JWT signing secret for session management. If absent, Kaneo auto-generates one, but persistence across restarts requires explicit configuration.

### Optional Services

Enable enhanced functionality through Redis configuration for WebSocket pub/sub:

- **`REDIS_URL`**: Single instance connection string
- **`REDIS_SENTINELS`**: Sentinel configuration for high availability
- **`REDIS_CLUSTER_NODES`**: Cluster node addresses for distributed deployments

### Feature Toggles

Control optional behaviors with boolean flags defined in `.env.sample`:

- **`KANEO_CLOUD`**: Enables cloud-mode abuse mitigations
- **`DISABLE_EMAIL_OTP_SIGN_IN`**: Disables email-based OTP authentication
- **Turnstile Captcha**: Configure via related environment variables

## Configuration Loading Order

Kaneo processes environment variables through a specific sequence defined in [`compose.yml`](https://github.com/usekaneo/kaneo/blob/main/compose.yml) and the container startup scripts:

1. **Docker Compose mounts** the `.env` file into each container using `env_file: - .env` configuration
2. **API initialization** reads values directly via `process.env` without additional processing
3. **Frontend preparation** executes [`apps/web/env.sh`](https://github.com/usekaneo/kaneo/blob/main/apps/web/env.sh) at container startup, scanning built JavaScript and CSS assets for placeholders matching variable names
4. **Placeholder substitution** replaces tokens like `KANEO_API_URL` with actual values. The script strips unset placeholders to prevent "truthy" string values that could break sign-up flows

The [`apps/web/env.sh`](https://github.com/usekaneo/kaneo/blob/main/apps/web/env.sh) script contains a loop that automatically processes any remaining variable prefixed with `KANEO_*`, making the system extensible without modifying the shell script itself.

## Customizing Configuration

### Creating Your Configuration File

Start by copying the template:

```bash
cp .env.sample .env

```

Edit `.env` to include required values:

```dotenv

# .env

KANEO_CLIENT_URL=http://localhost:5173
POSTGRES_DB=kaneo
POSTGRES_USER=kaneo
POSTGRES_PASSWORD=super-secret
AUTH_SECRET=$(openssl rand -hex 32)

```

### Runtime Overrides

Override specific variables for single executions without modifying `.env`:

```bash
KANEO_API_URL=http://api.myhost.com pnpm dev

```

CLI environment variables take precedence over `.env` file values.

### Adding Custom Feature Flags

Extend functionality with custom variables:

1. Add to `.env`:

   ```dotenv
   KANEO_FEATURE_X_ENABLED=true
   ```

2. Access in the API via `process.env.KANEO_FEATURE_X_ENABLED`
3. Reference the placeholder `KANEO_FEATURE_X_ENABLED` in frontend TypeScript code; [`env.sh`](https://github.com/usekaneo/kaneo/blob/main/env.sh) substitutes it at runtime according to the loop processing `KANEO_*` keys

## Deployment Workflow

Deploy Kaneo using Docker Compose or the Helm chart:

```bash
docker compose up -d

```

Monitor the replacement process:

```bash
docker compose logs -f kaneo

```

Look for "✅ Replaced …" messages confirming [`apps/web/env.sh`](https://github.com/usekaneo/kaneo/blob/main/apps/web/env.sh) successfully substituted placeholders in static assets.

## Summary

- Kaneo uses a single `.env` file at the repository root for all configuration, mounted via [`compose.yml`](https://github.com/usekaneo/kaneo/blob/main/compose.yml) using `env_file: - .env`
- The API reads variables via `process.env`, while the frontend relies on [`apps/web/env.sh`](https://github.com/usekaneo/kaneo/blob/main/apps/web/env.sh) to inject values into built assets and strip unset placeholders
- Core variables include `KANEO_CLIENT_URL`, `DATABASE_URL` (or `POSTGRES_*` alternatives), and `AUTH_SECRET` which requires explicit setting for persistence across restarts
- Redis clustering and feature toggles like `KANEO_CLOUD` configure optional services
- Any `KANEO_` prefixed variable is automatically processed by the frontend shell script's loop for extensibility

## Frequently Asked Questions

### Where does Kaneo store its configuration files?

Kaneo stores all configuration in a `.env` file at the repository root. Docker Compose mounts this file into containers at runtime as specified in [`compose.yml`](https://github.com/usekaneo/kaneo/blob/main/compose.yml), and the [`apps/web/env.sh`](https://github.com/usekaneo/kaneo/blob/main/apps/web/env.sh) script processes these values to configure the frontend. No external configuration directories or additional files are required.

### How do I add custom environment variables to Kaneo?

Add any variable prefixed with `KANEO_` to your `.env` file. The [`apps/web/env.sh`](https://github.com/usekaneo/kaneo/blob/main/apps/web/env.sh) script automatically detects these variables through its loop processing `KANEO_*` keys, substituting placeholders in the built static assets. In the API, access custom variables directly via `process.env.YOUR_VARIABLE_NAME`.

### Can I run Kaneo without a .env file?

While possible for testing using CLI environment variables, production deployments require the `.env` file for persistence. You can override specific values via command line (e.g., `KANEO_API_URL=http://api.example.com docker compose up`), but the file ensures consistent configuration across restarts and proper secret management for `AUTH_SECRET`.

### Why are my environment variables not appearing in the frontend?

The frontend requires variables to be processed by [`apps/web/env.sh`](https://github.com/usekaneo/kaneo/blob/main/apps/web/env.sh) at container startup. Verify that variables are defined in `.env` and mounted via [`compose.yml`](https://github.com/usekaneo/kaneo/blob/main/compose.yml), and check that container logs show "✅ Replaced …" messages indicating successful substitution. Unset placeholders are stripped by the script to prevent breaking authentication flows, so missing variables won't appear as literal strings.