Skip to content

Choosing a database

NuGetKeep stores its metadata (packages, feeds, users, keys, audit trail, download counts) in a relational database. Package blobs are separate — they always live in the storage volume, whatever database you pick.

Out of the box NuGetKeep uses a single SQLite file inside the /data volume. There is nothing to install, nothing to configure, and backup is copying one volume. For a single server instance — most teams — this is the right choice, and it is not a “demo mode”: the supply-chain gate, SSO, multi-feed, retention, and metrics all run on it.

Choose PostgreSQL instead when:

  • your platform team requires a managed database (RDS, Cloud SQL, Azure Database, …),
  • you want point-in-time recovery or replication at the database layer,
  • write concurrency is high enough that SQLite’s single-writer model shows (rare for a package feed — reads dominate), or
  • a future multi-instance/HA topology is on your roadmap.

Two ways to run it, both built into the installer:

Terminal window
curl -fsSL https://nugetkeep.com/install | bash -s -- --db postgres

The generated compose stack gains a postgres:17-alpine service with its own nugetkeep-pgdata volume and a strong generated password (stored in the stack’s .env, mode 0600). The app waits for the database’s healthcheck before starting. The password is applied by the postgres image on first volume initialization only — re-running the installer never rotates it; to truly reset, docker compose down -v (this destroys the data).

Terminal window
curl -fsSL https://nugetkeep.com/install | bash -s -- --db external-postgres \
--db-connection 'Host=pg.example.com;Port=5432;Database=nugetkeep;Username=nugetkeep;Password=…'

The connection string uses the Npgsql keyword form; a postgres://user:pass@host:port/db URI is also accepted and converted. The installer validates the connection (a real SELECT 1, not just a port probe) before writing anything, with specific errors for DNS, refused connections, failed authentication, a missing database, and pg_hba.conf/SSL rejections (--skip-db-check bypasses it).

The database must already exist — NuGetKeep creates its schema (EF Core migrations run at startup), but never the database itself:

CREATE DATABASE nugetkeep OWNER nugetkeep;

A Postgres on the same machine as Docker is reached via host.docker.internal, not localhost (inside the container, localhost is the container).

Outside the installer, the same two settings drive everything (e.g. Kubernetes):

Terminal window
NUGETKEEP_DB_PROVIDER=Postgres
NUGETKEEP_DB_CONNECTION='Host=…;Port=5432;Database=nugetkeep;Username=…;Password=…'
ModeWhat to back up
SQLiteThe nugetkeep-data volume. One volume, one backup — database, packages, and keys together.
Bundled PostgresThe nugetkeep-data volume (packages/keys) and the database: docker compose exec postgres pg_dump -U nugetkeep nugetkeep > nugetkeep.sql
External PostgresThe nugetkeep-data volume, plus whatever backup story your database server already has.

When upgrading a bundled Postgres across a major version (17 → 18), dump and restore — the data directory format is not compatible across majors.

There is no automatic data migration between SQLite and PostgreSQL (in either direction). Switching providers means starting with a fresh database — packages would need to be re-pushed or re-mirrored. The installer warns loudly if you ask it to switch an existing stack; the old SQLite file / postgres volume is left untouched. If you anticipate needing PostgreSQL, start on it.