DEV Community

puffball1567
puffball1567

Posted on

KoutenDB v0.14.0: A Self-Hosted Database with Docker and Verified Backups

Starting a database container is easy. Operating that database after the first successful request is the harder part.

Backups need to be restorable, upgrades need a rollback path, certificates expire, unhealthy processes should not restart forever, and a database should not quietly cross an authorization boundary while answering a query.

KoutenDB v0.14.0, released on August 27, 2026, focuses on that operational layer. It adds a reproducible self-host path around KoutenDB with versioned multi-architecture images, TLS and authentication defaults, verified recovery workflows, bounded supervision, approval-gated capacity plans, and additional confidentiality hardening.

KoutenDB is a locality-first document and vector database written in Nim. Applications place related data into explicit coordinates called rings. At query time, KoutenDB first limits the candidates to the selected ring and then ranks the records within that smaller set. Previous releases established the storage, retrieval, persistence, cluster, and endurance foundations. Version 0.14.0 addresses the next practical challenge: operating the database on infrastructure controlled by its user.

Self-hosting a database is a lifecycle, not a Docker command

The new operational path is designed as a sequence of explicit, verifiable stages:

Versioned KoutenDB image
          ↓
Non-root Docker Compose deployment
          ↓
TLS, authentication, health checks, strong durability
          ↓
Checkpoint → export → independent restore → verification
          ↓
Upgrade or certificate rotation with rollback
          ↓
Capacity observation → immutable plan → explicit approval
Enter fullscreen mode Exit fullscreen mode

Official OCI images are published for linux/amd64 and linux/arm64 through ghcr.io/puffball1567/koutendb. The included single-node Compose bundle runs with a non-root user, a read-only container root, persistent strong-durability storage, generated TLS and authentication configuration, ring-local disk reads, and health checks.

The bootstrap keeps secret values outside the JSON configuration files. It generates password and secret-key files, a local CA and server certificate for the initial deployment, and mounts the prepared runtime secrets read-only. The CA private key is not mounted into the database container.

The intent is not to turn KoutenDB into a cloud provisioning platform. Docker, Kubernetes, Terraform, a virtualization platform, or a human operator can prepare CPU, memory, disks, and machines. KoutenDB is responsible for database-specific safety: validating its topology, producing recovery artifacts, checking whether prepared capacity is usable, and executing only typed database actions.

A backup is not complete until a restored copy is verified

Creating an archive is only the first half of a database backup. The important question is whether the exported generation can be restored and opened independently.

The v0.14.0 self-host operator turns that into one controlled workflow:

Drain writes
    ↓
Create an immutable checkpoint
    ↓
Verify the checkpoint
    ↓
Copy it under a staging name
    ↓
Restore it into an independent temporary volume
    ↓
Verify the restored data and segment layout
    ↓
Publish the backup generation
Enter fullscreen mode Exit fullscreen mode

The final backup directory appears only after the transported artifact and the independently restored copy pass verification. An interrupted or invalid candidate does not replace an existing destination.

From the generated deployment directory, a manual checkpoint, export, and independent restore drill look like this:

./operator.sh checkpoint-create before-upgrade

backup_dir=/mnt/koutendb-backups
./operator.sh checkpoint-export before-upgrade "$backup_dir"
./operator.sh restore-drill "$backup_dir/before-upgrade"
Enter fullscreen mode Exit fullscreen mode

The same workflow is available as a scheduled backup operation. The included systemd timer runs the checkpoint, staged export, restore drill, verification, publication, and retention sequence under one lifecycle lock. Verified generations count toward retention; corrupt generations are preserved as diagnostic evidence instead of being treated as successful backups.

The complete scheduled transaction can also be run manually. The final argument is the number of verified exports to retain:

./operator.sh scheduled-backup /var/backups/koutendb 7
Enter fullscreen mode Exit fullscreen mode

This distinction matters because a green “archive created” message does not prove that the database can recover from that archive. Version 0.14.0 makes the restore test part of the normal backup transaction.

Rollback-safe database upgrades and certificate rotation

The operator also handles upgrades using an explicitly versioned image or immutable digest. Mutable latest images are rejected.

Before replacement, the workflow validates the target image, drains and snapshots the active node, creates a checkpoint, and requires both the active and target images to verify that recovery generation. The configured image reference changes only after those checks. If the replacement fails its health check, the operator restores the previous image reference, recreates the service, verifies health, and resumes writes.

An upgrade takes a pinned image reference and a checkpoint name:

./operator.sh upgrade \
  ghcr.io/puffball1567/koutendb:0.14.0 \
  before-0.14.0
Enter fullscreen mode Exit fullscreen mode

Certificate rotation follows a similar staged model. Before changing the active certificate set, KoutenDB checks the CA, certificate chain, hostname, validity window, private key, and certificate/key match. A failed TLS health check restores the previous files.

./operator.sh certificate-rotate \
  /mnt/koutendb-pki/server.crt \
  /mnt/koutendb-pki/server.key
Enter fullscreen mode Exit fullscreen mode
Preflight new artifact
        ↓
Preserve a verified recovery point
        ↓
Stage and activate the change
        ↓
Health verification
   ↙ success      ↘ failure
keep new state     restore previous state
Enter fullscreen mode Exit fullscreen mode

The same basic rule is used across the lifecycle: do not discard the last known-good state before the replacement has proved that it can operate.

Capacity planning without arbitrary infrastructure hooks

KoutenDB v0.14.0 records bounded numeric capacity history and can generate a provider-neutral plan from observed storage growth, memory, and CPU data.

Each plan includes a forecast horizon, required headroom, topology intent, prerequisites, and the KoutenDB actions that would consume already prepared resources. Its ID is a SHA-256 digest of the complete versioned plan. Approval is bound to that exact content, and execution rechecks the plan identity, expiry, observation freshness, live growth, service health, and currently available resources.

The operator does not execute an arbitrary shell hook or create cloud instances. Infrastructure can be prepared by the deployment's normal system; the approval gate then verifies that KoutenDB can safely use it. Modified, stale, repeated, unapproved, and under-provisioned plans are rejected.

The workflow records observations first, creates a plan for a requested horizon, and then requires the exact generated plan ID for approval and execution:

./capacity.sh sample
./capacity.sh plan 604800

plan_id="PASTE_GENERATED_PLAN_ID_HERE"
./capacity.sh approve "$plan_id"
./capacity.sh execute "$plan_id"
./capacity.sh status "$plan_id"
Enter fullscreen mode Exit fullscreen mode

Stricter database access control and confidentiality boundaries

The operational work is accompanied by a broader security hardening pass.

Version 0.14.0 separates reader, writer, replicator, and admin roles. Node-to-node traffic uses explicit peerAuth credentials instead of reusing an ordinary application identity. Authenticated sessions are bound to a galaxy, and ring authorization is applied to retrieval, listing, counting, querying, updates, deletes, and visible statistics.

Other changes include:

  • Argon2id password derivation and authenticated secretbox encryption for newly encrypted backups;
  • owner-managed files or environment variables for backup passphrases;
  • 0700 POSIX data directories and 0600 managed artifacts at creation time;
  • rejection of symbolic-link output targets;
  • request and response framing limits before allocation;
  • bounded C ABI payload, vector, batch, string, boolean, and orbital inputs;
  • stable remote error categories that do not expose internal exception text;
  • fail-closed behavior for closed or unknown C ABI handles.

These boundaries are exercised by a checked-in Security Validation Matrix. The release validation covers authenticated TLS, galaxy and ring isolation, role and peer-service authorization, malformed protocol frames, encrypted-backup migration, POSIX artifact permissions, crash and storage-failure recovery, topology migration, coordinator failover, Universe synchronization, C ABI builds, and OCI image construction.

Trying the v0.14.0 self-host bundle

The complete self-host path is included in the release tag:

git clone https://github.com/puffball1567/koutendb.git
cd koutendb
git checkout v0.14.0

KOUTENDB_VERSION=0.14.0 \
  deploy/self-hosted/bootstrap.sh ../koutendb-deployment

cd ../koutendb-deployment
docker compose config
docker compose up -d
docker compose ps
Enter fullscreen mode Exit fullscreen mode

The default listener binds to 127.0.0.1:7301. The generated bundle contains the Compose deployment, client and server configuration, operational scripts, recovery storage layout, and optional systemd timer units.

The full commands for health verification, checkpoint export, restore drills, scheduled backups, upgrades, certificate rotation, and capacity plans are documented in the single-node self-host guide.

From database features to a database that can be operated

KoutenDB began with a retrieval model: place related data together and avoid making unrelated records candidates in the first place. That remains the database's central idea, but a useful database also needs a credible path from a local experiment to a service someone can recover, update, and supervise.

Version 0.14.0 moves that path forward without hiding critical operations behind an unbounded automation layer. Recovery generations are verified, replacements keep a rollback route, capacity actions require exact approval, and authorization is applied at the data boundaries the database exposes.

Top comments (0)