Databases
Nanokit provides a first-class database orchestration layer that handles provisioning, connection injection, branching, and lifecycle management across all environments.
Supported Engines
| Engine | Local Mode | Cloud Mode | Branching |
|---|---|---|---|
| PostgreSQL | Docker container | AWS RDS / existing host | ✅ |
MySQL (mysql) | Docker container | managed host | ✅ |
MariaDB (mariadb) | Docker container (mariadb:11) | managed host | ✅ |
| MongoDB | Docker container | MongoDB Atlas | ✅ |
| Redis | Docker container | managed host | ❌ (stateless) |
Planned: a self-hosted libSQL (
sqld) container engine is the near-term in-philosophy target (roadmap.v2). Managed serverless engines — Neon (CoW Postgres) and Turso (edge LibSQL) — are deferred pending real-account validation (roadmap.v3) and are not selectable today. See Providers → Roadmap.
Configuration
Databases are declared in the databases: block of nanokit.yml. The mode field switches between a locally managed Docker container and a cloud provider API.
databases:
main-postgres:
engine: postgres
mode: local # 'local' = Docker, 'cloud' = provider API
version: "16"
rootPassword: ${DB_PASSWORD}
branching:
enabled: true
strategy: snapshot # 'snapshot' clones data, 'empty' starts fresh
cache:
engine: redis
mode: localLocal Mode
In local mode, Nanokit boots a Docker container for the database and mounts a persistent named volume:
- Container name:
nk-<project>-<env>-<db-name> - Volume name:
nk-<project>-<env>-<db-name>-data
The database is automatically placed on the private nanokit-net network and is only reachable by other project services.
Cloud Mode
In cloud mode, Nanokit connects to a managed database provider API. Credentials and the provider endpoint are resolved from secrets.
databases:
main-postgres:
engine: postgres
mode: cloud
provider: rds # e.g. AWS RDS / managed Postgres host
connectionString: ${DATABASE_URL}Managed serverless providers (
neon,turso) are planned (roadmap.v3) and not selectable today — see the note under Supported Engines.
Automatic Connection Injection
When a service declares a database dependency via depends_on, Nanokit automatically resolves and injects the connection string as an environment variable. No manual wiring needed.
services:
api:
runtime: node
depends_on:
- main-postgresThis injects into the api container:
| Variable | Value |
|---|---|
MAIN_POSTGRES_URL | Full connection string (postgres://user:pass@host:5432/dbname) |
MAIN_POSTGRES_HOST | Hostname of the container or cloud endpoint |
MAIN_POSTGRES_PORT | Database port |
MAIN_POSTGRES_USER | Username |
MAIN_POSTGRES_PASSWORD | Password |
The variable prefix is derived from the database name (uppercased, hyphens replaced with underscores).
Custom Variable Names
Use the db:// scheme to map a connection string to a specific variable your application expects:
services:
api:
env:
DATABASE_URL: "db://main-postgres" # maps to your ORM's expected variable
REDIS_URL: "db://cache"Migrations
Nanokit does not run migrations automatically. The recommended pattern is to run them inside the prepare step on deploy, or as a one-off nkapp run command.
With Prisma
deploy:
prepare: npm ci && npx prisma migrate deploy && npm run buildWith Drizzle / Knex
deploy:
prepare: npm ci && npm run db:migrate && npm run buildManual one-off migration
# Run a migration command inside the service container
nkapp run api -- npx prisma migrate deploy -e stage[!IMPORTANT] When using database branching, always run migrations after switching to the target branch so they apply to the correct database clone.
Database Branching
Nanokit supports zero-friction database branching — isolate your data alongside your code branches for safe parallel development and perfect CI/CD pipelines.
Quick reference
# Create a new isolated copy of the database for the current Git branch
nkapp db fork <db-name>
# Switch to a specific branch database
nkapp db switch <db-name> --branch feat-login
# Reset branch data from the parent
nkapp db reset <db-name>
# Pull production data into your local branch
nkapp db pull <db-name> --from productionBackup & Restore
For structured, catalog-tracked backups with scheduling, retention, encryption, and S3 storage see the nkapp backup CLI reference.
Manual dump via db pull
nkapp db pull streams a database dump from a remote environment directly to your local instance over an encrypted SSH tunnel — no temporary files on disk:
nkapp db pull main-postgres --from productionOptions:
--from <env>— source environment (default:production)--force— allow pull from empty remote (dangerous, drops local data)-b, --branch <name>— target a specific local database branch
Manual dump
For manual exports, exec into the container:
# PostgreSQL
nkapp shell main-postgres -- pg_dump -U postgres mydb > backup.sql
# MySQL
nkapp shell main-postgres -- mysqldump -u root -p mydb > backup.sql
# MongoDB
nkapp shell cache -- mongodump --out /tmp/dumpLifecycle Commands
| Command | Description |
|---|---|
nkapp up -e <env> | Start all databases defined in config |
nkapp start <db-name> -e <env> | Start a single database container |
nkapp stop <db-name> -e <env> | Stop a database container (data preserved) |
nkapp restart <db-name> -e <env> | Restart a database container |
nkapp destroy <db-name> -e <env> | Remove container (volume preserved) |
nkapp shell <db-name> | Open a shell inside the database container |
Troubleshooting
Connection refused from service
Cause: The service is trying to connect before the database container is ready.
Fix: Ensure depends_on is set on the service. Nanokit waits for the DB to be healthy before starting dependent containers.
Volume already exists from a different project
Cause: Docker volume names collide across projects.
Fix: Ensure each project has a unique name: field in nanokit.yml. Nanokit uses this as the volume name prefix.
db fork fails with “volume not found”
Cause: The base database has never been started; no volume exists to clone.
Fix: Run nkapp up -e local first to initialize the base database volume, then run nkapp db fork <name>.