Production install
Install on any Linux or macOS host (x64/arm64) with Docker + the compose v2 plugin:
curl -fsSL https://nugetkeep.com/install | bashThis downloads the self-contained nugetkeep-install binary for your platform from
the public releases repo,
verifies its sha256 against the release’s checksums.txt, and launches it. On a
terminal you get a guided wizard — port, database, package storage, optional domain
with automatic HTTPS, optional OIDC/SSO, optional license key — and at the end a
running stack plus the admin API key and a ready-to-run dotnet nuget push line.
Pass flags after --:
curl -fsSL https://nugetkeep.com/install | bash -s -- --domain nuget.acme.comThe generated deploy lands in ./deploy (override with --dir): a
docker-compose.yml, a 0600 .env holding the secrets, and a Caddyfile when a
domain is set. Re-running is idempotent — the admin key is reused (rotate with
--force), bundled database/storage passwords are never silently rotated, and
switching database or storage providers requires an explicit confirmation because
data and blobs do not migrate.
Windows: run the same command inside WSL2 — native Windows support lands later. Alpine/musl hosts: run the Docker image directly.
Non-interactive / CI
Section titled “Non-interactive / CI”curl -fsSL https://nugetkeep.com/install | bash -s -- --yes \ --image ghcr.io/atypical-consulting/nugetkeep:latest --port 5380 --api-key "$ADMIN_KEY"--yes takes defaults and never prompts (without a terminal, the installer refuses
to guess unless --yes is set). Every flag has an environment-variable twin with
the same names the classic script used (DB, STORAGE, API_KEY, ASSUME_YES, …).
Commands
Section titled “Commands”| Command | What it does |
|---|---|
install (default) | Collect → validate → render → apply: brings the compose stack up and waits for /health/ready. |
render --target compose|docker-run|helm | Write the deployment files only; never touches Docker. |
validate | Pre-flight probes only (Docker, database, storage, OIDC, port) — exit code for CI. |
license <jwt|file> | Verify a license key offline and print edition/customer/expiry. |
Other targets
Section titled “Other targets”Single container — no compose, one docker run:
curl -fsSL https://nugetkeep.com/install | bash -s -- render --target docker-run \ --image ghcr.io/atypical-consulting/nugetkeep:latest./deploy/run.shKubernetes — renders values.yaml + nugetkeep-secret.yaml + helm-install.sh
for the NuGetKeep Helm chart (the installer never touches your cluster):
curl -fsSL https://nugetkeep.com/install | bash -s -- render --target helm \ --image ghcr.io/atypical-consulting/nugetkeep:latestPull the chart once from GHCR and point the generated script at it:
helm pull oci://ghcr.io/atypical-consulting/charts/nugetkeep --untar --untardir ~/.nugetkeepNUGETKEEP_CHART_PATH=~/.nugetkeep/nugetkeep ./deploy/helm-install.sh(Contributors working from a source checkout can use the chart at charts/nugetkeep
directly instead.)
The helm target expects the cluster to bring its own database/object storage/SSO — bundled PostgreSQL/MinIO/Dex are compose-only, and the installer says so.
Pinning and verifying
Section titled “Pinning and verifying”curl -fsSL https://nugetkeep.com/install | NUGETKEEP_INSTALL_VERSION=0.5.0 bashNUGETKEEP_INSTALL_BASE_URL points the shim at a mirror serving the same URL
layout. To audit before running: the shim is plain text at
nugetkeep.com/install, and the tarballs +
checksums.txt can be downloaded and checked by hand from the releases repo.
Flags reference
Section titled “Flags reference”| Flag | Purpose |
|---|---|
--dir <path> | Output directory for the stack files (default ./deploy). |
--port <n> | Host port when not behind Caddy (default 8080). |
--image <ref> | Image to deploy. The public GHCR image (ghcr.io/atypical-consulting/nugetkeep, pinned to the installer’s version) is the default outside a source checkout; inside one, the local Dockerfile is built instead. |
--api-key <key> | Pin the admin key (otherwise a strong one is generated). |
--db <mode> | sqlite (default), postgres (bundled container), external-postgres. |
--db-connection <conn> | For external-postgres — Npgsql keyword form or a postgres:// URI; validated before anything is written. |
--db-password <pw> | Pin the bundled-postgres password (otherwise generated; never rotated on re-run). |
--skip-db-check | Skip the external-database connection pre-flight. |
--storage <mode> | filesystem (default), minio (bundled), s3, azure-blob. |
--s3-endpoint / --s3-bucket / --s3-region / --s3-access-key / --s3-secret-key / --s3-path-style | External S3-compatible settings (prefer the S3_SECRET_KEY env var for the secret). |
--azure-connection <conn> / --azure-container <name> | Azure Blob settings (prefer the AZURE_CONNECTION env var). |
--minio-password <pw> | Pin the bundled-MinIO root password (otherwise generated; reused on re-run). |
--skip-storage-check | Skip the bucket/container pre-flight. |
--domain <host> | Front with Caddy for automatic HTTPS on that domain (compose target). |
--oidc-authority / --oidc-client-id / --oidc-client-secret | Enable SSO. |
--bootstrap-admins <csv> | Emails auto-granted Admin on first login. |
--with-dex / --dex-email / --dex-password | Bundle a local Dex IdP (local/dev only). |
--with-monitoring / --grafana-port <n> | Prometheus + Grafana sidecars (compose); the chart’s ServiceMonitor toggle (helm). |
--license-key <jwt|file> | Validate (offline) and install an Enterprise license. |
--target <t> | compose (default), docker-run, helm (render only for the last two). |
--pull / --no-build | Image acquisition control for install. |
--force | Rotate the admin key / confirm a provider switch. |
--dry-run | Print the rendered files (secrets redacted) instead of writing. |
--print | Legacy install alias for render-only (prefer the render command). |
--allow-test-license | Accept test-signed license keys (development only). |
--yes | Non-interactive: take defaults, never prompt. |
Database
Section titled “Database”The interactive picker offers SQLite (single container, zero config — the right
start for most teams), a bundled PostgreSQL container managed by the same stack, or
an existing PostgreSQL server. Bundled mode adds a second volume,
nugetkeep-pgdata, and the summary prints a pg_dump backup hint; external mode
validates the connection before the stack is written. Trade-offs, backup guidance,
and the no-data-migration caveat when switching:
Choosing a database.
Package storage
Section titled “Package storage”A second picker chooses where package blobs live: the local data volume (zero
config), a bundled MinIO container, an existing S3-compatible bucket (AWS S3,
MinIO, R2, …), or Azure Blob Storage. Bundled MinIO adds a nugetkeep-miniodata
volume; the external modes pre-flight the bucket/container before the stack is
written. Trade-offs and the no-blob-migration caveat:
Choosing package storage.
Manage the stack afterwards from the deploy dir: cd deploy && docker compose ps /
logs -f / restart / down. The nugetkeep-data volume survives
docker compose down. To enable SSO, see
Identity & SSO; to license Enterprise
features, see Applying a license.
Contributors only: from a source checkout,
scripts/install.shstill works with the same flags — it is a thin wrapper that runs the same installer from source (needs the .NET SDK fromglobal.json); without the SDK it points you at the hosted command above.