How to Configure Kaneo Environment Variables: Production Setup Guide

Kaneo requires a single .env file at the repository root containing core variables like KANEO_CLIENT_URL, AUTH_SECRET, and DATABASE_URL, which the API and web frontend read via process.env at startup.

Kaneo is an open-source project management platform that centralizes configuration through environment variables. To configure Kaneo environment variables for production deployment, you must populate a .env file with URLs, secrets, and database connections that both the API server and web application consume during initialization.

Required Environment Variables

Core Application URLs

KANEO_CLIENT_URL defines the public URL of the web application (e.g., https://kaneo.example.com). The API uses this to construct absolute links for invitations and webhooks in apps/api/src/auth.ts (line 71) and apps/api/src/index.ts (line 170).

KANEO_API_URL specifies the base URL of the API server. The web frontend reads this via VITE_API_URL at build time, as defined in apps/web/vite.config.ts (line 12).

Authentication Security

AUTH_SECRET requires a minimum 32-character string for JWT signing. The API validates this length on startup in apps/api/src/auth.ts (lines 105-107). If the secret is too short or missing, the server aborts immediately with an error message.

Database Connection

DATABASE_URL provides the full PostgreSQL connection string (e.g., postgresql://user:pass@host:5432/db). Drizzle ORM initializes the connection using this variable in apps/api/src/database/prepare-database-startup.ts (line 23).

POSTGRES_DB, POSTGRES_USER, and POSTGRES_PASSWORD support migration scripts and testing utilities in tests/api-integration/helpers/database.ts (lines 9-11).

Optional Environment Variables

Redis for WebSocket Broadcasting

Configure REDIS_URL (e.g., redis://host:6379) to enable multi-instance WebSocket broadcasting. If omitted, the system falls back to in-memory broadcasting, which breaks real-time sync across multiple server instances (see apps/api/src/ws/broadcast-adapter.ts lines 5-7).

Advanced Redis Sentinel or Cluster configurations use REDIS_SENTINELS, REDIS_CLUSTER_NODES, REDIS_SENTINEL_MASTER_NAME, REDIS_SENTINEL_PASSWORD, and REDIS_SENTINEL_TLS as defined in apps/api/src/ws/redis-config.ts.

S3-Compatible Storage

For image uploads, define these variables consumed in apps/api/src/storage/s3.ts (lines 12-23):

  • S3_ENDPOINT: Storage service endpoint
  • S3_BUCKET: Target bucket name
  • S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY: Credentials
  • S3_REGION: Geographic region
  • S3_FORCE_PATH_STYLE: Set to true for MinIO or non-AWS providers
  • S3_MAX_IMAGE_UPLOAD_BYTES: Upload limit (default 5 MiB)
  • S3_KEY_PREFIX: Optional path prefix (e.g., staging/)

OAuth and SSO Providers

Enable third-party authentication with provider-specific variables:

Email and Billing

Step-by-Step Configuration

  1. Create the .env file at the repository root:

    touch .env
  2. Add required variables:

    KANEO_CLIENT_URL=https://your-domain.com
    KANEO_API_URL=https://api.your-domain.com
    AUTH_SECRET=your-minimum-32-character-secret-key-here
    DATABASE_URL=postgresql://user:password@localhost:5432/kaneo
    CORS_ORIGINS=https://your-domain.com
  3. Add feature-specific variables based on your infrastructure (Redis, S3, OAuth).

  4. Secure the file by ensuring .env is listed in .gitignore to prevent accidental commits of secrets.

  5. Restart services to apply changes:

    pnpm --filter @kaneo/api dev
    pnpm --filter @kaneo/web dev

Code Implementation Examples

Reading variables in the API:

// apps/api/src/auth.ts
const clientUrl = process.env.KANEO_CLIENT_URL || "http://localhost:5173";
const secret = process.env.AUTH_SECRET || "";

if (secret.length < 32) {
  throw new Error("AUTH_SECRET is less than 32 characters...");
}

Frontend API URL resolution:

// apps/web/src/fetchers/project/get-project.ts
const base = import.meta.env.VITE_API_URL ?? process.env.KANEO_API_URL;

export async function getProject(id: string) {
  const res = await fetch(`${base}/api/project/${id}`);
  return res.json();
}

Generating invitation links with fallback:

// apps/web/src/lib/invitation-link.ts
export function createInvitationLink(token: string) {
  const origin = typeof window !== "undefined" 
    ? window.location.origin 
    : process.env.KANEO_CLIENT_URL;
  return `${origin}/invitation/accept/${token}`;
}

Troubleshooting Common Issues

  • AUTH_SECRET too short: The API aborts startup with "AUTH_SECRET is less than 32 characters" if the secret is under 32 characters (apps/api/src/auth.ts lines 105-107).
  • CORS failures: Missing KANEO_CLIENT_URL or misconfigured CORS_ORIGINS causes the API to reject cross-origin requests (apps/api/src/index.ts line 181).
  • Database connection errors: Verify DATABASE_URL format includes the full protocol (postgresql://) as expected by apps/api/src/database/prepare-database-startup.ts (line 23).
  • S3 upload failures: For non-AWS providers, ensure S3_FORCE_PATH_STYLE=true is set, and verify endpoint credentials in apps/api/src/storage/s3.ts.

Summary

  • Kaneo uses a single .env file at the repository root for all configuration, read by both the API and web frontend.
  • Required variables: KANEO_CLIENT_URL, KANEO_API_URL, AUTH_SECRET (minimum 32 characters), and DATABASE_URL.
  • Optional integrations: Redis for multi-instance scaling, S3 for file storage, OAuth providers for SSO, and SMTP for transactional email.
  • The API validates critical security requirements at startup and aborts if AUTH_SECRET is insufficient.
  • Frontend build variables use the VITE_ prefix to be exposed to the Vite build system.

Frequently Asked Questions

What happens if I don't set the AUTH_SECRET?

The API server will terminate immediately on startup with an error indicating the secret is missing or too short, as enforced by the validation logic in apps/api/src/auth.ts (lines 105-107).

Can I use environment variables without a .env file?

Yes. Kaneo reads from process.env, so Docker secrets, Kubernetes ConfigMaps, or systemd environment files work as long as variables are present when the Node.js process starts. The .env file is simply a convenience for local development.

How do I configure Redis for multiple Kaneo instances?

Set REDIS_URL to your Redis server address (e.g., redis://localhost:6379). For production clusters with Sentinel, configure REDIS_SENTINELS as a comma-separated list and provide REDIS_SENTINEL_MASTER_NAME and REDIS_SENTINEL_PASSWORD as defined in apps/api/src/ws/redis-config.ts.

Why are my S3 uploads failing?

Verify that S3_ENDPOINT, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, and S3_BUCKET match your provider's configuration. For non-AWS providers like MinIO or Wasabi, set S3_FORCE_PATH_STYLE=true as required by the S3 client initialization in apps/api/src/storage/s3.ts (line 22).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →