Kaneo Database Options: PostgreSQL Configuration Guide for Production and Development
Kaneo primarily runs on PostgreSQL with three connection methods—full DATABASE_URL, individual POSTGRES_* environment variables, or a local SQLite fallback for development.
Kaneo is an open-source project management platform built with a PostgreSQL-centric architecture. While other databases are not natively supported, the platform offers flexible configuration options for connecting to PostgreSQL instances across different environments. This guide breaks down every database option available in Kaneo based on the actual source code implementation.
Primary Database: PostgreSQL
Kaneo's entire data layer is engineered around PostgreSQL. The schema definitions in apps/api/src/database/schema.ts use Drizzle ORM's PostgreSQL dialect, making the codebase tightly coupled to PostgreSQL-specific types and features. According to the Kaneo source code, switching to MySQL, MariaDB, or NoSQL alternatives would require extensive modifications to the schema and query logic.
Three Ways to Configure Your Database
Kaneo resolves its database connection through a cascading priority system defined in apps/api/src/database/resolve-database-url.ts. The platform checks for configuration in this order:
1. Full DATABASE_URL Connection String
The most direct method for production deployments. Set a single environment variable containing a complete PostgreSQL URI.
DATABASE_URL=postgresql://kaneo:strong-pass@db.myhost.com:5432/kaneo
This approach is recommended for production because it supports all PostgreSQL connection features, including SSL modes, connection pooling parameters, and advanced authentication schemes. The resolve-database-url.ts module uses this value verbatim when present.
2. Individual POSTGRES Environment Variables
When DATABASE_URL is unset, Kaneo automatically constructs the connection string from discrete variables. This is the default for Docker Compose deployments.
POSTGRES_USER=kaneo
POSTGRES_PASSWORD=changeme
POSTGRES_DB=kaneo
POSTGRES_HOST=postgres # optional, defaults to "localhost"
POSTGRES_PORT=5432 # optional, defaults to 5432
The derivation logic in apps/api/src/database/resolve-database-url.ts assembles these into postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}. This method keeps secrets out of URLs and integrates cleanly with container orchestration secrets management.
3. SQLite Fallback for Local Development
When neither DATABASE_URL nor any POSTGRES_* variables are defined, Kaneo falls back to an in-memory SQLite database. This zero-configuration mode is ideal for:
- Quick local API testing
- CI pipeline runs without PostgreSQL infrastructure
- Development environments where persistence is unnecessary
# No environment variables required
npm run dev
# API starts with ephemeral SQLite database
Note that this fallback is implemented solely for convenience. Data disappears when the process exits, and certain PostgreSQL-specific features may behave differently.
Docker Compose Default Setup
The official docker-compose.yml documented in apps/docs/core/installation/docker-compose.mdx provides a batteries-included PostgreSQL service:
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: kaneo
POSTGRES_PASSWORD: changeme
POSTGRES_DB: kaneo
volumes:
- postgres_data:/var/lib/postgresql/data
api:
environment:
POSTGRES_USER: kaneo
POSTGRES_PASSWORD: changeme
POSTGRES_DB: kaneo
POSTGRES_HOST: postgres
depends_on:
- postgres
This configuration automatically satisfies the individual POSTGRES variables method, requiring no DATABASE_URL management.
External and Cloud-Hosted PostgreSQL
Kaneo connects to any PostgreSQL instance accessible via TCP. Deployment documentation in apps/docs/core/deployments/railway.mdx demonstrates connecting to managed services like Railway, but the same pattern applies to:
- AWS RDS PostgreSQL
- Google Cloud SQL
- Azure Database for PostgreSQL
- Self-hosted instances
Use the full DATABASE_URL method for external connections to capture all connection parameters:
# Railway example with SSL
DATABASE_URL=postgresql://kaneo:${{Postgres.DATABASE_PASSWORD}}@${{Postgres.RW_HOST}}:5432/railway?sslmode=require
Database Startup Validation
Before accepting connections, apps/api/src/database/prepare-database-startup.ts performs validation:
- Verifies the resolved connection string is parseable
- Attempts initial connection with meaningful error messages
- Logs the configured database host (without credentials) for debugging
This startup guard prevents cryptic failures later in application initialization.
What Kaneo Does Not Support
Based on the schema implementation in apps/api/src/database/schema.ts:
- MySQL/MariaDB — Drizzle ORM dialect mismatch
- SQLite for production — Schema uses PostgreSQL-specific types (UUID, JSONB, arrays)
- MongoDB or other NoSQL — Relational schema design with foreign key constraints
Database Schema and Migrations
All table definitions reside in apps/api/src/database/schema.ts using Drizzle's PostgreSQL column builders:
// Excerpt from schema.ts — PostgreSQL-specific types
import { pgTable, serial, varchar, timestamp, uuid, jsonb } from 'drizzle-orm/pg-core';
export const workspaces = pgTable('workspaces', {
id: uuid('id').defaultRandom().primaryKey(),
name: varchar('name', { length: 255 }).notNull(),
settings: jsonb('settings').default({}),
createdAt: timestamp('created_at').defaultNow(),
});
The uuid, jsonb, and timestamp types are PostgreSQL-native. Migration files are generated against PostgreSQL dialect and cannot be applied to other databases.
Summary
- Kaneo requires PostgreSQL for production use, with schema definitions locked to Drizzle's PostgreSQL dialect.
- Three configuration methods: full
DATABASE_URL(production), individualPOSTGRES_*variables (Docker default), or SQLite fallback (development only). - External databases work via
DATABASE_URLpointing to any accessible PostgreSQL instance. - No native support for MySQL, MariaDB, or NoSQL alternatives—migrating would require rewriting
schema.tsand all queries.
Frequently Asked Questions
Can Kaneo run on MySQL or MariaDB instead of PostgreSQL?
No. Kaneo's schema in apps/api/src/database/schema.ts uses PostgreSQL-specific types including uuid, jsonb, and native timestamps. The Drizzle ORM configuration is hardcoded to the PostgreSQL dialect throughout the API codebase.
How do I connect Kaneo to an existing PostgreSQL database?
Set DATABASE_URL to a valid PostgreSQL connection URI. For SSL-secured cloud instances, include ?sslmode=require or equivalent parameters in the URL. Alternatively, populate POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, and POSTGRES_HOST to have Kaneo construct the connection string automatically.
What happens if I don't configure any database environment variables?
Kaneo falls back to an in-memory SQLite database via the logic in apps/api/src/database/resolve-database-url.ts. This mode is intended for development and testing only—all data is lost when the API process terminates, and some PostgreSQL features may not behave identically.
Is the SQLite fallback safe for production use?
No. The SQLite fallback uses an in-memory store with no persistence guarantees. For production deployments, configure a persistent PostgreSQL instance using either DATABASE_URL or the individual POSTGRES_* variables method.
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 →