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 endpointS3_BUCKET: Target bucket nameS3_ACCESS_KEY_IDandS3_SECRET_ACCESS_KEY: CredentialsS3_REGION: Geographic regionS3_FORCE_PATH_STYLE: Set totruefor MinIO or non-AWS providersS3_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:
- GitHub:
GITHUB_OAUTH_CLIENT_ID,GITHUB_OAUTH_CLIENT_SECRET(used inapps/api/src/plugins/github/webhooks/issue-opened.tsline 141) - Google:
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET(apps/api/src/auth.tslines 173-176) - Discord:
DISCORD_CLIENT_ID,DISCORD_CLIENT_SECRET(apps/api/src/plugins/discord/events.tsline 109) - Custom OAuth:
CUSTOM_OAUTH_CLIENT_ID,CUSTOM_OAUTH_CLIENT_SECRET,CUSTOM_OAUTH_AUTHORIZE_URL,CUSTOM_OAUTH_TOKEN_URL,CUSTOM_OAUTH_USER_INFO_URL(apps/api/src/auth.tslines 180-190)
Email and Billing
- SMTP settings:
SMTP_HOST,SMTP_PORT,SMTP_USER,SMTP_PASSWORD,SMTP_FROM(required for invitation emails inapps/api/src/email/send-email.ts) - Stripe integration:
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET(used inapps/api/src/billing/stripe.tsandstripe-webhook.ts)
Step-by-Step Configuration
-
Create the
.envfile at the repository root:touch .env -
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 -
Add feature-specific variables based on your infrastructure (Redis, S3, OAuth).
-
Secure the file by ensuring
.envis listed in.gitignoreto prevent accidental commits of secrets. -
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_SECRETtoo short: The API aborts startup with "AUTH_SECRET is less than 32 characters" if the secret is under 32 characters (apps/api/src/auth.tslines 105-107).- CORS failures: Missing
KANEO_CLIENT_URLor misconfiguredCORS_ORIGINScauses the API to reject cross-origin requests (apps/api/src/index.tsline 181). - Database connection errors: Verify
DATABASE_URLformat includes the full protocol (postgresql://) as expected byapps/api/src/database/prepare-database-startup.ts(line 23). - S3 upload failures: For non-AWS providers, ensure
S3_FORCE_PATH_STYLE=trueis set, and verify endpoint credentials inapps/api/src/storage/s3.ts.
Summary
- Kaneo uses a single
.envfile 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), andDATABASE_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_SECRETis 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →