This guide will help you set up the Kaneo development environment and troubleshoot common issues.
-
Create a
.envfile in the root of the project with the required environment variables (see the documentation for the complete list). -
Start the development servers:
pnpm dev
This starts both the API (port 1337) and web app (port 5173). Both will automatically reload when you make changes.
Tip: The web app at http://localhost:5173 will automatically connect to the API at http://localhost:1337
Kaneo uses a single .env file in the root of the project for all environment variables. This file is shared by both the API and web services.
For development, you'll need at minimum:
KANEO_CLIENT_URL- The URL of the web application (e.g.,http://localhost:5173)KANEO_API_URL- The URL of the API (e.g.,http://localhost:1337)AUTH_SECRET- Secret key for JWT token generation (must be at least 32 characters long; use a long, random value in production)DEVICE_AUTH_CLIENT_IDS- Optional. Comma-separated list of allowed device-flow OAuth client IDs. When unset, Kaneo implicitly allowskaneo-cliandkaneo-mcpby default (no extra configuration for the CLI or MCP). Override only when you need additional trusted clients, for examplekaneo-cli,kaneo-mcp,my-desktop-app.DATABASE_URL- PostgreSQL connection stringPOSTGRES_DB- PostgreSQL database namePOSTGRES_USER- PostgreSQL usernamePOSTGRES_PASSWORD- PostgreSQL password
If your app uses a device client ID that is not included in the defaults, set DEVICE_AUTH_CLIENT_IDS to the full comma-separated list of allowed IDs (including any defaults you still need), so it includes the client ID your app sends to /api/auth/device/code.
For local development, the web app also supports:
VITE_API_URL- API URL for development (defaults tohttp://localhost:1337if not set)VITE_APP_URL- App URL for generating links (optional)
Kaneo supports many optional configuration options including:
- SSO providers (GitHub OAuth via
GITHUB_OAUTH_CLIENT_ID/GITHUB_OAUTH_CLIENT_SECRET, Google, Discord, Custom OAuth/OIDC) - GitHub repository integration (GitHub App:
GITHUB_APP_ID,GITHUB_PRIVATE_KEY,GITHUB_WEBHOOK_SECRET, optionalGITHUB_APP_NAME), separate from GitHub SSO - SMTP configuration for email
- Access control settings
- CORS configuration
- Redis for horizontal scaling
- Private-network notification receivers (
KANEO_ALLOW_PRIVATE_WEBHOOK_DESTINATIONS=truelets ntfy/Gotify/webhook destinations resolve to private addresses; off by default to prevent SSRF)
Kaneo supports three Redis deployment modes for WebSocket Pub/Sub. When any Redis mode is configured, WebSocket broadcasts use Redis Pub/Sub, allowing multiple API instances to relay real-time updates. When none are set, an in-memory adapter is used (single-instance only).
Standalone (single server):
REDIS_URL- Redis connection string (e.g.,redis://localhost:6379)
Sentinel (high-availability with automatic failover):
REDIS_SENTINELS- Comma-separated list of Sentinel nodes (e.g.,sentinel-1:26379,sentinel-2:26379,sentinel-3:26379)REDIS_SENTINEL_MASTER_NAME- Name of the Sentinel master group (default:mymaster)REDIS_SENTINEL_PASSWORD- Password for Sentinel instances, if different from the Redis password (optional)REDIS_SENTINEL_TLS- Set totrueto enable TLS for Sentinel connections (default:false)
Cluster (horizontal sharding):
REDIS_CLUSTER_NODES- Comma-separated list of cluster seed nodes (e.g.,node-1:6379,node-2:6379,node-3:6379)
Shared (used by Sentinel and Cluster modes):
REDIS_PASSWORD- Password for the Redis data nodes (used by both Sentinel and Cluster modes, not for Sentinel auth itself; useREDIS_SENTINEL_PASSWORDfor that)
Note: Only one mode should be configured at a time. If multiple are set, the priority is: Cluster > Sentinel > Standalone.
For sending emails (workspace invitations, magic links, etc.), configure these variables:
SMTP_HOST- SMTP server hostnameSMTP_PORT- SMTP server portSMTP_USER- SMTP usernameSMTP_PASSWORD- SMTP passwordSMTP_FROM- From email addressSMTP_SECURE- Use TLS (default:true, set tofalseto disable)SMTP_REQUIRE_TLS- Require TLS (default:false, set totrueto require)SMTP_IGNORE_TLS- Ignore TLS certificate errors (default:false, set totruefor self-signed certificates)
Note: If you're using an SMTP server with a self-signed or invalid TLS certificate, set
SMTP_IGNORE_TLS=trueto bypass certificate validation.
When SMTP is configured, sign-in uses email verification codes by default. Set DISABLE_EMAIL_OTP_SIGN_IN=true to use email/password sign-in instead (workspace invitation emails still use SMTP).
Hosted multi-tenant instances should enable the cloud abuse gates. Self-hosted instances can leave these unset.
KANEO_CLOUD- Set totrueto enable cloud-only protections: disposable-email signup block, Turnstile captcha enforcement, guest-account invite block, and tightened rate limits on/sign-up/emailand/organization/invite-member.TURNSTILE_SECRET_KEY- Cloudflare Turnstile secret key (API container, server-side verification). When unset, captcha verification is skipped.KANEO_TURNSTILE_SITE_KEY- Cloudflare Turnstile site key, on the web container. The production web image bakes the literal placeholderKANEO_TURNSTILE_SITE_KEYinto the bundle;apps/web/env.shswaps it for the runtime value when the container starts.VITE_TURNSTILE_SITE_KEY- Local dev only. Set inapps/web/.envwhen runningpnpm dev; Vite reads this at build/dev time. Not used in the production image.
All Sentry integration is opt-in; leave these unset for zero telemetry.
SENTRY_DSN- Sentry DSN for the API. When unset, the Sentry SDK never initializes.SENTRY_ENVIRONMENT- Environment tag for API events (defaults toNODE_ENV).SENTRY_TRACES_SAMPLE_RATE- Fraction of API requests to trace for performance monitoring,0-1(default:0, tracing off).KANEO_SENTRY_DSN- Sentry DSN for the web container (browser errors, tracing, session replay). Same runtime-placeholder mechanism asKANEO_TURNSTILE_SITE_KEY.VITE_SENTRY_DSN- Local dev only. Set inapps/web/.envwhen runningpnpm dev.
For a complete list of all environment variables, their descriptions, and configuration options, see the official documentation.
Symptoms:
- "Failed to fetch" errors in browser console
- Network errors when making API requests
- "Access to fetch at '...' from origin '...' has been blocked by CORS policy"
Solutions:
-
Check URL Configuration:
- Ensure
KANEO_API_URLmatches your API server URL - Ensure
KANEO_CLIENT_URLmatches your web app URL - For development, you can also set
VITE_API_URLin your.envfile
- Ensure
-
Configure CORS Origins:
- Add your frontend URL to
CORS_ORIGINSin your.env:CORS_ORIGINS=http://localhost:5173,https://yourdomain.com - For development, you can leave
CORS_ORIGINSempty to allow all origins - Note:
CORS_ORIGINSshould matchKANEO_CLIENT_URLfor proper authentication
- Add your frontend URL to
-
Check Protocol Consistency:
- Ensure both frontend and API use the same protocol (http/https)
- Don't mix http and https in development
-
Verify Server Accessibility:
- Test if the API is accessible:
curl http://localhost:1337/config - Check if the server is running on the correct port
- Test if the API is accessible:
Symptoms:
- "Database connection failed" errors
- API server won't start
Solutions:
-
Check PostgreSQL:
- Ensure PostgreSQL is running
- Verify database exists and credentials are correct
- Test connection:
psql $DATABASE_URL
-
Update DATABASE_URL:
- Ensure the connection string format is correct
- Check username, password, host, port, and database name
-
Match the hostname to where the API runs:
- Use
postgresonly when the API container is on the same Docker Compose network as the Postgres service - Use
localhostwhen the API runs directly on your host machine - If you see
getaddrinfo EAI_AGAIN postgres, the API is trying to resolve the Compose hostname from the wrong network context
- Use
-
Use the right configuration mode:
- For host-native development, prefer an explicit
DATABASE_URL - If you derive from
POSTGRES_*, setPOSTGRES_HOST=localhostwhen running the API on your host POSTGRES_DBandPOSTGRES_USERby themselves do not switch Kaneo into derived connection mode
- For host-native development, prefer an explicit
Symptoms:
- "Authentication failed" errors
- Users can't sign in
Solutions:
-
Check Authentication Configuration:
- Ensure
AUTH_SECRETis set in your.envfile - Use a strong secret in production
- Verify
KANEO_CLIENT_URLandKANEO_API_URLare correctly configured
- Ensure
-
Clear Browser Data:
- Clear cookies and local storage
- Try in incognito/private mode
Symptoms:
- "Network error" messages
- API requests timeout
Solutions:
-
Check Server Status:
- Verify API server is running
- Check server logs for errors
-
Check Firewall/Proxy:
- Ensure ports are not blocked
- Check if proxy settings interfere
-
Verify URLs:
- Check that all URLs are accessible
- Test with curl or browser
- Use
http://localhostfor both frontend and API - Leave
CORS_ORIGINSempty to allow all origins (or set it to match your local URLs) - Use simple secrets for
AUTH_SECRET(not for production) - The web app will use
VITE_API_URLif set, otherwise defaults tohttp://localhost:1337
- Use HTTPS for both frontend and API
- Set specific
CORS_ORIGINSfor security (should matchKANEO_CLIENT_URL) - Use strong, unique secrets for
AUTH_SECRET - Configure proper database credentials
- Ensure
KANEO_CLIENT_URLandKANEO_API_URLare set to your production URLs
If you're still experiencing issues:
- Check the browser console for detailed error messages
- Review the API server logs
- Verify all environment variables are set correctly
- Ensure all services (PostgreSQL, API, Frontend) are running
- Consult the official documentation for detailed guides and troubleshooting
For the most up-to-date information on environment variables and configuration, always refer to the official documentation.