From 30e2647ee8f1366595c78e5da95b2aa6d4ac9a77 Mon Sep 17 00:00:00 2001 From: Wael Nasreddine Date: Fri, 30 Jan 2026 18:41:33 -0800 Subject: [PATCH 1/2] style: apply nix fmt to documentation and project files This commit applies project-wide formatting using 'nix fmt', mostly affecting documentation files and internal metadata. No functional changes included. --- docs/!!!meta.json | 90 +-- docs/docs.md | 11 +- docs/docs/Developer Guide.md | 23 +- docs/docs/Developer Guide/Architecture.md | 25 +- .../Architecture/Components.md | 91 ++- .../Architecture/Request Flow.md | 9 +- .../Architecture/Storage Backends.md | 37 +- .../S3 Storage Implementation.md | 59 +- docs/docs/Developer Guide/Contributing.md | 363 ++++++----- docs/docs/Developer Guide/Testing.md | 35 +- docs/docs/User Guide.md | 81 ++- docs/docs/User Guide/Configuration.md | 99 ++- .../User Guide/Configuration/Analytics.md | 174 +++--- .../docs/User Guide/Configuration/Database.md | 23 +- .../Database/Migration Between Databases.md | 9 +- .../Database/MySQLMariaDB Configuration.md | 23 +- .../Database/PostgreSQL Configuration.md | 31 +- .../Database/SQLite Configuration.md | 27 +- .../Configuration/Database/Troubleshooting.md | 41 +- .../User Guide/Configuration/Observability.md | 139 +++-- .../User Guide/Configuration/Reference.md | 97 ++- docs/docs/User Guide/Configuration/Storage.md | 21 +- .../Storage/Local Filesystem Storage.md | 29 +- .../Storage/Migration Between Storage Back.md | 5 +- .../Storage/S3-Compatible Storage.md | 63 +- .../Storage/Storage Comparison.md | 5 +- .../Configuration/Storage/Troubleshooting.md | 23 +- docs/docs/User Guide/Deployment.md | 125 ++-- .../Deployment/Distributed Locking.md | 585 +++++++++--------- .../Deployment/High Availability.md | 153 +++-- .../User Guide/Deployment/Single Instance.md | 109 ++-- docs/docs/User Guide/Getting Started.md | 49 +- .../User Guide/Getting Started/Concepts.md | 171 +++-- .../User Guide/Getting Started/Quick Start.md | 53 +- docs/docs/User Guide/Installation.md | 143 +++-- .../User Guide/Installation/Docker Compose.md | 45 +- docs/docs/User Guide/Installation/Docker.md | 63 +- .../User Guide/Installation/Helm Chart.md | 61 +- .../Helm Chart/Chart Reference.md | 37 +- .../User Guide/Installation/Kubernetes.md | 33 +- docs/docs/User Guide/Installation/NixOS.md | 37 +- docs/docs/User Guide/Operations.md | 51 +- .../User Guide/Operations/Backup Restore.md | 31 +- docs/docs/User Guide/Operations/Monitoring.md | 53 +- .../Operations/NarInfo Migration.md | 248 ++++---- .../User Guide/Operations/Troubleshooting.md | 41 +- docs/docs/User Guide/Operations/Upgrading.md | 31 +- docs/docs/User Guide/Usage.md | 27 +- .../docs/User Guide/Usage/Cache Management.md | 73 ++- docs/docs/User Guide/Usage/Client Setup.md | 25 +- 50 files changed, 1896 insertions(+), 1981 deletions(-) diff --git a/docs/!!!meta.json b/docs/!!!meta.json index 389c58b2..e2291f65 100644 --- a/docs/!!!meta.json +++ b/docs/!!!meta.json @@ -1074,44 +1074,44 @@ { "type": "relation", "name": "internalLink", - "value": "XGLieGaoykBR", + "value": "CgyeembF6J3W", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "btAHOppSLATG", + "value": "XGLieGaoykBR", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "QXVK8oy1Fxt4", + "value": "btAHOppSLATG", "isInheritable": false, "position": 40 }, { "type": "relation", "name": "internalLink", - "value": "3PqatYARSWot", + "value": "QXVK8oy1Fxt4", "isInheritable": false, "position": 50 }, { - "type": "label", - "name": "shareAlias", - "value": "observability", + "type": "relation", + "name": "internalLink", + "value": "3PqatYARSWot", "isInheritable": false, "position": 60 }, { - "type": "relation", - "name": "internalLink", - "value": "CgyeembF6J3W", + "type": "label", + "name": "shareAlias", + "value": "observability", "isInheritable": false, - "position": 70 + "position": 60 } ], "format": "markdown", @@ -2577,37 +2577,37 @@ { "type": "relation", "name": "internalLink", - "value": "QXVK8oy1Fxt4", + "value": "CgyeembF6J3W", "isInheritable": false, "position": 50 }, { "type": "relation", "name": "internalLink", - "value": "Zjh0gpeFlaIp", + "value": "QXVK8oy1Fxt4", "isInheritable": false, "position": 60 }, { "type": "relation", "name": "internalLink", - "value": "9QwQ6aHPcZLC", + "value": "Zjh0gpeFlaIp", "isInheritable": false, "position": 70 }, + { + "type": "relation", + "name": "internalLink", + "value": "9QwQ6aHPcZLC", + "isInheritable": false, + "position": 80 + }, { "type": "label", "name": "shareAlias", "value": "operations", "isInheritable": false, "position": 100 - }, - { - "type": "relation", - "name": "internalLink", - "value": "CgyeembF6J3W", - "isInheritable": false, - "position": 110 } ], "format": "markdown", @@ -2767,30 +2767,30 @@ { "type": "relation", "name": "internalLink", - "value": "Xfu0l3KoHmVw", + "value": "CgyeembF6J3W", "isInheritable": false, "position": 10 }, { "type": "relation", "name": "internalLink", - "value": "Zjh0gpeFlaIp", + "value": "Xfu0l3KoHmVw", "isInheritable": false, "position": 20 }, { - "type": "label", - "name": "shareAlias", - "value": "upgrading", + "type": "relation", + "name": "internalLink", + "value": "Zjh0gpeFlaIp", "isInheritable": false, "position": 30 }, { - "type": "relation", - "name": "internalLink", - "value": "CgyeembF6J3W", + "type": "label", + "name": "shareAlias", + "value": "upgrading", "isInheritable": false, - "position": 40 + "position": 30 } ], "format": "markdown", @@ -2818,35 +2818,35 @@ "name": "internalLink", "value": "XGLieGaoykBR", "isInheritable": false, - "position": 30 + "position": 10 }, { "type": "relation", "name": "internalLink", "value": "Bj05XwpRo8b0", "isInheritable": false, - "position": 40 + "position": 20 }, { "type": "relation", "name": "internalLink", "value": "BWy0GQ2M438N", "isInheritable": false, - "position": 50 + "position": 30 }, { "type": "relation", "name": "internalLink", "value": "IjYqLhriG6Le", "isInheritable": false, - "position": 60 + "position": 40 }, { "type": "relation", "name": "internalLink", "value": "btAHOppSLATG", "isInheritable": false, - "position": 70 + "position": 50 } ], "format": "markdown", @@ -2944,37 +2944,37 @@ { "type": "relation", "name": "internalLink", - "value": "QXVK8oy1Fxt4", + "value": "CgyeembF6J3W", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "IjYqLhriG6Le", + "value": "QXVK8oy1Fxt4", "isInheritable": false, "position": 30 }, { "type": "relation", "name": "internalLink", - "value": "btAHOppSLATG", + "value": "IjYqLhriG6Le", "isInheritable": false, "position": 40 }, + { + "type": "relation", + "name": "internalLink", + "value": "btAHOppSLATG", + "isInheritable": false, + "position": 50 + }, { "type": "label", "name": "shareAlias", "value": "cache-management", "isInheritable": false, "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "CgyeembF6J3W", - "isInheritable": false, - "position": 50 } ], "format": "markdown", diff --git a/docs/docs.md b/docs/docs.md index f83124eb..62733f82 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -1,5 +1,4 @@ -# docs - +# docs ## ncps: Nix Cache Proxy Server Welcome to the official documentation for **ncps** (Nix Cache Proxy Server). @@ -10,8 +9,8 @@ Welcome to the official documentation for **ncps** (Nix Cache Proxy Server). Please choose one of the following guides to get started: -- [**User Guide**](docs/User%20Guide.md) Everything you need to know about installing, configuring, deploying, and operating ncps. Start here if you are setting up ncps for yourself or your organization. -- [**Developer Guide**](docs/Developer%20Guide.md) Detailed information on the system architecture, component design, and contribution guidelines. Head here if you want to understand the internals or contribute to the project. +* [**User Guide**](docs/User%20Guide.md) Everything you need to know about installing, configuring, deploying, and operating ncps. Start here if you are setting up ncps for yourself or your organization. +* [**Developer Guide**](docs/Developer%20Guide.md) Detailed information on the system architecture, component design, and contribution guidelines. Head here if you want to understand the internals or contribute to the project. ## About the Author @@ -19,5 +18,5 @@ Please choose one of the following guides to get started: If you find this project useful, check out my blog or consider supporting my work: -- **Blog**: [https://wael.nasreddine.com/](https://wael.nasreddine.com/) -- **Sponsor**: [https://github.com/sponsors/kalbasit](https://github.com/sponsors/kalbasit) +* **Blog**: [https://wael.nasreddine.com/](https://wael.nasreddine.com/) +* **Sponsor**: [https://github.com/sponsors/kalbasit](https://github.com/sponsors/kalbasit) \ No newline at end of file diff --git a/docs/docs/Developer Guide.md b/docs/docs/Developer Guide.md index 41c800e4..cf7869d4 100644 --- a/docs/docs/Developer Guide.md +++ b/docs/docs/Developer Guide.md @@ -1,5 +1,4 @@ -# Developer Guide - +# Developer Guide ## Development Guide Information for contributing to ncps development. @@ -26,9 +25,9 @@ nix develop **Available tools in dev shell:** -- go, golangci-lint, sqlc, sqlfluff -- dbmate, delve, watchexec -- Integration test helpers +* go, golangci-lint, sqlc, sqlfluff +* dbmate, delve, watchexec +* Integration test helpers ## Development Workflow @@ -56,10 +55,10 @@ nix run .#deps This starts: -- **MinIO** (port 9000) - S3-compatible storage -- **PostgreSQL** (port 5432) - Database -- **MySQL/MariaDB** (port 3306) - Database -- **Redis** (port 6379) - Distributed locks +* **MinIO** (port 9000) - S3-compatible storage +* **PostgreSQL** (port 5432) - Database +* **MySQL/MariaDB** (port 3306) - Database +* **Redis** (port 6379) - Distributed locks ### Code Quality @@ -97,6 +96,6 @@ See Testing  ## Related Documentation -- Contributing - Full contribution guide -- Architecture - Deep dive into design -- Testing - Testing procedures +* Contributing - Full contribution guide +* Architecture - Deep dive into design +* Testing - Testing procedures \ No newline at end of file diff --git a/docs/docs/Developer Guide/Architecture.md b/docs/docs/Developer Guide/Architecture.md index b33730cc..b916e047 100644 --- a/docs/docs/Developer Guide/Architecture.md +++ b/docs/docs/Developer Guide/Architecture.md @@ -1,14 +1,13 @@ -# Architecture - +# Architecture ## Architecture Documentation Deep dive into ncps internals and design. ## Guides -- Components - System components and their interactions -- Storage Backends - Local and S3 storage implementation -- Request Flow - Detailed request processing flow +* Components - System components and their interactions +* Storage Backends - Local and S3 storage implementation +* Request Flow - Detailed request processing flow ## Overview @@ -16,10 +15,10 @@ ncps is designed as a modular caching proxy with pluggable storage and database ## Key Design Principles -1. **Modularity** - Separate concerns (storage, database, locks, server) -1. **Flexibility** - Support multiple backends for storage and database -1. **Scalability** - Scale from single instance to high availability -1. **Simplicity** - Easy to deploy and operate +1. **Modularity** - Separate concerns (storage, database, locks, server) +2. **Flexibility** - Support multiple backends for storage and database +3. **Scalability** - Scale from single instance to high availability +4. **Simplicity** - Easy to deploy and operate ## System Architecture @@ -44,7 +43,7 @@ ncps is designed as a modular caching proxy with pluggable storage and database ## Related Documentation -- Components - Detailed component breakdown -- Storage Backends - Storage implementation -- Request Flow - Request processing -- Developer Guide - Contributing +* Components - Detailed component breakdown +* Storage Backends - Storage implementation +* Request Flow - Request processing +* Developer Guide - Contributing \ No newline at end of file diff --git a/docs/docs/Developer Guide/Architecture/Components.md b/docs/docs/Developer Guide/Architecture/Components.md index d1d40604..b0c1cbad 100644 --- a/docs/docs/Developer Guide/Architecture/Components.md +++ b/docs/docs/Developer Guide/Architecture/Components.md @@ -1,5 +1,4 @@ -# Components - +# Components Detailed breakdown of ncps system components. ## HTTP Server (pkg/server/) @@ -8,33 +7,33 @@ Detailed breakdown of ncps system components. **Responsibilities:** -- Handle HTTP requests -- Route requests to handlers -- Serve static files (pubkey, nix-cache-info) -- Middleware (logging, metrics, tracing) +* Handle HTTP requests +* Route requests to handlers +* Serve static files (pubkey, nix-cache-info) +* Middleware (logging, metrics, tracing) **Key Endpoints:** -- `GET /pubkey` - Public key -- `GET /nix-cache-info` - Cache metadata -- `GET /.narinfo` - Package metadata -- `GET /nar/` - Package archive -- `GET /metrics` - Prometheus metrics (if enabled) +* `GET /pubkey` - Public key +* `GET /nix-cache-info` - Cache metadata +* `GET /.narinfo` - Package metadata +* `GET /nar/` - Package archive +* `GET /metrics` - Prometheus metrics (if enabled) ## Cache Layer (pkg/cache/) **Responsibilities:** -- Check if package exists in cache -- Fetch from upstream if not cached -- Sign NarInfo files -- Coordinate downloads (HA mode) +* Check if package exists in cache +* Fetch from upstream if not cached +* Sign NarInfo files +* Coordinate downloads (HA mode) **Key Functions:** -- `GetNarInfo()` - Get package metadata -- `GetNar()` - Get package archive -- `DownloadAndCache()` - Fetch from upstream +* `GetNarInfo()` - Get package metadata +* `GetNar()` - Get package archive +* `DownloadAndCache()` - Fetch from upstream ## Storage Backends (pkg/storage/) @@ -42,14 +41,14 @@ Detailed breakdown of ncps system components. **Implementations:** -- **Local** (`storage/local/`) - Filesystem storage -- **S3** (`storage/s3/`) - S3-compatible storage +* **Local** (`storage/local/`) - Filesystem storage +* **S3** (`storage/s3/`) - S3-compatible storage **Responsibilities:** -- Store and retrieve NAR files -- Store and retrieve NarInfo files -- Store secret keys +* Store and retrieve NAR files +* Store and retrieve NarInfo files +* Store secret keys ## Database Backends (pkg/database/) @@ -57,47 +56,47 @@ Detailed breakdown of ncps system components. **Implementations:** -- **SQLite** (`database/sqlitedb/`) -- **PostgreSQL** (`database/postgresdb/`) -- **MySQL** (`database/mysqldb/`) +* **SQLite** (`database/sqlitedb/`) +* **PostgreSQL** (`database/postgresdb/`) +* **MySQL** (`database/mysqldb/`) **Schema:** `db/schema.sql` **Queries:** `db/query.*.sql` **Responsibilities:** -- Store NarInfo metadata -- Track cache size -- Store download state +* Store NarInfo metadata +* Track cache size +* Store download state ## Lock Manager (pkg/lock/) **Implementations:** -- **Local** (`lock/local/`) - In-process locks (sync.Mutex, sync.RWMutex) -- **Redis** (`lock/redis/`) - Distributed locks (Redlock algorithm) -- **PostgreSQL** (`lock/postgres/`) - Distributed locks (PostgreSQL advisory locks) +* **Local** (`lock/local/`) - In-process locks (sync.Mutex, sync.RWMutex) +* **Redis** (`lock/redis/`) - Distributed locks (Redlock algorithm) +* **PostgreSQL** (`lock/postgres/`) - Distributed locks (PostgreSQL advisory locks) **Responsibilities:** -- Coordinate downloads (prevent duplicates) -- Coordinate LRU cleanup -- Handle lock retries -- Provide both exclusive and shared (read-write) locking +* Coordinate downloads (prevent duplicates) +* Coordinate LRU cleanup +* Handle lock retries +* Provide both exclusive and shared (read-write) locking **Lock Types:** -- `Locker` - Exclusive locks only (Lock/Unlock/TryLock) -- `RWLocker` - Read-write locks (Lock/Unlock/RLock/RUnlock) - - PostgreSQL: True shared read locks via `pg_advisory_lock_shared()` - - Redis: True shared read locks via Redis hash sets +* `Locker` - Exclusive locks only (Lock/Unlock/TryLock) +* `RWLocker` - Read-write locks (Lock/Unlock/RLock/RUnlock) + * PostgreSQL: True shared read locks via `pg_advisory_lock_shared()` + * Redis: True shared read locks via Redis hash sets ## NAR Handler (pkg/nar/) **Responsibilities:** -- Parse NAR format -- Handle compression (xz, zstd) -- Extract metadata +* Parse NAR format +* Handle compression (xz, zstd) +* Extract metadata ## Component Interaction @@ -115,6 +114,6 @@ Response ## Related Documentation -- Storage Backends - Storage details -- Request Flow - Request processing -- Developer Guide - Code structure +* Storage Backends - Storage details +* Request Flow - Request processing +* Developer Guide - Code structure \ No newline at end of file diff --git a/docs/docs/Developer Guide/Architecture/Request Flow.md b/docs/docs/Developer Guide/Architecture/Request Flow.md index 989e1617..12bcc41e 100644 --- a/docs/docs/Developer Guide/Architecture/Request Flow.md +++ b/docs/docs/Developer Guide/Architecture/Request Flow.md @@ -1,5 +1,4 @@ -# Request Flow - +# Request Flow ## NarInfo Request Flow ``` @@ -98,6 +97,6 @@ Result: Only one download from upstream! ## Related Documentation -- Components - System components -- Distributed Locking - Lock details -- High Availability - HA deployment +* Components - System components +* Distributed Locking - Lock details +* High Availability - HA deployment \ No newline at end of file diff --git a/docs/docs/Developer Guide/Architecture/Storage Backends.md b/docs/docs/Developer Guide/Architecture/Storage Backends.md index dd83bec3..9befed46 100644 --- a/docs/docs/Developer Guide/Architecture/Storage Backends.md +++ b/docs/docs/Developer Guide/Architecture/Storage Backends.md @@ -1,5 +1,4 @@ -# Storage Backends - +# Storage Backends Implementation details of local and S3 storage backends. ## Storage Interface @@ -31,9 +30,9 @@ type NarStore interface { **Implementation:** -- Files stored directly on filesystem -- Simple directory structure -- Atomic writes using temp files +* Files stored directly on filesystem +* Simple directory structure +* Atomic writes using temp files **Directory Structure:** @@ -49,14 +48,14 @@ type NarStore interface { **Pros:** -- Fast (local I/O) -- Simple implementation -- No external dependencies +* Fast (local I/O) +* Simple implementation +* No external dependencies **Cons:** -- Not suitable for HA -- Limited to single server +* Not suitable for HA +* Limited to single server ## S3-Compatible Backend @@ -64,9 +63,9 @@ type NarStore interface { **Implementation:** -- Uses MinIO Go SDK -- Supports all S3-compatible services -- Concurrent-safe +* Uses MinIO Go SDK +* Supports all S3-compatible services +* Concurrent-safe **Object Structure:** @@ -79,17 +78,17 @@ s3://bucket/ **Pros:** -- Scalable -- Redundant See S3 Storage Implementation for detailed implementation. +* Scalable +* Redundant See S3 Storage Implementation for detailed implementation. **Cons:** -- Network latency -- Requires S3 service +* Network latency +* Requires S3 service **Implementation Details:** See S3 Storage Implementation for detailed implementation. ## Related Documentation -- [Storage Configuration](../../User%20Guide/Configuration/Storage.md) - Configure storage -- Components - All components +* [Storage Configuration](../../User%20Guide/Configuration/Storage.md) - Configure storage +* Components - All components \ No newline at end of file diff --git a/docs/docs/Developer Guide/Architecture/Storage Backends/S3 Storage Implementation.md b/docs/docs/Developer Guide/Architecture/Storage Backends/S3 Storage Implementation.md index acb02fef..aecc311f 100644 --- a/docs/docs/Developer Guide/Architecture/Storage Backends/S3 Storage Implementation.md +++ b/docs/docs/Developer Guide/Architecture/Storage Backends/S3 Storage Implementation.md @@ -1,16 +1,15 @@ -# S3 Storage Implementation - +# S3 Storage Implementation ## S3 Storage Implementation This package provides an S3-compatible storage backend for ncps (Nix Cache Proxy Server). It implements the same interface as the local storage but uses S3 or S3-compatible services like MinIO for backend storage. ## Features -- **S3 Compatibility**: Works with AWS S3 and any S3-compatible service (MinIO, Ceph, etc.) -- **Drop-in Replacement**: Implements the same interface as local storage -- **Configurable**: Supports custom endpoints, regions, and authentication -- **MinIO Optimized**: Built using the MinIO Go SDK for optimal compatibility -- **Telemetry**: Includes OpenTelemetry tracing for monitoring +* **S3 Compatibility**: Works with AWS S3 and any S3-compatible service (MinIO, Ceph, etc.) +* **Drop-in Replacement**: Implements the same interface as local storage +* **Configurable**: Supports custom endpoints, regions, and authentication +* **MinIO Optimized**: Built using the MinIO Go SDK for optimal compatibility +* **Telemetry**: Includes OpenTelemetry tracing for monitoring ## Configuration @@ -29,9 +28,9 @@ type Config struct { ### Important Notes -- **Endpoint Format**: The endpoint **must** include the URL scheme (e.g., `"http://localhost:9000"` or `"https://s3.us-west-2.amazonaws.com"`). The scheme determines whether SSL/TLS is used. -- **Region**: Optional for MinIO, but typically required for AWS S3. -- **ForcePathStyle**: Set to `true` for MinIO and other S3-compatible services that require path-style addressing. Set to `false` for AWS S3 (which uses virtual-hosted-style by default). +* **Endpoint Format**: The endpoint **must** include the URL scheme (e.g., `"http://localhost:9000"` or `"https://s3.us-west-2.amazonaws.com"`). The scheme determines whether SSL/TLS is used. +* **Region**: Optional for MinIO, but typically required for AWS S3. +* **ForcePathStyle**: Set to `true` for MinIO and other S3-compatible services that require path-style addressing. Set to `false` for AWS S3 (which uses virtual-hosted-style by default). ## Usage @@ -105,18 +104,18 @@ Files are automatically sharded using the first 1-2 characters of their hash to The implementation properly handles S3-specific errors: -- `NoSuchKey` errors are converted to `storage.ErrNotFound` -- Configuration validation ensures required fields are provided -- Bucket existence is verified during initialization -- Returns `storage.ErrAlreadyExists` when attempting to overwrite existing objects +* `NoSuchKey` errors are converted to `storage.ErrNotFound` +* Configuration validation ensures required fields are provided +* Bucket existence is verified during initialization +* Returns `storage.ErrAlreadyExists` when attempting to overwrite existing objects ### Telemetry All operations include OpenTelemetry tracing with relevant attributes: -- Operation names (e.g., "s3.GetNarInfo", "s3.PutNar") -- Object keys and paths -- Hash values and NAR URLs +* Operation names (e.g., "s3.GetNarInfo", "s3.PutNar") +* Object keys and paths +* Hash values and NAR URLs ### Streaming Uploads @@ -132,18 +131,18 @@ go test ./pkg/storage/s3/... ## Dependencies -- `github.com/minio/minio-go/v7` - MinIO Go SDK for S3 operations -- `github.com/nix-community/go-nix` - Nix-specific types and utilities -- `go.opentelemetry.io/otel` - OpenTelemetry for tracing +* `github.com/minio/minio-go/v7` - MinIO Go SDK for S3 operations +* `github.com/nix-community/go-nix` - Nix-specific types and utilities +* `go.opentelemetry.io/otel` - OpenTelemetry for tracing ## Migration from Local Storage To migrate from local storage to S3 storage: -1. Create an S3 bucket or MinIO instance -1. Configure the S3 storage with appropriate credentials -1. Replace the local storage initialization with S3 storage -1. The rest of your application code remains unchanged +1. Create an S3 bucket or MinIO instance +2. Configure the S3 storage with appropriate credentials +3. Replace the local storage initialization with S3 storage +4. The rest of your application code remains unchanged ```go // Before (local storage) @@ -161,9 +160,9 @@ s3Store, err := s3.New(ctx, s3.Config{ ## Security Considerations -- Store credentials securely (environment variables, IAM roles, etc.) -- Use IAM policies to restrict bucket access (for AWS S3) -- Consider using temporary credentials for production -- Enable bucket versioning for data protection -- Use appropriate bucket policies for access control -- Always use HTTPS in production (e.g., `Endpoint: "https://s3.amazonaws.com"`) +* Store credentials securely (environment variables, IAM roles, etc.) +* Use IAM policies to restrict bucket access (for AWS S3) +* Consider using temporary credentials for production +* Enable bucket versioning for data protection +* Use appropriate bucket policies for access control +* Always use HTTPS in production (e.g., `Endpoint: "https://s3.amazonaws.com"`) \ No newline at end of file diff --git a/docs/docs/Developer Guide/Contributing.md b/docs/docs/Developer Guide/Contributing.md index d09613c7..c96a599d 100644 --- a/docs/docs/Developer Guide/Contributing.md +++ b/docs/docs/Developer Guide/Contributing.md @@ -1,5 +1,4 @@ -# Contributing - +# Contributing ## Contributing to ncps Thank you for your interest in contributing to ncps! This document provides guidelines and instructions for contributing to the project. @@ -10,37 +9,36 @@ Thank you for your interest in contributing to ncps! This document provides guid The project uses **Nix flakes** with **direnv** for reproducible development environments. You'll need: -1. **Nix with flakes enabled** - [Installation guide](https://nixos.org/download.html) -1. **direnv** - [Installation guide](https://direnv.net/docs/installation.html) +1. **Nix with flakes enabled** - [Installation guide](https://nixos.org/download.html) +2. **direnv** - [Installation guide](https://direnv.net/docs/installation.html) ### Initial Setup -1. **Clone the repository:** - - ```sh - git clone https://github.com/kalbasit/ncps.git - cd ncps - ``` +1. **Clone the repository:** -1. **Allow direnv:** + ```sh + git clone https://github.com/kalbasit/ncps.git + cd ncps + ``` +2. **Allow direnv:** - ```sh - direnv allow - ``` + ```sh + direnv allow + ``` - This will automatically load the development environment with all required tools: + This will automatically load the development environment with all required tools: - - Go - - golangci-lint - - sqlc - - dbmate - - delve (debugger) - - watchexec - - sqlfluff - - MinIO (for S3 testing) - - PostgreSQL (for database testing) - - MySQL/MariaDB (for database testing) - - Redis (for distributed locking testing) + * Go + * golangci-lint + * sqlc + * dbmate + * delve (debugger) + * watchexec + * sqlfluff + * MinIO (for S3 testing) + * PostgreSQL (for database testing) + * MySQL/MariaDB (for database testing) + * Redis (for distributed locking testing) ## Development Environment @@ -72,21 +70,21 @@ nix run .#deps This starts: -- **MinIO** - S3-compatible storage server (port 9000, console on 9001) - - Test bucket: `test-bucket` - - Credentials: `test-access-key` / `test-secret-key` - - Self-validation ensures proper setup -- **PostgreSQL** - Database server (port 5432) - - Test database: `test-db` - - Credentials: `test-user` / `test-password` - - Connection URL: `postgresql://test-user:test-password@127.0.0.1:5432/test-db?sslmode=disable` -- **MariaDB** - MySQL-compatible database server (port 3306) - - Test database: `test-db` - - Credentials: `test-user` / `test-password` - - Connection URL: `mysql://test-user:test-password@127.0.0.1:3306/test-db` -- **Redis** - Distributed locking server (port 6379) - - No authentication required (test environment) - - Used for distributed lock testing +* **MinIO** - S3-compatible storage server (port 9000, console on 9001) + * Test bucket: `test-bucket` + * Credentials: `test-access-key` / `test-secret-key` + * Self-validation ensures proper setup +* **PostgreSQL** - Database server (port 5432) + * Test database: `test-db` + * Credentials: `test-user` / `test-password` + * Connection URL: `postgresql://test-user:test-password@127.0.0.1:5432/test-db?sslmode=disable` +* **MariaDB** - MySQL-compatible database server (port 3306) + * Test database: `test-db` + * Credentials: `test-user` / `test-password` + * Connection URL: `mysql://test-user:test-password@127.0.0.1:3306/test-db` +* **Redis** - Distributed locking server (port 6379) + * No authentication required (test environment) + * Used for distributed lock testing ## Development Workflow @@ -114,27 +112,23 @@ The server automatically restarts when you modify code files. The documentation for this project is managed using Trilium. Follow these steps to contribute to the documentation: -1. **Run the documentation editor:** - - ```sh - trilium-edit-docs - ``` - - This tool is available in the `PATH` provided by the Nix flake, see [Development Environment in the Developer Guide](../Developer%20Guide.md) for more information. +1. **Run the documentation editor:** -1. **Edit the documentation through Trilium:** The Trilium interface will open, allowing you to edit the notes. Trilium automatically exports the markdown files back to the repository as you make changes. + ```sh + trilium-edit-docs + ``` -1. **Wait and close:** Wait 5 minutes after you have finished all your edits to ensure all changes are synced, then close Trilium. + This tool is available in the `PATH` provided by the Nix flake, see [Development Environment in the Developer Guide](../Developer%20Guide.md) for more information. +2. **Edit the documentation through Trilium:** The Trilium interface will open, allowing you to edit the notes. Trilium automatically exports the markdown files back to the repository as you make changes. +3. **Wait and close:** Wait 5 minutes after you have finished all your edits to ensure all changes are synced, then close Trilium. +4. **Format the documentation:** -1. **Format the documentation:** + Run the project formatter to ensure the markdown files follow the project's standards: - Run the project formatter to ensure the markdown files follow the project's standards: - - ```sh - nix fmt - ``` - -1. **Submit your changes:** Submit a Pull Request with your changes. + ```sh + nix fmt + ``` +5. **Submit your changes:** Submit a Pull Request with your changes. ### Database Migrations @@ -148,9 +142,9 @@ dbmate --migrations-dir db/migrations/mysql new migration_name The `dbmate` command is a wrapper that automatically: -- Detects database type from the URL scheme -- Selects the appropriate migrations directory (`db/migrations/sqlite/`, `db/migrations/postgres/`, or `db/migrations/mysql/`) -- Creates timestamped migration files +* Detects database type from the URL scheme +* Selects the appropriate migrations directory (`db/migrations/sqlite/`, `db/migrations/postgres/`, or `db/migrations/mysql/`) +* Creates timestamped migration files **Applying migrations:** @@ -172,9 +166,9 @@ sqlc generate This generates type-safe Go code from: -- `db/query.sqlite.sql` → `pkg/database/sqlitedb/` -- `db/query.postgres.sql` → `pkg/database/postgresdb/` -- `db/query.mysql.sql` → `pkg/database/mysqldb/` +* `db/query.sqlite.sql` → `pkg/database/sqlitedb/` +* `db/query.postgres.sql` → `pkg/database/postgresdb/` +* `db/query.mysql.sql` → `pkg/database/mysqldb/` ## Code Quality Standards @@ -189,13 +183,13 @@ nix fmt The project uses: -- **gofumpt** - Stricter Go formatting -- **goimports** - Import organization -- **gci** - Import grouping (standard → default → alias → localmodule) -- **nixfmt** - Nix code formatting -- **sqlfluff** - SQL formatting and linting -- **yamlfmt** - YAML formatting -- **mdformat** - Markdown formatting +* **gofumpt** - Stricter Go formatting +* **goimports** - Import organization +* **gci** - Import grouping (standard → default → alias → localmodule) +* **nixfmt** - Nix code formatting +* **sqlfluff** - SQL formatting and linting +* **yamlfmt** - YAML formatting +* **mdformat** - Markdown formatting ### Linting @@ -214,11 +208,11 @@ golangci-lint run ./pkg/server/... The project uses 30+ linters including: -- **err113** - Explicit error wrapping -- **exhaustive** - Exhaustive switch statements -- **gosec** - Security checks -- **paralleltest** - Parallel test detection -- **testpackage** - Test package naming +* **err113** - Explicit error wrapping +* **exhaustive** - Exhaustive switch statements +* **gosec** - Security checks +* **paralleltest** - Parallel test detection +* **testpackage** - Test package naming See `.golangci.yml` for complete linter configuration. @@ -306,28 +300,28 @@ eval "$(disable-integration-tests)" The helper commands output shell export statements that you evaluate in your current shell: -- `**enable-s3-tests**` exports: - - `NCPS_TEST_S3_BUCKET=test-bucket` - - `NCPS_TEST_S3_ENDPOINT=http://127.0.0.1:9000` - - `NCPS_TEST_S3_REGION=us-east-1` - - `NCPS_TEST_S3_ACCESS_KEY_ID=test-access-key` - - `NCPS_TEST_S3_SECRET_ACCESS_KEY=test-secret-key` -- `**enable-postgres-tests**` exports: - - `NCPS_TEST_POSTGRES_URL=postgresql://test-user:test-password@127.0.0.1:5432/test-db?sslmode=disable` -- `**enable-mysql-tests**` exports: - - `NCPS_TEST_MYSQL_URL=mysql://test-user:test-password@127.0.0.1:3306/test-db` -- `**enable-redis-tests**` exports: - - `NCPS_ENABLE_REDIS_TESTS=1` +* `**enable-s3-tests**` exports: + * `NCPS_TEST_S3_BUCKET=test-bucket` + * `NCPS_TEST_S3_ENDPOINT=http://127.0.0.1:9000` + * `NCPS_TEST_S3_REGION=us-east-1` + * `NCPS_TEST_S3_ACCESS_KEY_ID=test-access-key` + * `NCPS_TEST_S3_SECRET_ACCESS_KEY=test-secret-key` +* `**enable-postgres-tests**` exports: + * `NCPS_TEST_POSTGRES_URL=postgresql://test-user:test-password@127.0.0.1:5432/test-db?sslmode=disable` +* `**enable-mysql-tests**` exports: + * `NCPS_TEST_MYSQL_URL=mysql://test-user:test-password@127.0.0.1:3306/test-db` +* `**enable-redis-tests**` exports: + * `NCPS_ENABLE_REDIS_TESTS=1` Tests automatically skip if these environment variables aren't set, so you can run `go test -race ./...` without enabling integration tests and only unit tests will run. ### Test Requirements -- Use **testify** for assertions -- Enable race detector (`-race` flag) -- Use `_test` package suffix (enforced by `testpackage` linter) -- Write parallel tests where possible (checked by `paralleltest` linter) -- Each test should be isolated and not depend on other tests +* Use **testify** for assertions +* Enable race detector (`-race` flag) +* Use `_test` package suffix (enforced by `testpackage` linter) +* Write parallel tests where possible (checked by `paralleltest` linter) +* Each test should be isolated and not depend on other tests ### Nix Build Tests @@ -341,11 +335,11 @@ nix build The Nix build automatically: -1. Starts MinIO, PostgreSQL, MariaDB, and Redis in `preCheck` phase -1. Creates test databases and buckets -1. Exports test environment variables -1. Runs all tests (including integration tests) -1. Stops services in `postCheck` phase +1. Starts MinIO, PostgreSQL, MariaDB, and Redis in `preCheck` phase +2. Creates test databases and buckets +3. Exports test environment variables +4. Runs all tests (including integration tests) +5. Stops services in `postCheck` phase ### Helm Chart Testing @@ -353,10 +347,10 @@ The project includes comprehensive Helm chart testing using a local Kind cluster **Prerequisites:** -- Docker -- kubectl -- helm -- kind +* Docker +* kubectl +* helm +* kind **Setup (one-time):** @@ -402,15 +396,15 @@ DOCKER_IMAGE_TAGS="yourregistry.com/ncps:sha$(git rev-parse --short HEAD)" nix r The generate-test-values.sh script creates 10 different test configurations: -- **Single Instance with Local Storage:** - - SQLite, PostgreSQL, or MariaDB database -- **Single Instance with S3 Storage:** - - SQLite, PostgreSQL, or MariaDB database - - Tests S3 configuration and MinIO compatibility -- **High Availability:** - - 2 replicas with S3 storage - - PostgreSQL or MariaDB database - - Redis for distributed locking +* **Single Instance with Local Storage:** + * SQLite, PostgreSQL, or MariaDB database +* **Single Instance with S3 Storage:** + * SQLite, PostgreSQL, or MariaDB database + * Tests S3 configuration and MinIO compatibility +* **High Availability:** + * 2 replicas with S3 storage + * PostgreSQL or MariaDB database + * Redis for distributed locking **Testing Individual Deployments:** @@ -452,68 +446,61 @@ helm upgrade --install ncps-single-local-postgres . \ ### Before Submitting -1. **Format your code:** - - ``` - nix fmt - ``` +1. **Format your code:** -1. **Fix linting issues:** + ``` + nix fmt + ``` +2. **Fix linting issues:** - ``` - golangci-lint run --fix - ``` + ``` + golangci-lint run --fix + ``` +3. **Run tests:** -1. **Run tests:** + ``` + go test -race ./... + ``` +4. **Build successfully:** - ``` - go test -race ./... - ``` - -1. **Build successfully:** - - ``` - nix build - ``` + ``` + nix build + ``` ### Commit Guidelines -- Use clear, descriptive commit messages -- Follow [Conventional Commits](https://www.conventionalcommits.org/) when possible: - - `feat:` - New features - - `fix:` - Bug fixes - - `docs:` - Documentation changes - - `refactor:` - Code refactoring - - `test:` - Test additions/changes - - `chore:` - Build/tooling changes +* Use clear, descriptive commit messages +* Follow [Conventional Commits](https://www.conventionalcommits.org/) when possible: + * `feat:` - New features + * `fix:` - Bug fixes + * `docs:` - Documentation changes + * `refactor:` - Code refactoring + * `test:` - Test additions/changes + * `chore:` - Build/tooling changes ### Pull Request Guidelines -1. **Create a feature branch:** - - ``` - git checkout -b feature/your-feature-name - ``` - -1. **Make your changes** following code quality standards - -1. **Update documentation** if needed (README.md, CLAUDE.md, etc.) - -1. **Add tests** for new functionality +1. **Create a feature branch:** -1. **Submit PR** with: + ``` + git checkout -b feature/your-feature-name + ``` +2. **Make your changes** following code quality standards +3. **Update documentation** if needed (README.md, CLAUDE.md, etc.) +4. **Add tests** for new functionality +5. **Submit PR** with: - - Clear description of changes - - Reference to related issues - - Screenshots/examples if applicable + * Clear description of changes + * Reference to related issues + * Screenshots/examples if applicable ### CI/CD Notes The project uses GitHub Actions for CI/CD: -- Workflows only run on PRs targeting `main` branch -- This supports Graphite-style stacked PRs efficiently -- When modifying workflows, maintain the `branches: [main]` restriction +* Workflows only run on PRs targeting `main` branch +* This supports Graphite-style stacked PRs efficiently +* When modifying workflows, maintain the `branches: [main]` restriction ## Project Structure @@ -558,24 +545,24 @@ ncps/ **Storage (**`**pkg/storage/store.go**`**):** -- `ConfigStore` - Secret key storage -- `NarInfoStore` - NarInfo metadata storage -- `NarStore` - NAR file storage +* `ConfigStore` - Secret key storage +* `NarInfoStore` - NarInfo metadata storage +* `NarStore` - NAR file storage Both local and S3 backends implement these interfaces. **Locks (**`**pkg/lock/lock.go**`**):** -- `Locker` - Exclusive locking for download deduplication -- `RWLocker` - Read-write locking for LRU coordination +* `Locker` - Exclusive locking for download deduplication +* `RWLocker` - Read-write locking for LRU coordination Both local (sync.Mutex) and Redis (Redlock) backends implement these interfaces. Redis locks enable high-availability deployments with multiple instances. **Database:** -- Supports SQLite, PostgreSQL, and MySQL via sqlc -- Database selection via URL scheme in `--cache-database-url` -- Type-safe queries generated from `db/query.*.sql` files +* Supports SQLite, PostgreSQL, and MySQL via sqlc +* Database selection via URL scheme in `--cache-database-url` +* Type-safe queries generated from `db/query.*.sql` files ## Common Development Tasks @@ -615,9 +602,9 @@ dbmate --url "mysql://..." up Edit the appropriate query file: -- db/query.sqlite.sql (SQLite-specific queries) -- db/query.postgres.sql (PostgreSQL-specific queries) -- db/query.mysql.sql (MySQL-specific queries) +* db/query.sqlite.sql (SQLite-specific queries) +* db/query.postgres.sql (PostgreSQL-specific queries) +* db/query.mysql.sql (MySQL-specific queries) ### Generating SQL Code @@ -630,23 +617,23 @@ go generate ./pkg/database This generates type-safe Go code from: -- `db/query.sqlite.sql` → `pkg/database/sqlitedb/` -- `db/query.postgres.sql` → `pkg/database/postgresdb/` -- `db/query.mysql.sql` → `pkg/database/mysqldb/` +* `db/query.sqlite.sql` → `pkg/database/sqlitedb/` +* `db/query.postgres.sql` → `pkg/database/postgresdb/` +* `db/query.mysql.sql` → `pkg/database/mysqldb/` And automatically updates: -- `pkg/database/querier.go` (Common interface) -- `pkg/database/models.go` (Common models) -- `pkg/database/wrapper_*.go` (Engine adaptors) +* `pkg/database/querier.go` (Common interface) +* `pkg/database/models.go` (Common models) +* `pkg/database/wrapper_*.go` (Engine adaptors) ### Adding a New Storage Backend -1. Implement the storage interfaces in `pkg/storage/` -1. Add configuration flags in `cmd/serve.go` -1. Update documentation in README.md and CLAUDE.md -1. Add integration tests -1. Update Docker and Kubernetes examples if applicable +1. Implement the storage interfaces in `pkg/storage/` +2. Add configuration flags in `cmd/serve.go` +3. Update documentation in README.md and CLAUDE.md +4. Add integration tests +5. Update Docker and Kubernetes examples if applicable ### Debugging @@ -677,22 +664,22 @@ DOCKER_IMAGE_TAGS="kalbasit/ncps:latest kalbasit/ncps:v1.0.0" nix run .#push-doc ## Getting Help -- **Documentation Issues:** Check CLAUDE.md for detailed development guidance -- **Bug Reports:** [Open an issue](https://github.com/kalbasit/ncps/issues) -- **Questions:** [Start a discussion](https://github.com/kalbasit/ncps/discussions) -- **Security Issues:** Contact maintainers privately +* **Documentation Issues:** Check CLAUDE.md for detailed development guidance +* **Bug Reports:** [Open an issue](https://github.com/kalbasit/ncps/issues) +* **Questions:** [Start a discussion](https://github.com/kalbasit/ncps/discussions) +* **Security Issues:** Contact maintainers privately ## Code of Conduct -- Be respectful and inclusive -- Provide constructive feedback -- Focus on what's best for the project -- Show empathy towards other contributors +* Be respectful and inclusive +* Provide constructive feedback +* Focus on what's best for the project +* Show empathy towards other contributors ## License By contributing to ncps, you agree that your contributions will be licensed under the MIT License. -______________________________________________________________________ +--- -Thank you for contributing to ncps! 🎉 +Thank you for contributing to ncps! 🎉 \ No newline at end of file diff --git a/docs/docs/Developer Guide/Testing.md b/docs/docs/Developer Guide/Testing.md index fce1edc1..ef785753 100644 --- a/docs/docs/Developer Guide/Testing.md +++ b/docs/docs/Developer Guide/Testing.md @@ -1,5 +1,4 @@ -# Testing - +# Testing ## Testing Guide Testing procedures and integration test setup. @@ -39,12 +38,12 @@ eval "$(disable-integration-tests)" **Available helpers:** -- `enable-s3-tests` - S3/MinIO tests -- `enable-postgres-tests` - PostgreSQL tests -- `enable-mysql-tests` - MySQL tests -- `enable-redis-tests` - Redis lock tests -- `enable-integration-tests` - All integration tests -- `disable-integration-tests` - Disable all +* `enable-s3-tests` - S3/MinIO tests +* `enable-postgres-tests` - PostgreSQL tests +* `enable-mysql-tests` - MySQL tests +* `enable-redis-tests` - Redis lock tests +* `enable-integration-tests` - All integration tests +* `disable-integration-tests` - Disable all ### CI/CD Testing @@ -56,9 +55,9 @@ nix flake check This automatically: -1. Starts all dependencies (MinIO, PostgreSQL, MariaDB, Redis) -1. Runs all tests including integration tests -1. Stops all services +1. Starts all dependencies (MinIO, PostgreSQL, MariaDB, Redis) +2. Runs all tests including integration tests +3. Stops all services ## Test Structure @@ -116,11 +115,11 @@ golangci-lint run path/to/file.go **Key linters:** -- err113 - Error handling -- exhaustive - Switch exhaustiveness -- gosec - Security -- paralleltest - Parallel testing -- testpackage - Test package naming +* err113 - Error handling +* exhaustive - Switch exhaustiveness +* gosec - Security +* paralleltest - Parallel testing +* testpackage - Test package naming ## Code Formatting @@ -153,5 +152,5 @@ go tool cover -html=coverage.out ## Related Documentation -- Contributing - Contribution guidelines -- Developer Guide - Development environment guide +* Contributing - Contribution guidelines +* Developer Guide - Development environment guide \ No newline at end of file diff --git a/docs/docs/User Guide.md b/docs/docs/User Guide.md index ea11a0c5..2c27189c 100644 --- a/docs/docs/User Guide.md +++ b/docs/docs/User Guide.md @@ -1,5 +1,4 @@ -# User Guide - +# User Guide ## ncps Documentation Welcome to the comprehensive documentation for ncps (Nix Cache Proxy Server). This documentation is organized to help you quickly find the information you need, whether you're just getting started or managing a production deployment. @@ -23,60 +22,60 @@ Welcome to the comprehensive documentation for ncps (Nix Cache Proxy Server). Th **Get Started** -- [Run ncps for the first time](User%20Guide/Getting%20Started/Quick%20Start.md) -- [Understand how ncps works](User%20Guide/Getting%20Started/Concepts.md) -- [Choose the right deployment method](User%20Guide/Installation.md) +* [Run ncps for the first time](User%20Guide/Getting%20Started/Quick%20Start.md) +* [Understand how ncps works](User%20Guide/Getting%20Started/Concepts.md) +* [Choose the right deployment method](User%20Guide/Installation.md) **Install ncps** -- [Install with Docker](User%20Guide/Installation/Docker.md) -- [Install with Docker Compose](User%20Guide/Installation/Docker%20Compose.md) -- [Deploy on Kubernetes](User%20Guide/Installation/Kubernetes.md) -- [Use the Helm chart](User%20Guide/Installation/Helm%20Chart.md) -- [Configure on NixOS](User%20Guide/Installation/NixOS.md) +* [Install with Docker](User%20Guide/Installation/Docker.md) +* [Install with Docker Compose](User%20Guide/Installation/Docker%20Compose.md) +* [Deploy on Kubernetes](User%20Guide/Installation/Kubernetes.md) +* [Use the Helm chart](User%20Guide/Installation/Helm%20Chart.md) +* [Configure on NixOS](User%20Guide/Installation/NixOS.md) **Configure ncps** -- [See all configuration options](User%20Guide/Configuration/Reference.md) -- [Configure storage backends](User%20Guide/Configuration/Storage.md) -- [Choose and configure a database](User%20Guide/Configuration/Database.md) -- [Configure analytics reporting](User%20Guide/Configuration/Analytics.md) -- [Set up observability](User%20Guide/Configuration/Observability.md) +* [See all configuration options](User%20Guide/Configuration/Reference.md) +* [Configure storage backends](User%20Guide/Configuration/Storage.md) +* [Choose and configure a database](User%20Guide/Configuration/Database.md) +* [Configure analytics reporting](User%20Guide/Configuration/Analytics.md) +* [Set up observability](User%20Guide/Configuration/Observability.md) **Deploy for Production** -- [Deploy a single instance](User%20Guide/Deployment/Single%20Instance.md) -- [Set up high availability](User%20Guide/Deployment/High%20Availability.md) -- [Configure distributed locking](User%20Guide/Deployment/Distributed%20Locking.md) +* [Deploy a single instance](User%20Guide/Deployment/Single%20Instance.md) +* [Set up high availability](User%20Guide/Deployment/High%20Availability.md) +* [Configure distributed locking](User%20Guide/Deployment/Distributed%20Locking.md) **Use ncps** -- [Configure Nix clients](User%20Guide/Usage/Client%20Setup.md) -- [Manage the cache](User%20Guide/Usage/Cache%20Management.md) +* [Configure Nix clients](User%20Guide/Usage/Client%20Setup.md) +* [Manage the cache](User%20Guide/Usage/Cache%20Management.md) **Operate and Maintain** -- [Monitor ncps](User%20Guide/Operations/Monitoring.md) -- [Troubleshoot issues](User%20Guide/Operations/Troubleshooting.md) -- [Backup and restore](User%20Guide/Operations/Backup%20Restore.md) -- [Upgrade ncps](User%20Guide/Operations/Upgrading.md) +* [Monitor ncps](User%20Guide/Operations/Monitoring.md) +* [Troubleshoot issues](User%20Guide/Operations/Troubleshooting.md) +* [Backup and restore](User%20Guide/Operations/Backup%20Restore.md) +* [Upgrade ncps](User%20Guide/Operations/Upgrading.md) **Understand Internals** -- [Learn about system components](Developer%20Guide/Architecture/Components.md) -- [Understand storage backends](Developer%20Guide/Architecture/Storage%20Backends.md) -- [Helm Chart Documentation](User%20Guide/Installation/Helm%20Chart/Chart%20Reference.md) - Comprehensive Helm chart reference -- [Follow request flow](Developer%20Guide/Architecture/Request%20Flow.md) -- [Set up development environment](Developer%20Guide.md) -- [See contribution guidelines](Developer%20Guide/Contributing.md) +* [Learn about system components](Developer%20Guide/Architecture/Components.md) +* [Understand storage backends](Developer%20Guide/Architecture/Storage%20Backends.md) +* [Helm Chart Documentation](User%20Guide/Installation/Helm%20Chart/Chart%20Reference.md) - Comprehensive Helm chart reference +* [Follow request flow](Developer%20Guide/Architecture/Request%20Flow.md) +* [Set up development environment](Developer%20Guide.md) +* [See contribution guidelines](Developer%20Guide/Contributing.md) ## Additional Resources -- [Helm Chart Documentation](User%20Guide/Installation/Helm%20Chart/Chart%20Reference.md) - Comprehensive Helm chart reference -- [See contribution guidelines](Developer%20Guide/Contributing.md) - Development and contribution guidelines -- [Configuration Example](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) - Complete configuration file example -- [**GitHub Issues**](https://github.com/kalbasit/ncps/issues) - Report bugs and request features -- [**Discussions**](https://github.com/kalbasit/ncps/discussions) - Ask questions and share ideas +* [Helm Chart Documentation](User%20Guide/Installation/Helm%20Chart/Chart%20Reference.md) - Comprehensive Helm chart reference +* [See contribution guidelines](Developer%20Guide/Contributing.md) - Development and contribution guidelines +* [Configuration Example](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) - Complete configuration file example +* [**GitHub Issues**](https://github.com/kalbasit/ncps/issues) - Report bugs and request features +* [**Discussions**](https://github.com/kalbasit/ncps/discussions) - Ask questions and share ideas ## Documentation Versions @@ -86,11 +85,11 @@ This documentation is for the latest version of ncps. For version-specific docum Found an error or want to improve the documentation? Contributions are welcome! -1. Documentation source files are in the `/docs` directory -1. Submit pull requests with improvements -1. Follow the existing structure and style -1. See Contributing for guidelines +1. Documentation source files are in the `/docs` directory +2. Submit pull requests with improvements +3. Follow the existing structure and style +4. See Contributing for guidelines -______________________________________________________________________ +--- -**Need Help?** Check the Troubleshooting or ask in [Discussions](https://github.com/kalbasit/ncps/discussions). +**Need Help?** Check the Troubleshooting or ask in [Discussions](https://github.com/kalbasit/ncps/discussions). \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration.md b/docs/docs/User Guide/Configuration.md index 97237002..5953474e 100644 --- a/docs/docs/User Guide/Configuration.md +++ b/docs/docs/User Guide/Configuration.md @@ -1,16 +1,15 @@ -# Configuration - +# Configuration ## Configuration Guide Learn how to configure ncps for your specific needs. ## Configuration Files -- Reference - Complete reference of all configuration options -- Storage - Configure local or S3 storage backends -- Database - Configure SQLite, PostgreSQL, or MySQL -- Analytics - Configure anonymous usage statistics reporting -- Observability - Set up metrics, logging, and tracing +* Reference - Complete reference of all configuration options +* Storage - Configure local or S3 storage backends +* Database - Configure SQLite, PostgreSQL, or MySQL +* Analytics - Configure anonymous usage statistics reporting +* Observability - Set up metrics, logging, and tracing ## Quick Links @@ -18,39 +17,39 @@ Learn how to configure ncps for your specific needs. **Getting Started** -- [All configuration options](Configuration/Reference.md) -- [Example Configuration](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) +* [All configuration options](Configuration/Reference.md) +* [Example Configuration](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) **Storage** -- Local Filesystem Storage -- S3-Compatible Storage -- Storage Comparison +* Local Filesystem Storage +* S3-Compatible Storage +* Storage Comparison **Database** -- SQLite Configuration -- PostgreSQL Configuration -- MySQL/MariaDB Configuration -- [Database Migrations](Configuration/Database/Migration%20Between%20Databases.md) +* SQLite Configuration +* PostgreSQL Configuration +* MySQL/MariaDB Configuration +* [Database Migrations](Configuration/Database/Migration%20Between%20Databases.md) **Observability** -- [Prometheus Metrics](Configuration/Observability.md) -- [Logging Setup](Configuration/Observability.md) -- [Tracing Setup](Configuration/Observability.md) +* [Prometheus Metrics](Configuration/Observability.md) +* [Logging Setup](Configuration/Observability.md) +* [Tracing Setup](Configuration/Observability.md) **Privacy & Analytics** -- [Analytics Overview](Configuration/Analytics.md) -- [Data Collection](Configuration/Analytics.md) -- [Opt-out Guide](Configuration/Analytics.md) +* [Analytics Overview](Configuration/Analytics.md) +* [Data Collection](Configuration/Analytics.md) +* [Opt-out Guide](Configuration/Analytics.md) ## Configuration Methods ncps supports multiple ways to configure the service: -### 1. Command-line Flags +### 1\. Command-line Flags ```sh ncps serve \ @@ -61,7 +60,7 @@ ncps serve \ --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ``` -### 2. Environment Variables +### 2\. Environment Variables ```sh export CACHE_HOSTNAME=cache.example.com @@ -73,7 +72,7 @@ export CACHE_UPSTREAM_PUBLIC_KEYS=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ1 ncps serve ``` -### 3. Configuration File +### 3\. Configuration File Create `config.yaml`: @@ -98,20 +97,20 @@ ncps serve --config=config.yaml **Supported formats:** -- YAML (`.yaml`, `.yml`) -- TOML (`.toml`) -- JSON (`.json`) +* YAML (`.yaml`, `.yml`) +* TOML (`.toml`) +* JSON (`.json`) See [Example Configuration](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) for a complete example. -### 4. Combination +### 4\. Combination Configuration methods can be combined. Priority (highest to lowest): -1. Command-line flags -1. Environment variables -1. Configuration file -1. Defaults +1. Command-line flags +2. Environment variables +3. Configuration file +4. Defaults ## Common Configuration Scenarios @@ -191,19 +190,19 @@ cache: These must be set for ncps to start: -- `cache.hostname` - Hostname for key generation -- Storage backend (choose one): - - `cache.storage.local` OR - - `cache.storage.s3.*` (bucket, endpoint, credentials) -- `cache.upstream.urls` - At least one upstream cache -- `cache.upstream.public-keys` - Corresponding public keys +* `cache.hostname` - Hostname for key generation +* Storage backend (choose one): + * `cache.storage.local` OR + * `cache.storage.s3.*` (bucket, endpoint, credentials) +* `cache.upstream.urls` - At least one upstream cache +* `cache.upstream.public-keys` - Corresponding public keys ### Optional But Recommended -- `cache.max-size` - Prevent unbounded cache growth -- `cache.lru.schedule` - Automatic cleanup -- `prometheus.enabled` - Metrics for monitoring -- `cache.database-url` - For shared database (default: embedded SQLite) +* `cache.max-size` - Prevent unbounded cache growth +* `cache.lru.schedule` - Automatic cleanup +* `prometheus.enabled` - Metrics for monitoring +* `cache.database-url` - For shared database (default: embedded SQLite) ## Validation @@ -219,13 +218,13 @@ ncps serve --config=config.yaml --log-level=debug ## Next Steps -1. Reference - See all available options -1. Storage - Choose and configure storage backend -1. Database - Choose and configure database -1. Observability - Set up monitoring +1. Reference - See all available options +2. Storage - Choose and configure storage backend +3. Database - Choose and configure database +4. Observability - Set up monitoring ## Related Documentation -- [Example configuration file](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) - Complete configuration example -- [Installation Guides](Installation.md) - Installation-specific configuration -- [Observability Configuration](Configuration/Observability.md) - Observability-specific configuration +* [Example configuration file](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) - Complete configuration example +* [Installation Guides](Installation.md) - Installation-specific configuration +* [Observability Configuration](Configuration/Observability.md) - Observability-specific configuration \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Analytics.md b/docs/docs/User Guide/Configuration/Analytics.md index 717235f2..845201cb 100644 --- a/docs/docs/User Guide/Configuration/Analytics.md +++ b/docs/docs/User Guide/Configuration/Analytics.md @@ -1,5 +1,4 @@ -# Analytics - +# Analytics ## Analytics Reporting Configure anonymous usage statistics reporting to help improve ncps. @@ -10,16 +9,16 @@ ncps includes an optional analytics reporting system that collects anonymous usa **Key Points:** -- **Enabled by default** - Can be disabled with `--analytics-reporting-enabled=false` -- **Fully anonymous** - No personal data, IP addresses, or cache contents -- **Minimal overhead** - Metrics sent once per hour, logs only on startup and errors -- **Privacy-focused** - Only collects configuration metadata and aggregate statistics +* **Enabled by default** - Can be disabled with `--analytics-reporting-enabled=false` +* **Fully anonymous** - No personal data, IP addresses, or cache contents +* **Minimal overhead** - Metrics sent once per hour, logs only on startup and errors +* **Privacy-focused** - Only collects configuration metadata and aggregate statistics ## What Data is Collected? Analytics reporting collects three types of data: -### 1. Resource Attributes (Metadata) +### 1\. Resource Attributes (Metadata) These attributes are attached to all metrics and logs: @@ -33,7 +32,7 @@ These attributes are attached to all metrics and logs: **Note:** The `cluster_uuid` is randomly generated and stored in your database. It helps identify unique installations but contains no identifying information about your organization or infrastructure. -### 2. Metrics (Sent Hourly) +### 2\. Metrics (Sent Hourly) Aggregate statistics about cache usage: @@ -45,7 +44,7 @@ Aggregate statistics about cache usage: These metrics are sent every **1 hour** to minimize network overhead. -### 3. Logs +### 3\. Logs Event logs for application lifecycle: @@ -60,14 +59,14 @@ Event logs for application lifecycle: Analytics reporting explicitly **does not** collect: -- **Personal information** - No usernames, emails, or other PII -- **Network information** - No IP addresses, hostnames, or network topology -- **Host information** - No hostname or process owner user -- **Cache contents** - No store paths, package names, or derivation data -- **Configuration secrets** - No passwords, keys, or authentication tokens -- **Request logs** - No HTTP requests, client information, or access patterns -- **Storage paths** - No file paths, bucket names, or storage configuration -- **Upstream URLs** - No upstream cache URLs or authentication details +* **Personal information** - No usernames, emails, or other PII +* **Network information** - No IP addresses, hostnames, or network topology +* **Host information** - No hostname or process owner user +* **Cache contents** - No store paths, package names, or derivation data +* **Configuration secrets** - No passwords, keys, or authentication tokens +* **Request logs** - No HTTP requests, client information, or access patterns +* **Storage paths** - No file paths, bucket names, or storage configuration +* **Upstream URLs** - No upstream cache URLs or authentication details ## Analytics Endpoint @@ -79,9 +78,9 @@ otlp.ncps.dev:443 This endpoint receives OpenTelemetry data over HTTPS using: -- **OTLP/HTTP** protocol -- **gzip compression** to minimize bandwidth -- **TLS encryption** for secure transmission +* **OTLP/HTTP** protocol +* **gzip compression** to minimize bandwidth +* **TLS encryption** for secure transmission ## Privacy and Security @@ -89,8 +88,8 @@ This endpoint receives OpenTelemetry data over HTTPS using: Analytics data is retained for: -- **Metrics**: 90 days (for trend analysis) -- **Logs**: 30 days (for bug identification) +* **Metrics**: 90 days (for trend analysis) +* **Logs**: 30 days (for bug identification) After this period, data is automatically deleted. @@ -98,25 +97,25 @@ After this period, data is automatically deleted. Analytics data is used exclusively for: -- Understanding deployment patterns (database types, HA vs single-instance) -- Identifying common cache sizes to inform default configurations -- Detecting bugs through panic logs -- Measuring upstream health trends -- Planning future development priorities +* Understanding deployment patterns (database types, HA vs single-instance) +* Identifying common cache sizes to inform default configurations +* Detecting bugs through panic logs +* Measuring upstream health trends +* Planning future development priorities Analytics data is **never**: -- Sold to third parties -- Used for advertising or tracking -- Shared outside the ncps project maintainers -- Used to identify individual users or organizations +* Sold to third parties +* Used for advertising or tracking +* Shared outside the ncps project maintainers +* Used to identify individual users or organizations ### Security -- All data transmission uses TLS encryption -- No authentication tokens or credentials are collected -- Panic logs are sanitized to remove environment variables -- The cluster UUID is randomly generated and cannot be traced back to your organization +* All data transmission uses TLS encryption +* No authentication tokens or credentials are collected +* Panic logs are sanitized to remove environment variables +* The cluster UUID is randomly generated and cannot be traced back to your organization ## Configuration @@ -221,16 +220,16 @@ One of the key features of the analytics system is **panic recovery** for backgr ncps uses `analytics.SafeGo()` to wrap all background goroutines with panic recovery. When a panic occurs: -1. **Panic is caught** - The goroutine doesn't crash the entire application -1. **Stack trace is captured** - Full stack trace for debugging -1. **Logged locally** - Panic is logged to application logs (always, regardless of analytics setting) -1. **Reported to analytics** - If analytics is enabled, panic is sent to maintainers +1. **Panic is caught** - The goroutine doesn't crash the entire application +2. **Stack trace is captured** - Full stack trace for debugging +3. **Logged locally** - Panic is logged to application logs (always, regardless of analytics setting) +4. **Reported to analytics** - If analytics is enabled, panic is sent to maintainers This ensures that: -- Your ncps instance stays running even if a background operation fails -- Bugs are reported to maintainers automatically (if analytics enabled) -- You have local logs for your own troubleshooting +* Your ncps instance stays running even if a background operation fails +* Bugs are reported to maintainers automatically (if analytics enabled) +* You have local logs for your own troubleshooting ### Example Panic Log @@ -247,15 +246,15 @@ This ensures that: **Analytics log (if enabled):** -Includes the same information plus resource attributes (service version, db_type, etc.) to help maintainers identify patterns. +Includes the same information plus resource attributes (service version, db\_type, etc.) to help maintainers identify patterns. ### SafeGo Usage When analytics is enabled, the following operations use `SafeGo()` for panic protection: -- **LRU cleanup** - Background cache eviction operations -- **Health checks** - Upstream cache health monitoring -- **Metrics collection** - Periodic statistics gathering +* **LRU cleanup** - Background cache eviction operations +* **Health checks** - Upstream cache health monitoring +* **Metrics collection** - Periodic statistics gathering ## Troubleshooting @@ -263,37 +262,34 @@ When analytics is enabled, the following operations use `SafeGo()` for panic pro If you expect analytics to be enabled but don't see the startup message: -1. **Check the flag value:** - - ``` - ncps serve --help | grep analytics - ``` - -1. **Verify environment variables:** - - ``` - echo $ANALYTICS_REPORTING_ENABLED - ``` +1. **Check the flag value:** -1. **Check configuration file:** + ``` + ncps serve --help | grep analytics + ``` +2. **Verify environment variables:** - ``` - cat config.yaml | grep -A 3 analytics - ``` + ``` + echo $ANALYTICS_REPORTING_ENABLED + ``` +3. **Check configuration file:** -1. **Check for errors in logs:** + ``` + cat config.yaml | grep -A 3 analytics + ``` +4. **Check for errors in logs:** - ``` - journalctl -u ncps | grep -i analytics - ``` + ``` + journalctl -u ncps | grep -i analytics + ``` ### Network Issues If analytics fails to connect to `otlp.ncps.dev:443`: -- **Firewall** - Ensure outbound HTTPS (port 443) is allowed -- **Proxy** - OpenTelemetry respects HTTP proxy environment variables -- **DNS** - Verify `otlp.ncps.dev` resolves correctly +* **Firewall** - Ensure outbound HTTPS (port 443) is allowed +* **Proxy** - OpenTelemetry respects HTTP proxy environment variables +* **DNS** - Verify `otlp.ncps.dev` resolves correctly Analytics failures are **non-fatal** - if the analytics endpoint is unreachable, ncps will log a warning but continue operating normally. @@ -349,10 +345,10 @@ See Observability for de Analytics is enabled by default because: -1. **Low overhead** - Minimal network usage (1 request per hour) -1. **Privacy-focused** - No sensitive data collection -1. **Helpful to maintainers** - Informs development priorities -1. **Easy opt-out** - Single flag to disable +1. **Low overhead** - Minimal network usage (1 request per hour) +2. **Privacy-focused** - No sensitive data collection +3. **Helpful to maintainers** - Informs development priorities +4. **Easy opt-out** - Single flag to disable This follows the model of other privacy-respecting open source projects like Homebrew, which collect anonymous statistics to understand usage patterns without compromising user privacy. @@ -362,17 +358,17 @@ This follows the model of other privacy-respecting open source projects like Hom No. Analytics has negligible performance impact: -- Metrics sent once per hour (not per request) -- Uses background goroutines (non-blocking) -- Compressed data (minimal bandwidth) +* Metrics sent once per hour (not per request) +* Uses background goroutines (non-blocking) +* Compressed data (minimal bandwidth) ### What if the analytics endpoint is down? If `otlp.ncps.dev` is unreachable: -- ncps logs a warning but continues operating -- No retries or queuing (to avoid memory buildup) -- Analytics automatically resumes when endpoint is available +* ncps logs a warning but continues operating +* No retries or queuing (to avoid memory buildup) +* Analytics automatically resumes when endpoint is available ### Can I host my own analytics collector? @@ -382,23 +378,23 @@ Not currently. The analytics endpoint is hardcoded to `otlp.ncps.dev:443`. If yo Unlike telemetry systems that collect invasive data, ncps analytics: -- **Is transparent** - This documentation explains exactly what's collected -- **Is minimal** - Only configuration metadata and aggregate statistics -- **Is optional** - Easy one-flag opt-out -- **Respects privacy** - No PII, IP addresses, or tracking -- **Has retention limits** - Data automatically deleted after 30-90 days -- **Is open source** - You can review the code in `pkg/analytics/` +* **Is transparent** - This documentation explains exactly what's collected +* **Is minimal** - Only configuration metadata and aggregate statistics +* **Is optional** - Easy one-flag opt-out +* **Respects privacy** - No PII, IP addresses, or tracking +* **Has retention limits** - Data automatically deleted after 30-90 days +* **Is open source** - You can review the code in `pkg/analytics/` ## Related Documentation -- Reference - All configuration options -- Observability - OpenTelemetry and Prometheus +* Reference - All configuration options +* Observability - OpenTelemetry and Prometheus ## Feedback Have questions or concerns about analytics? Please: -- Open an issue: [github.com/kalbasit/ncps/issues](https://github.com/kalbasit/ncps/issues) -- Start a discussion: [github.com/kalbasit/ncps/discussions](https://github.com/kalbasit/ncps/discussions) +* Open an issue: [github.com/kalbasit/ncps/issues](https://github.com/kalbasit/ncps/issues) +* Start a discussion: [github.com/kalbasit/ncps/discussions](https://github.com/kalbasit/ncps/discussions) -Your feedback helps us balance transparency, privacy, and useful data collection. +Your feedback helps us balance transparency, privacy, and useful data collection. \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Database.md b/docs/docs/User Guide/Configuration/Database.md index 496231a0..053a82a9 100644 --- a/docs/docs/User Guide/Configuration/Database.md +++ b/docs/docs/User Guide/Configuration/Database.md @@ -1,5 +1,4 @@ -# Database - +# Database ## Database Configuration Configure ncps database backends: SQLite, PostgreSQL, or MySQL/MariaDB. @@ -8,9 +7,9 @@ Configure ncps database backends: SQLite, PostgreSQL, or MySQL/MariaDB. ncps supports three database backends for storing metadata (NarInfo, cache statistics, etc.): -- **SQLite**: Embedded database, no external dependencies -- **PostgreSQL**: Production-ready, concurrent access support -- **MySQL/MariaDB**: Production-ready, concurrent access support +* **SQLite**: Embedded database, no external dependencies +* **PostgreSQL**: Production-ready, concurrent access support +* **MySQL/MariaDB**: Production-ready, concurrent access support ## Quick Comparison @@ -25,13 +24,13 @@ ncps supports three database backends for storing metadata (NarInfo, cache stati ## Next Steps -1. [Storage Configuration](Storage.md) - Configure storage backend -1. [Configuration Reference](Reference.md) - All database options -1. High Availability - PostgreSQL/MySQL for HA -1. [Operations Guide](../Operations/Backup%20Restore.md) - Backup strategies +1. [Storage Configuration](Storage.md) - Configure storage backend +2. [Configuration Reference](Reference.md) - All database options +3. High Availability - PostgreSQL/MySQL for HA +4. [Operations Guide](../Operations/Backup%20Restore.md) - Backup strategies ## Related Documentation -- [Configuration Reference](Reference.md) - All configuration options -- [High Availability Guide](../Deployment/High%20Availability.md) - HA database setup -- [Backup and Restore Guide](../Operations/Backup%20Restore.md) - Backup strategies +* [Configuration Reference](Reference.md) - All configuration options +* [High Availability Guide](../Deployment/High%20Availability.md) - HA database setup +* [Backup and Restore Guide](../Operations/Backup%20Restore.md) - Backup strategies \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Database/Migration Between Databases.md b/docs/docs/User Guide/Configuration/Database/Migration Between Databases.md index 3619fe6d..35ac04a3 100644 --- a/docs/docs/User Guide/Configuration/Database/Migration Between Databases.md +++ b/docs/docs/User Guide/Configuration/Database/Migration Between Databases.md @@ -1,5 +1,4 @@ -# Migration Between Databases - +# Migration Between Databases ### From SQLite to PostgreSQL ``` @@ -27,6 +26,6 @@ pgloader sqlite:///var/lib/ncps/db/db.sqlite \ Similar process using tools like: -- `sqlite3mysql` utility -- Manual export and conversion -- Custom migration scripts +* `sqlite3mysql` utility +* Manual export and conversion +* Custom migration scripts \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Database/MySQLMariaDB Configuration.md b/docs/docs/User Guide/Configuration/Database/MySQLMariaDB Configuration.md index 1647611f..d5df5ed3 100644 --- a/docs/docs/User Guide/Configuration/Database/MySQLMariaDB Configuration.md +++ b/docs/docs/User Guide/Configuration/Database/MySQLMariaDB Configuration.md @@ -1,16 +1,15 @@ -# MySQL/MariaDB Configuration - +# MySQL/MariaDB Configuration ### When to Use -- Same use cases as PostgreSQL -- Existing MySQL infrastructure -- Familiarity with MySQL ecosystem +* Same use cases as PostgreSQL +* Existing MySQL infrastructure +* Familiarity with MySQL ecosystem ### Prerequisites -- MySQL 8.0+ or MariaDB 10.3+ server -- Database and user created -- Network connectivity from ncps to MySQL +* MySQL 8.0+ or MariaDB 10.3+ server +* Database and user created +* Network connectivity from ncps to MySQL ### Setup MySQL @@ -49,9 +48,9 @@ mysql://[username]:[password]@[host]:[port]/[database]?[options] **Common options:** -- `socket` - Path to the Unix domain socket. -- `tls=true` - Enable TLS. -- `charset=utf8mb4` - Set character encoding. +* `socket` - Path to the Unix domain socket. +* `tls=true` - Enable TLS. +* `charset=utf8mb4` - Set character encoding. **Examples:** @@ -102,4 +101,4 @@ mysqldump -u ncps -p ncps > /backup/ncps.sql ``` mysql -u ncps -p ncps < /backup/ncps.sql -``` +``` \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Database/PostgreSQL Configuration.md b/docs/docs/User Guide/Configuration/Database/PostgreSQL Configuration.md index 1ee4d50a..3753cf7b 100644 --- a/docs/docs/User Guide/Configuration/Database/PostgreSQL Configuration.md +++ b/docs/docs/User Guide/Configuration/Database/PostgreSQL Configuration.md @@ -1,17 +1,16 @@ -# PostgreSQL Configuration - +# PostgreSQL Configuration ### When to Use -- **High availability deployments**: Multiple ncps instances -- **Production environments**: Scalability and reliability required -- **Large teams**: High concurrent access -- **Cloud-native deployments** +* **High availability deployments**: Multiple ncps instances +* **Production environments**: Scalability and reliability required +* **Large teams**: High concurrent access +* **Cloud-native deployments** ### Prerequisites -- PostgreSQL 12+ server -- Database and user created -- Network connectivity from ncps to PostgreSQL +* PostgreSQL 12+ server +* Database and user created +* Network connectivity from ncps to PostgreSQL ### Setup PostgreSQL @@ -57,10 +56,10 @@ postgresql://[username]:[password]@[host]:[port]/[database]?[options] **Common options:** -- `host` - Hostname or path to the directory containing the Unix domain socket. -- `sslmode=require` - Require TLS encryption. -- `sslmode=disable` - Disable TLS (not recommended for production). -- `connect_timeout=10` - Connection timeout in seconds. +* `host` - Hostname or path to the directory containing the Unix domain socket. +* `sslmode=require` - Require TLS encryption. +* `sslmode=disable` - Disable TLS (not recommended for production). +* `connect_timeout=10` - Connection timeout in seconds. **Examples:** @@ -85,8 +84,8 @@ postgresql://ncps:password@localhost:5432/ncps?sslmode=require&connect_timeout=1 **Defaults for PostgreSQL:** -- Max open connections: 25 -- Max idle connections: 5 +* Max open connections: 25 +* Max idle connections: 5 **Custom settings:** @@ -144,4 +143,4 @@ pg_dump -h localhost -U ncps ncps > /backup/ncps.sql ``` psql -h localhost -U ncps ncps < /backup/ncps.sql -``` +``` \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Database/SQLite Configuration.md b/docs/docs/User Guide/Configuration/Database/SQLite Configuration.md index 119659ed..c34d8a76 100644 --- a/docs/docs/User Guide/Configuration/Database/SQLite Configuration.md +++ b/docs/docs/User Guide/Configuration/Database/SQLite Configuration.md @@ -1,11 +1,10 @@ -# SQLite Configuration - +# SQLite Configuration ### When to Use -- **Single-instance deployments**: One ncps server only -- **Simple setup**: No external database required -- **Development and testing** -- **Small to medium teams** (up to 100+ users) +* **Single-instance deployments**: One ncps server only +* **Simple setup**: No external database required +* **Development and testing** +* **Small to medium teams** (up to 100+ users) **Important:** SQLite does NOT support high-availability deployments with multiple instances. @@ -61,16 +60,16 @@ SQLite enforces a maximum of 1 open connection: **Pros:** -- Zero configuration -- Fast for single-instance -- No network overhead -- Automatic backups (file copy) +* Zero configuration +* Fast for single-instance +* No network overhead +* Automatic backups (file copy) **Cons:** -- Single writer at a time -- Not suitable for HA -- Limited scalability +* Single writer at a time +* Not suitable for HA +* Limited scalability ### Backup and Restore @@ -93,4 +92,4 @@ systemctl start ncps systemctl stop ncps cp /backup/db.sqlite.20240101 /var/lib/ncps/db/db.sqlite systemctl start ncps -``` +``` \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Database/Troubleshooting.md b/docs/docs/User Guide/Configuration/Database/Troubleshooting.md index 8af51aaf..e65551fe 100644 --- a/docs/docs/User Guide/Configuration/Database/Troubleshooting.md +++ b/docs/docs/User Guide/Configuration/Database/Troubleshooting.md @@ -1,12 +1,11 @@ -# Troubleshooting - +# Troubleshooting ### SQLite Issues **Database Locked:** -- Only one writer at a time -- Ensure no other processes are accessing the database -- Check for stale lock files +* Only one writer at a time +* Ensure no other processes are accessing the database +* Check for stale lock files **Corruption:** @@ -22,34 +21,34 @@ sqlite3 /var/lib/ncps/db/db.sqlite ".recover" | sqlite3 recovered.db **Connection Refused:** -- Check PostgreSQL is running: `systemctl status postgresql` -- Verify `pg_hba.conf` allows connections from ncps host -- Check firewall rules +* Check PostgreSQL is running: `systemctl status postgresql` +* Verify `pg_hba.conf` allows connections from ncps host +* Check firewall rules **Authentication Failed:** -- Verify username and password -- Check `pg_hba.conf` authentication method -- Ensure user has correct privileges +* Verify username and password +* Check `pg_hba.conf` authentication method +* Ensure user has correct privileges **Too Many Connections:** -- Reduce pool size in ncps -- Increase `max_connections` in PostgreSQL -- Check for connection leaks +* Reduce pool size in ncps +* Increase `max_connections` in PostgreSQL +* Check for connection leaks ### MySQL Issues **Connection Refused:** -- Check MySQL is running: `systemctl status mysql` -- Verify `bind-address` in my.cnf -- Check firewall rules +* Check MySQL is running: `systemctl status mysql` +* Verify `bind-address` in my.cnf +* Check firewall rules **Access Denied:** -- Verify username, password, and host in GRANT -- Check user privileges: `SHOW GRANTS FOR 'ncps'@'%';` -- Flush privileges after changes +* Verify username, password, and host in GRANT +* Check user privileges: `SHOW GRANTS FOR 'ncps'@'%';` +* Flush privileges after changes -See the [Troubleshooting Guide](../../Operations/Troubleshooting.md) for more help. +See the [Troubleshooting Guide](../../Operations/Troubleshooting.md) for more help. \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Observability.md b/docs/docs/User Guide/Configuration/Observability.md index 95f0bc89..c6269006 100644 --- a/docs/docs/User Guide/Configuration/Observability.md +++ b/docs/docs/User Guide/Configuration/Observability.md @@ -1,5 +1,4 @@ -# Observability - +# Observability ## Observability Configuration Configure monitoring, metrics, logging, and tracing for ncps. @@ -8,10 +7,10 @@ Configure monitoring, metrics, logging, and tracing for ncps. ncps provides comprehensive observability through: -- **Prometheus** - Metrics endpoint for monitoring your deployment -- **OpenTelemetry** - Distributed tracing and telemetry for your infrastructure -- **Structured Logging** - JSON-formatted logs with context -- **Analytics Reporting** - Anonymous usage statistics sent to project maintainers (separate from your monitoring) +* **Prometheus** - Metrics endpoint for monitoring your deployment +* **OpenTelemetry** - Distributed tracing and telemetry for your infrastructure +* **Structured Logging** - JSON-formatted logs with context +* **Analytics Reporting** - Anonymous usage statistics sent to project maintainers (separate from your monitoring) **Important:** This page covers observability for **your own deployment** (Prometheus, OpenTelemetry, logs). For information about anonymous usage statistics sent to project maintainers, see [Analytics Configuration](Analytics.md). @@ -51,49 +50,49 @@ http://your-ncps:8501/metrics **HTTP Metrics** (via otelchi middleware): -- `http_server_requests_total` - Total HTTP requests -- `http_server_request_duration_seconds` - Request duration histogram -- `http_server_active_requests` - Currently active requests +* `http_server_requests_total` - Total HTTP requests +* `http_server_request_duration_seconds` - Request duration histogram +* `http_server_active_requests` - Currently active requests **Cache Metrics:** -- `ncps_nar_served_total` - Total NAR files served -- `ncps_narinfo_served_total` - Total NarInfo files served +* `ncps_nar_served_total` - Total NAR files served +* `ncps_narinfo_served_total` - Total NarInfo files served **Upstream Health Metrics** (available when analytics reporting is enabled): -- `ncps_upstream_count_healthy` - Number of healthy upstream caches -- `ncps_upstream_count_total` - Total number of configured upstream caches +* `ncps_upstream_count_healthy` - Number of healthy upstream caches +* `ncps_upstream_count_total` - Total number of configured upstream caches Note: Upstream health metrics are collected as part of analytics reporting. See [Analytics Configuration](Analytics.md) for details. **Lock Metrics** (when using Redis for HA): -- `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisition attempts - - `type`: "download" or "lru" - - `result`: "success" or "failure" - - `mode`: "local" or "distributed" -- `ncps_lock_hold_duration_seconds{type,mode}` - Lock hold time histogram -- `ncps_lock_failures_total{type,reason,mode}` - Lock failures - - `reason`: "timeout", "redis_error", "circuit_breaker" -- `ncps_lock_retry_attempts_total{type}` - Retry attempts +* `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisition attempts + * `type`: "download" or "lru" + * `result`: "success" or "failure" + * `mode`: "local" or "distributed" +* `ncps_lock_hold_duration_seconds{type,mode}` - Lock hold time histogram +* `ncps_lock_failures_total{type,reason,mode}` - Lock failures + * `reason`: "timeout", "redis\_error", "circuit\_breaker" +* `ncps_lock_retry_attempts_total{type}` - Retry attempts **Migration Metrics** (during narinfo migration): -- `ncps_migration_narinfos_total{operation,result}` - NarInfo migration operations - - `operation`: "migrate" or "delete" - - `result`: "success", "failure", or "skipped" -- `ncps_migration_duration_seconds{operation}` - Migration operation duration histogram - - `operation`: "migrate" or "delete" -- `ncps_migration_batch_size` - Migration batch size histogram +* `ncps_migration_narinfos_total{operation,result}` - NarInfo migration operations + * `operation`: "migrate" or "delete" + * `result`: "success", "failure", or "skipped" +* `ncps_migration_duration_seconds{operation}` - Migration operation duration histogram + * `operation`: "migrate" or "delete" +* `ncps_migration_batch_size` - Migration batch size histogram **Background Migration Metrics** (during on-the-fly migration): -- `ncps_background_migration_narinfos_total{operation,result}` - Background NarInfo migration operations - - `operation`: "migrate" or "delete" - - `result`: "success" or "failure" -- `ncps_background_migration_duration_seconds{operation}` - Background migration operation duration histogram - - `operation`: "migrate" or "delete" +* `ncps_background_migration_narinfos_total{operation,result}` - Background NarInfo migration operations + * `operation`: "migrate" or "delete" + * `result`: "success" or "failure" +* `ncps_background_migration_duration_seconds{operation}` - Background migration operation duration histogram + * `operation`: "migrate" or "delete" See [NarInfo Migration Guide](../Operations/NarInfo%20Migration.md) for migration documentation. @@ -133,16 +132,16 @@ Create dashboards to visualize: **Cache Performance:** -- Cache hit rate -- NAR files served (rate) -- Request duration percentiles (p50, p95, p99) +* Cache hit rate +* NAR files served (rate) +* Request duration percentiles (p50, p95, p99) **HA Lock Performance:** -- Lock acquisition success/failure rate -- Lock hold duration -- Retry attempt rate -- Lock contention +* Lock acquisition success/failure rate +* Lock hold duration +* Retry attempt rate +* Lock contention See the [Monitoring Guide](../Operations/Monitoring.md) for dashboard examples. @@ -183,7 +182,7 @@ export OTEL_GRPC_URL=http://otel-collector:4317 When enabled, OpenTelemetry provides: -**1. Logs** - Structured application logs **2. Metrics** - Application and system metrics **3. Traces** - Distributed request tracing +**1\. Logs** - Structured application logs **2\. Metrics** - Application and system metrics **3\. Traces** - Distributed request tracing ### OpenTelemetry Collector Setup @@ -279,10 +278,10 @@ ncps serve --log-level=debug **Levels:** -- `debug` - Verbose logging, including debug information -- `info` - Standard informational messages (default) -- `warn` - Warning messages only -- `error` - Error messages only +* `debug` - Verbose logging, including debug information +* `info` - Standard informational messages (default) +* `warn` - Warning messages only +* `error` - Error messages only **Configuration file:** @@ -310,21 +309,21 @@ Logs are output in JSON format with structured fields: **Cache Operations:** -- `serving nar from cache` - NAR file served from cache -- `downloading nar from upstream` - Fetching from upstream -- `nar cached successfully` - Download and cache complete +* `serving nar from cache` - NAR file served from cache +* `downloading nar from upstream` - Fetching from upstream +* `nar cached successfully` - Download and cache complete **Lock Operations (HA):** -- `acquired download lock` - Download lock obtained -- `failed to acquire lock` - Lock acquisition failed after retries -- `another instance is running LRU` - LRU skipped (another instance running) -- `circuit breaker open: Redis is unavailable` - Redis connectivity issues +* `acquired download lock` - Download lock obtained +* `failed to acquire lock` - Lock acquisition failed after retries +* `another instance is running LRU` - LRU skipped (another instance running) +* `circuit breaker open: Redis is unavailable` - Redis connectivity issues **Server:** -- `server started` - ncps HTTP server started -- `server shutdown` - Graceful shutdown initiated +* `server started` - ncps HTTP server started +* `server shutdown` - Graceful shutdown initiated ### Log Aggregation @@ -393,12 +392,12 @@ Access Jaeger UI at `http://localhost:16686` to view traces. Traces include: -- Request ID -- Upstream cache calls -- Lock acquisitions (HA mode) -- Database queries -- S3 operations -- Download and cache operations +* Request ID +* Upstream cache calls +* Lock acquisitions (HA mode) +* Database queries +* S3 operations +* Download and cache operations ## Health Checks @@ -504,20 +503,20 @@ services: **Access:** -- ncps: `http://localhost:8501` -- Prometheus: `http://localhost:9090` -- Grafana: `http://localhost:3000` (admin/admin) -- Jaeger: `http://localhost:16686` +* ncps: `http://localhost:8501` +* Prometheus: `http://localhost:9090` +* Grafana: `http://localhost:3000` (admin/admin) +* Jaeger: `http://localhost:16686` ## Next Steps -1. Monitoring - Set up dashboards and alerts -1. Troubleshooting - Use logs and metrics to debug -1. Reference - All observability options +1. Monitoring - Set up dashboards and alerts +2. Troubleshooting - Use logs and metrics to debug +3. Reference - All observability options ## Related Documentation -- Analytics - Anonymous usage statistics reporting -- Monitoring - Detailed monitoring setup -- High Availability - HA observability -- Reference - All configuration options +* Analytics - Anonymous usage statistics reporting +* Monitoring - Detailed monitoring setup +* High Availability - HA observability +* Reference - All configuration options \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Reference.md b/docs/docs/User Guide/Configuration/Reference.md index a02b385f..b641a836 100644 --- a/docs/docs/User Guide/Configuration/Reference.md +++ b/docs/docs/User Guide/Configuration/Reference.md @@ -1,5 +1,4 @@ -# Reference - +# Reference ## Configuration Reference Complete reference for all ncps configuration options. @@ -13,7 +12,7 @@ Options that apply to the entire ncps process. | `--config` | Path to configuration file (json, toml, yaml) | `NCPS_CONFIG_FILE` | `$XDG_CONFIG_HOME/ncps/config.yaml` | | `--log-level` | Log level: debug, info, warn, error | `LOG_LEVEL` | `info` | | `--otel-enabled` | Enable OpenTelemetry (logs, metrics, tracing) | `OTEL_ENABLED` | `false` | -| `--otel-grpc-url` | OpenTelemetry gRPC collector URL (omit for stdout) | `OTEL_GRPC_URL` | - | +| `--otel-grpc-url` | OpenTelemetry gRPC collector URL (omit for stdout) | `OTEL_GRPC_URL` | \- | | `--prometheus-enabled` | Enable Prometheus metrics endpoint at /metrics | `PROMETHEUS_ENABLED` | `false` | **Example:** @@ -84,13 +83,13 @@ Use these options for S3-compatible storage (AWS S3, MinIO, etc.). | Option | Description | Environment Variable | Required for S3 | Default | | --- | --- | --- | --- | --- | -| `--cache-storage-s3-bucket` | S3 bucket name | `CACHE_STORAGE_S3_BUCKET` | ✅ | - | -| `--cache-storage-s3-endpoint` | S3 endpoint URL with scheme (e.g., [https://s3.amazonaws.com](https://s3.amazonaws.com) or [http://minio:9000](http://minio:9000)) | `CACHE_STORAGE_S3_ENDPOINT` | ✅ | - | -| `--cache-storage-s3-access-key-id` | S3 access key ID | `CACHE_STORAGE_S3_ACCESS_KEY_ID` | ✅ | - | -| `--cache-storage-s3-secret-access-key` | S3 secret access key | `CACHE_STORAGE_S3_SECRET_ACCESS_KEY` | ✅ | - | -| `--cache-storage-s3-region` | S3 region (optional for some providers) | `CACHE_STORAGE_S3_REGION` | - | - | -| `--cache-storage-s3-force-path-style` | Use path-style URLs (required for MinIO) | `CACHE_STORAGE_S3_FORCE_PATH_STYLE` | - | `false` | -| `--cache-storage-s3-use-ssl` | **DEPRECATED:** Specify scheme in endpoint instead | `CACHE_STORAGE_S3_USE_SSL` | - | - | +| `--cache-storage-s3-bucket` | S3 bucket name | `CACHE_STORAGE_S3_BUCKET` | ✅ | \- | +| `--cache-storage-s3-endpoint` | S3 endpoint URL with scheme (e.g., [https://s3.amazonaws.com](https://s3.amazonaws.com) or [http://minio:9000](http://minio:9000)) | `CACHE_STORAGE_S3_ENDPOINT` | ✅ | \- | +| `--cache-storage-s3-access-key-id` | S3 access key ID | `CACHE_STORAGE_S3_ACCESS_KEY_ID` | ✅ | \- | +| `--cache-storage-s3-secret-access-key` | S3 secret access key | `CACHE_STORAGE_S3_SECRET_ACCESS_KEY` | ✅ | \- | +| `--cache-storage-s3-region` | S3 region (optional for some providers) | `CACHE_STORAGE_S3_REGION` | \- | \- | +| `--cache-storage-s3-force-path-style` | Use path-style URLs (required for MinIO) | `CACHE_STORAGE_S3_FORCE_PATH_STYLE` | \- | `false` | +| `--cache-storage-s3-use-ssl` | **DEPRECATED:** Specify scheme in endpoint instead | `CACHE_STORAGE_S3_USE_SSL` | \- | \- | **Note:** The endpoint must include the scheme (`https://` or `http://`). The `--cache-storage-s3-use-ssl` flag is deprecated in favor of specifying the scheme directly in the endpoint URL. @@ -128,7 +127,7 @@ See Storage for details. | `--cache-database-pool-max-open-conns` | Maximum open database connections | `CACHE_DATABASE_POOL_MAX_OPEN_CONNS` | 25 (PG/MySQL), 1 (SQLite) | | `--cache-database-pool-max-idle-conns` | Maximum idle database connections | `CACHE_DATABASE_POOL_MAX_IDLE_CONNS` | 5 (PG/MySQL), unset (SQLite) | | `--cache-max-size` | Maximum cache size (5K, 10G, etc.) | `CACHE_MAX_SIZE` | unlimited | -| `--cache-lru-schedule` | LRU cleanup cron schedule | `CACHE_LRU_SCHEDULE` | - | +| `--cache-lru-schedule` | LRU cleanup cron schedule | `CACHE_LRU_SCHEDULE` | \- | | `--cache-temp-path` | Temporary download directory | `CACHE_TEMP_PATH` | system temp | > [!IMPORTANT] @@ -136,18 +135,18 @@ See Storage for details. **Database URL Formats:** -- SQLite: `sqlite:/var/lib/ncps/db/db.sqlite` -- PostgreSQL: `postgresql://user:pass@host:5432/database?sslmode=require` -- PostgreSQL (Socket): `postgresql:///database?host=/var/run/postgresql` -- MySQL: `mysql://user:pass@host:3306/database` -- MySQL (Socket): `mysql://user:pass@/database?socket=/var/run/mysqld/mysqld.sock` +* SQLite: `sqlite:/var/lib/ncps/db/db.sqlite` +* PostgreSQL: `postgresql://user:pass@host:5432/database?sslmode=require` +* PostgreSQL (Socket): `postgresql:///database?host=/var/run/postgresql` +* MySQL: `mysql://user:pass@host:3306/database` +* MySQL (Socket): `mysql://user:pass@/database?socket=/var/run/mysqld/mysqld.sock` **Notes on Sockets:** For MySQL and PostgreSQL, you can use specialized schemes for Unix domain sockets: -- `mysql+unix:///path/to/socket.sock/database` -- `postgres+unix:///path/to/socket_dir/database` +* `mysql+unix:///path/to/socket.sock/database` +* `postgres+unix:///path/to/socket_dir/database` **Example:** @@ -190,9 +189,9 @@ Configure timeout values for upstream cache connections. Increase these if exper **Common timeout values:** -- `3s` - Default, works for most local/fast upstreams -- `10s` - Recommended for slow networks or distant upstreams -- `30s` - For very slow connections (satellite, slow VPN) +* `3s` - Default, works for most local/fast upstreams +* `10s` - Recommended for slow networks or distant upstreams +* `30s` - For very slow connections (satellite, slow VPN) **Example:** @@ -211,11 +210,11 @@ Redis configuration for distributed locking in high-availability deployments. | Option | Description | Environment Variable | Default | | --- | --- | --- | --- | | `--cache-redis-addrs` | Redis addresses (comma-separated for cluster) | `CACHE_REDIS_ADDRS` | (none - local mode) | -| `--cache-redis-username` | Redis ACL username | `CACHE_REDIS_USERNAME` | "" | -| `--cache-redis-password` | Redis password | `CACHE_REDIS_PASSWORD` | "" | -| `--cache-redis-db` | Redis database number (0-15) | `CACHE_REDIS_DB` | 0 | +| `--cache-redis-username` | Redis ACL username | `CACHE_REDIS_USERNAME` | "" | +| `--cache-redis-password` | Redis password | `CACHE_REDIS_PASSWORD` | "" | +| `--cache-redis-db` | Redis database number (0-15) | `CACHE_REDIS_DB` | 0 | | `--cache-redis-use-tls` | Enable TLS for Redis connections | `CACHE_REDIS_USE_TLS` | false | -| `--cache-redis-pool-size` | Connection pool size | `CACHE_REDIS_POOL_SIZE` | 10 | +| `--cache-redis-pool-size` | Connection pool size | `CACHE_REDIS_POOL_SIZE` | 10 | **Note:** If `--cache-redis-addrs` is not provided, ncps runs in single-instance mode using local locks. @@ -267,7 +266,7 @@ Lock timing and retry configuration for distributed locking. | Option | Description | Environment Variable | Default | | --- | --- | --- | --- | -| `--cache-lock-retry-max-attempts` | Maximum lock retry attempts | `CACHE_LOCK_RETRY_MAX_ATTEMPTS` | 3 | +| `--cache-lock-retry-max-attempts` | Maximum lock retry attempts | `CACHE_LOCK_RETRY_MAX_ATTEMPTS` | 3 | | `--cache-lock-retry-initial-delay` | Initial retry delay | `CACHE_LOCK_RETRY_INITIAL_DELAY` | `100ms` | | `--cache-lock-retry-max-delay` | Maximum retry delay (backoff cap) | `CACHE_LOCK_RETRY_MAX_DELAY` | `2s` | | `--cache-lock-retry-jitter` | Enable jitter in retry delays | `CACHE_LOCK_RETRY_JITTER` | `true` | @@ -295,27 +294,27 @@ Configure anonymous usage statistics reporting to help improve ncps. **What is collected:** -- **Resource attributes**: - - Database backend type: `sqlite`, `postgres`, or `mysql` - - Lock mechanism type: `local`, `redis`, or `postgres` - - Cluster UUID (randomly generated identifier) -- **Metrics** (hourly): Total cache size, upstream count, upstream health -- **Logs**: Startup events, panic/crash events with stack traces +* **Resource attributes**: + * Database backend type: `sqlite`, `postgres`, or `mysql` + * Lock mechanism type: `local`, `redis`, or `postgres` + * Cluster UUID (randomly generated identifier) +* **Metrics** (hourly): Total cache size, upstream count, upstream health +* **Logs**: Startup events, panic/crash events with stack traces **What is NOT collected:** -- No personal information (usernames, emails, PII) -- No network information (IP addresses, hostnames) -- No cache contents (store paths, packages) -- No configuration secrets (passwords, keys) -- No request logs (HTTP requests, clients) +* No personal information (usernames, emails, PII) +* No network information (IP addresses, hostnames) +* No cache contents (store paths, packages) +* No configuration secrets (passwords, keys) +* No request logs (HTTP requests, clients) **Privacy:** -- Fully anonymous and privacy-focused -- Data sent to `otlp.ncps.dev:443` via HTTPS -- Helps maintainers understand usage patterns and prioritize development -- Easy opt-out with `--analytics-reporting-enabled=false` +* Fully anonymous and privacy-focused +* Data sent to `otlp.ncps.dev:443` via HTTPS +* Helps maintainers understand usage patterns and prioritize development +* Easy opt-out with `--analytics-reporting-enabled=false` **Enable (default):** @@ -360,7 +359,7 @@ Metrics available at `http://your-ncps:8501/metrics`. | Option | Description | Environment Variable | Default | | --- | --- | --- | --- | | `--otel-enabled` | Enable OpenTelemetry (logs, metrics, tracing) | `OTEL_ENABLED` | `false` | -| `--otel-grpc-url` | gRPC collector endpoint (omit for stdout) | `OTEL_GRPC_URL` | - | +| `--otel-grpc-url` | gRPC collector endpoint (omit for stdout) | `OTEL_GRPC_URL` | \- | **Example:** @@ -446,15 +445,15 @@ otel: **Environment variable expansion:** -- Use `${VAR_NAME}` syntax in configuration files -- Variables are expanded when the config is loaded +* Use `${VAR_NAME}` syntax in configuration files +* Variables are expanded when the config is loaded See [config.example.yaml](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) for a complete example. ## Related Documentation -- Storage - Storage backend details -- Database - Database backend details -- Observability - Monitoring and logging -- High Availability - HA configuration -- Distributed Locking - Lock tuning +* Storage - Storage backend details +* Database - Database backend details +* Observability - Monitoring and logging +* High Availability - HA configuration +* Distributed Locking - Lock tuning \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Storage.md b/docs/docs/User Guide/Configuration/Storage.md index 672087b9..7dfff6f8 100644 --- a/docs/docs/User Guide/Configuration/Storage.md +++ b/docs/docs/User Guide/Configuration/Storage.md @@ -1,5 +1,4 @@ -# Storage - +# Storage ## Storage Configuration Configure ncps storage backends: local filesystem or S3-compatible storage. @@ -8,20 +7,20 @@ Configure ncps storage backends: local filesystem or S3-compatible storage. ncps supports two storage backends for storing NAR files and other cache data: -- **Local Filesystem**: Traditional file-based storage -- **S3-Compatible**: AWS S3, MinIO, and other S3-compatible services +* **Local Filesystem**: Traditional file-based storage +* **S3-Compatible**: AWS S3, MinIO, and other S3-compatible services **Note:** You must choose exactly ONE storage backend. You cannot use both simultaneously. ## Next Steps -1. Database - Configure database backend -1. Reference - All storage options -1. High Availability - S3 for HA deployments -1. Operations - Monitoring and maintenance +1. Database - Configure database backend +2. Reference - All storage options +3. High Availability - S3 for HA deployments +4. Operations - Monitoring and maintenance ## Related Documentation -- Reference - All configuration options -- Installation - Installation-specific storage setup -- S3 Storage Implementation - S3 implementation details +* Reference - All configuration options +* Installation - Installation-specific storage setup +* S3 Storage Implementation - S3 implementation details \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Storage/Local Filesystem Storage.md b/docs/docs/User Guide/Configuration/Storage/Local Filesystem Storage.md index d19bddea..c0fa2dd9 100644 --- a/docs/docs/User Guide/Configuration/Storage/Local Filesystem Storage.md +++ b/docs/docs/User Guide/Configuration/Storage/Local Filesystem Storage.md @@ -1,11 +1,10 @@ -# Local Filesystem Storage - +# Local Filesystem Storage ### When to Use -- **Single-instance deployments**: One ncps server -- **Simple setup**: No external dependencies -- **Low latency**: Direct disk I/O -- **Testing and development** +* **Single-instance deployments**: One ncps server +* **Simple setup**: No external dependencies +* **Low latency**: Direct disk I/O +* **Testing and development** ### Configuration @@ -42,9 +41,9 @@ Local storage creates the following structure: ### Requirements -- **Writable directory**: ncps user must have read/write access -- **Sufficient space**: Plan for cache growth (recommend 50GB-1TB) -- **Fast disk**: SSD recommended for better performance +* **Writable directory**: ncps user must have read/write access +* **Sufficient space**: Plan for cache growth (recommend 50GB-1TB) +* **Fast disk**: SSD recommended for better performance ### Permissions @@ -59,12 +58,12 @@ sudo chmod 0755 /var/lib/ncps **Pros:** -- Fast (local disk I/O) -- No network latency -- Simple to manage +* Fast (local disk I/O) +* No network latency +* Simple to manage **Cons:** -- Limited to single server's disk -- No built-in redundancy -- Not suitable for HA deployments +* Limited to single server's disk +* No built-in redundancy +* Not suitable for HA deployments \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Storage/Migration Between Storage Back.md b/docs/docs/User Guide/Configuration/Storage/Migration Between Storage Back.md index 3b5b54f9..f5a13270 100644 --- a/docs/docs/User Guide/Configuration/Storage/Migration Between Storage Back.md +++ b/docs/docs/User Guide/Configuration/Storage/Migration Between Storage Back.md @@ -1,5 +1,4 @@ -# Migration Between Storage Backends - +# Migration Between Storage Backends ### From Local to S3 ``` @@ -25,4 +24,4 @@ aws s3 sync s3://ncps-cache/config/ /var/lib/ncps/config/ # 2. Update ncps configuration to use local storage # 3. Restart ncps -``` +``` \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Storage/S3-Compatible Storage.md b/docs/docs/User Guide/Configuration/Storage/S3-Compatible Storage.md index 83932c2f..3447ea51 100644 --- a/docs/docs/User Guide/Configuration/Storage/S3-Compatible Storage.md +++ b/docs/docs/User Guide/Configuration/Storage/S3-Compatible Storage.md @@ -1,19 +1,18 @@ -# S3-Compatible Storage - +# S3-Compatible Storage ### When to Use -- **High availability deployments**: Multiple ncps instances -- **Cloud-native setups**: Leveraging cloud infrastructure -- **Scalability**: Need storage independent of server resources -- **Redundancy**: Built-in durability and replication +* **High availability deployments**: Multiple ncps instances +* **Cloud-native setups**: Leveraging cloud infrastructure +* **Scalability**: Need storage independent of server resources +* **Redundancy**: Built-in durability and replication ### Supported Providers -- AWS S3 -- MinIO (self-hosted) -- DigitalOcean Spaces -- Backblaze B2 -- Any S3-compatible service +* AWS S3 +* MinIO (self-hosted) +* DigitalOcean Spaces +* Backblaze B2 +* Any S3-compatible service ### Configuration @@ -80,18 +79,18 @@ cache: | Option | Required | Description | Default | | --- | --- | --- | --- | -| `bucket` | Yes | S3 bucket name | - | -| `endpoint` | Yes | S3 endpoint URL with scheme (e.g., `https://s3.amazonaws.com`) | - | +| `bucket` | Yes | S3 bucket name | \- | +| `endpoint` | Yes | S3 endpoint URL with scheme (e.g., `https://s3.amazonaws.com`) | \- | | `region` | Yes | AWS region or any value for MinIO | `us-east-1` | -| `access-key-id` | Yes | S3 access key ID | - | -| `secret-access-key` | Yes | S3 secret access key | - | -| `force-path-style` | No | Use path-style URLs (required for MinIO) | `false` | +| `access-key-id` | Yes | S3 access key ID | \- | +| `secret-access-key` | Yes | S3 secret access key | \- | +| `force-path-style` | No | Use path-style URLs (required for MinIO) | `false` | **Endpoint Scheme Requirement:** -- The endpoint **must** include a scheme (`https://` or `http://`) -- Examples: `https://s3.amazonaws.com`, `http://minio:9000` -- The scheme determines whether SSL/TLS is used +* The endpoint **must** include a scheme (`https://` or `http://`) +* Examples: `https://s3.amazonaws.com`, `http://minio:9000` +* The scheme determines whether SSL/TLS is used ### S3 Bucket Setup @@ -163,17 +162,17 @@ s3://ncps-cache/ **Pros:** -- Scalable (independent of server resources) -- Durable (built-in redundancy) -- Multi-instance support (required for HA) -- Geographic replication options +* Scalable (independent of server resources) +* Durable (built-in redundancy) +* Multi-instance support (required for HA) +* Geographic replication options **Cons:** -- Network latency overhead -- Potential costs (AWS S3) -- Requires S3 service setup -- More complex configuration +* Network latency overhead +* Potential costs (AWS S3) +* Requires S3 service setup +* More complex configuration ### Security Best Practices @@ -202,11 +201,11 @@ s3://ncps-cache/ **Encryption:** -- Enable server-side encryption (SSE-S3 or SSE-KMS) -- Use TLS for data in transit (`--cache-storage-s3-use-ssl=true`) +* Enable server-side encryption (SSE-S3 or SSE-KMS) +* Use TLS for data in transit (`--cache-storage-s3-use-ssl=true`) **Access Control:** -- Use least-privilege IAM policies -- Enable bucket versioning for recovery -- Consider bucket lifecycle policies for cost optimization +* Use least-privilege IAM policies +* Enable bucket versioning for recovery +* Consider bucket lifecycle policies for cost optimization \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Storage/Storage Comparison.md b/docs/docs/User Guide/Configuration/Storage/Storage Comparison.md index 26a0bd6d..7489324b 100644 --- a/docs/docs/User Guide/Configuration/Storage/Storage Comparison.md +++ b/docs/docs/User Guide/Configuration/Storage/Storage Comparison.md @@ -1,5 +1,4 @@ -# Storage Comparison - +# Storage Comparison | Feature | Local Storage | S3 Storage | | --- | --- | --- | | **Setup Complexity** | Simple | Moderate | @@ -9,4 +8,4 @@ | **High Availability** | ❌ Not supported | ✅ Required | | **Redundancy** | None (unless RAID/NFS) | Built-in | | **Cost** | Disk only | S3 storage + requests | -| **Best For** | Single-instance, dev/test | HA, production, cloud | +| **Best For** | Single-instance, dev/test | HA, production, cloud | \ No newline at end of file diff --git a/docs/docs/User Guide/Configuration/Storage/Troubleshooting.md b/docs/docs/User Guide/Configuration/Storage/Troubleshooting.md index 0db45573..17a5a61c 100644 --- a/docs/docs/User Guide/Configuration/Storage/Troubleshooting.md +++ b/docs/docs/User Guide/Configuration/Storage/Troubleshooting.md @@ -1,5 +1,4 @@ -# Troubleshooting - +# Troubleshooting ### Local Storage Issues **Permission Denied:** @@ -26,20 +25,20 @@ ncps serve --cache-max-size=50G --cache-lru-schedule="0 2 * * *" **Access Denied:** -- Verify credentials are correct -- Check IAM policy permissions -- Ensure bucket exists and is in correct region +* Verify credentials are correct +* Check IAM policy permissions +* Ensure bucket exists and is in correct region **Connection Timeout:** -- Check network connectivity to S3 endpoint -- Verify endpoint URL is correct -- Check firewall rules +* Check network connectivity to S3 endpoint +* Verify endpoint URL is correct +* Check firewall rules **Slow Performance:** -- Check network bandwidth -- Consider using S3 Transfer Acceleration (AWS) -- Verify region is geographically close +* Check network bandwidth +* Consider using S3 Transfer Acceleration (AWS) +* Verify region is geographically close -See the Troubleshooting for more help. +See the Troubleshooting for more help. \ No newline at end of file diff --git a/docs/docs/User Guide/Deployment.md b/docs/docs/User Guide/Deployment.md index 5fd95ce4..67216729 100644 --- a/docs/docs/User Guide/Deployment.md +++ b/docs/docs/User Guide/Deployment.md @@ -1,5 +1,4 @@ -# Deployment - +# Deployment ## Deployment Guide Choose the deployment strategy that best fits your requirements. @@ -14,18 +13,18 @@ One ncps server handling all cache requests. **Best for:** -- Development and testing -- Small to medium teams (1-100+ users) -- Single-location deployments -- Simpler operations +* Development and testing +* Small to medium teams (1-100+ users) +* Single-location deployments +* Simpler operations **Characteristics:** -- One server -- Local locks (no Redis) -- Local or S3 storage -- SQLite, PostgreSQL, or MySQL database -- Easier to set up and maintain +* One server +* Local locks (no Redis) +* Local or S3 storage +* SQLite, PostgreSQL, or MySQL database +* Easier to set up and maintain [Learn more →](Deployment/Single%20Instance.md) @@ -35,20 +34,20 @@ Multiple ncps instances for redundancy and scalability. **Best for:** -- Production environments -- Large teams (100+ users) -- Business-critical infrastructure -- Geographic distribution -- Zero-downtime requirements +* Production environments +* Large teams (100+ users) +* Business-critical infrastructure +* Geographic distribution +* Zero-downtime requirements **Characteristics:** -- 2+ servers -- Redis distributed locking -- S3 storage (required) -- PostgreSQL or MySQL database (required, NOT SQLite) -- Load balancer -- More complex setup +* 2+ servers +* Redis distributed locking +* S3 storage (required) +* PostgreSQL or MySQL database (required, NOT SQLite) +* Load balancer +* More complex setup [Learn more →](Deployment/High%20Availability.md) @@ -56,14 +55,14 @@ Multiple ncps instances for redundancy and scalability. | Aspect | Single-Instance | High Availability | | --- | --- | --- | -| **Servers** | 1 | 2+ | +| **Servers** | 1 | 2+ | | **Locking** | Local (in-process) | Redis distributed locks | | **Storage** | Local or S3 | S3 (required) | | **Database** | SQLite, PostgreSQL, or MySQL | PostgreSQL or MySQL (NOT SQLite) | | **Load Balancer** | Not needed | Required | | **Redundancy** | None | Full | | **Complexity** | Simple | Moderate | -| **Zero Downtime** | No | Yes | +| **Zero Downtime** | No | Yes | | **Scalability** | Limited to one server | Horizontal scaling | | **Cost** | Lower | Higher | @@ -82,9 +81,9 @@ Start ## Documentation -- [Single-Instance Deployment](Deployment/Single%20Instance.md) - Deploy one ncps server -- [High Availability Deployment](Deployment/High%20Availability.md) - Deploy multiple instances with HA -- Distributed Locking - Deep dive into Redis locking for HA +* [Single-Instance Deployment](Deployment/Single%20Instance.md) - Deploy one ncps server +* [High Availability Deployment](Deployment/High%20Availability.md) - Deploy multiple instances with HA +* Distributed Locking - Deep dive into Redis locking for HA ## Prerequisites by Mode @@ -92,45 +91,45 @@ Start **Minimum:** -- Server or VM (2+ CPU cores, 4GB+ RAM recommended) -- Storage (50GB-1TB depending on usage) -- Network connectivity to upstream caches +* Server or VM (2+ CPU cores, 4GB+ RAM recommended) +* Storage (50GB-1TB depending on usage) +* Network connectivity to upstream caches **Optional:** -- S3-compatible storage (for cloud-native or future HA) -- PostgreSQL/MySQL (for better performance than SQLite) +* S3-compatible storage (for cloud-native or future HA) +* PostgreSQL/MySQL (for better performance than SQLite) ### High Availability Prerequisites **Required:** -- 2+ servers (3+ recommended for better availability) -- Redis server (single instance or cluster) -- S3-compatible storage (AWS S3, MinIO, etc.) -- PostgreSQL or MySQL database -- Load balancer (nginx, HAProxy, cloud LB) +* 2+ servers (3+ recommended for better availability) +* Redis server (single instance or cluster) +* S3-compatible storage (AWS S3, MinIO, etc.) +* PostgreSQL or MySQL database +* Load balancer (nginx, HAProxy, cloud LB) **Optional:** -- Monitoring and alerting (Prometheus, Grafana) -- Centralized logging (ELK, Loki) +* Monitoring and alerting (Prometheus, Grafana) +* Centralized logging (ELK, Loki) ## Getting Started -1. **Choose deployment mode** based on your requirements -1. **Review prerequisites** for your chosen mode -1. **Follow installation guide**: - - Docker - - Docker Compose - - Kubernetes - - Helm Chart - - NixOS -1. **Configure** according to your mode: - - Single Instance - - High Availability -1. **Verify deployment** and test -1. **Set up monitoring** (recommended) +1. **Choose deployment mode** based on your requirements +2. **Review prerequisites** for your chosen mode +3. **Follow installation guide**: + * Docker + * Docker Compose + * Kubernetes + * Helm Chart + * NixOS +4. **Configure** according to your mode: + * Single Instance + * High Availability +5. **Verify deployment** and test +6. **Set up monitoring** (recommended) ## Migration Path @@ -138,10 +137,10 @@ Start Common migration path as your needs grow: -1. **Start**: Single instance with local storage and SQLite -1. **Scale up**: Move to PostgreSQL for better performance -1. **Cloud-ready**: Migrate to S3 storage -1. **High Availability**: Add Redis and additional instances +1. **Start**: Single instance with local storage and SQLite +2. **Scale up**: Move to PostgreSQL for better performance +3. **Cloud-ready**: Migrate to S3 storage +4. **High Availability**: Add Redis and additional instances Each step is incremental and can be done independently. @@ -190,13 +189,13 @@ Load Balancer ## Next Steps -1. [Choose and follow deployment guide](Deployment/Single%20Instance.md) -1. [Configure clients](Usage/Client%20Setup.md) to use your cache -1. [Set up monitoring](Operations/Monitoring.md) for production -1. [Review operations guides](Operations.md) for maintenance +1. [Choose and follow deployment guide](Deployment/Single%20Instance.md) +2. [Configure clients](Usage/Client%20Setup.md) to use your cache +3. [Set up monitoring](Operations/Monitoring.md) for production +4. [Review operations guides](Operations.md) for maintenance ## Related Documentation -- [Installation Guides](Installation.md) - Installation methods -- [Configuration Reference](Configuration/Reference.md) - All configuration options -- [Operations Guides](Operations.md) - Monitoring, troubleshooting, backups +* [Installation Guides](Installation.md) - Installation methods +* [Configuration Reference](Configuration/Reference.md) - All configuration options +* [Operations Guides](Operations.md) - Monitoring, troubleshooting, backups \ No newline at end of file diff --git a/docs/docs/User Guide/Deployment/Distributed Locking.md b/docs/docs/User Guide/Deployment/Distributed Locking.md index 84179052..1439a35a 100644 --- a/docs/docs/User Guide/Deployment/Distributed Locking.md +++ b/docs/docs/User Guide/Deployment/Distributed Locking.md @@ -1,26 +1,25 @@ -# Distributed Locking - +# Distributed Locking This document provides comprehensive guidance on using distributed locking in ncps for high-availability deployments. ## Overview ncps supports running multiple instances in a high-availability configuration using **Redis** or **PostgreSQL advisory locks** for distributed locking. This enables: -- **Zero-downtime deployments** - Update instances one at a time -- **Horizontal scaling** - Add instances to handle more traffic -- **Load distribution** - Spread requests across multiple servers -- **Geographic distribution** - Deploy instances closer to clients +* **Zero-downtime deployments** - Update instances one at a time +* **Horizontal scaling** - Add instances to handle more traffic +* **Load distribution** - Spread requests across multiple servers +* **Geographic distribution** - Deploy instances closer to clients ### Key Concepts -- **Download Deduplication**: When multiple instances request the same package, only one downloads it while others wait for the result -- **LRU Coordination**: Only one instance runs cache cleanup at a time to prevent conflicts -- **Retry with Backoff**: Failed lock acquisitions retry automatically with exponential backoff and jitter -- **Lock Expiry**: All locks have TTLs to prevent deadlocks from instance failures +* **Download Deduplication**: When multiple instances request the same package, only one downloads it while others wait for the result +* **LRU Coordination**: Only one instance runs cache cleanup at a time to prevent conflicts +* **Retry with Backoff**: Failed lock acquisitions retry automatically with exponential backoff and jitter +* **Lock Expiry**: All locks have TTLs to prevent deadlocks from instance failures -1. **Local Locks** (default) - In-memory locks using Go's `sync.Mutex`, suitable for single-instance deployments -1. **Redis** - Distributed locks using the Redlock algorithm, ideal for HA deployments with existing Redis infrastructure -1. **PostgreSQL Advisory Locks** - Distributed locks using PostgreSQL's native advisory lock feature +1. **Local Locks** (default) - In-memory locks using Go's `sync.Mutex`, suitable for single-instance deployments +2. **Redis** - Distributed locks using the Redlock algorithm, ideal for HA deployments with existing Redis infrastructure +3. **PostgreSQL Advisory Locks** - Distributed locks using PostgreSQL's native advisory lock feature ## Architecture @@ -40,9 +39,9 @@ ncps supports running multiple instances in a high-availability configuration us └─> SQLite Database ``` -- Uses Go's `sync.Mutex` and `sync.RWMutex` for coordination -- No external dependencies required -- Suitable for single-server deployments +* Uses Go's `sync.Mutex` and `sync.RWMutex` for coordination +* No external dependencies required +* Suitable for single-server deployments ### High-Availability Mode @@ -81,10 +80,10 @@ ncps supports running multiple instances in a high-availability configuration us └─────────┘ └───────────┘ ``` -- All instances share the same S3 storage and database -- Redis coordinates locks across instances -- Load balancer distributes traffic -- Instances can be added/removed dynamically +* All instances share the same S3 storage and database +* Redis coordinates locks across instances +* Load balancer distributes traffic +* Instances can be added/removed dynamically ### High-Availability Mode (Database Advisory Locks) @@ -122,11 +121,11 @@ ncps supports running multiple instances in a high-availability configuration us └─────────┘ ``` -- The shared database serves both as the metadata store AND the distributed lock coordinator -- Reduces infrastructure complexity (no Redis needed) -- Uses PostgreSQL's native advisory lock feature (`pg_advisory_lock`) -- All instances share the same S3 storage and database -- Load balancer distributes traffic +* The shared database serves both as the metadata store AND the distributed lock coordinator +* Reduces infrastructure complexity (no Redis needed) +* Uses PostgreSQL's native advisory lock feature (`pg_advisory_lock`) +* All instances share the same S3 storage and database +* Load balancer distributes traffic ## When to Use Distributed Locking @@ -134,41 +133,41 @@ ncps supports running multiple instances in a high-availability configuration us ✅ **Running Multiple Instances** -- Deploying behind a load balancer -- Need zero-downtime updates -- Require failover capability +* Deploying behind a load balancer +* Need zero-downtime updates +* Require failover capability ✅ **High Traffic Environments** -- Handling thousands of concurrent requests -- Need horizontal scaling -- Geographic distribution required +* Handling thousands of concurrent requests +* Need horizontal scaling +* Geographic distribution required ✅ **Production Deployments** -- Business-critical caching infrastructure -- SLA requirements for availability -- Need redundancy and fault tolerance +* Business-critical caching infrastructure +* SLA requirements for availability +* Need redundancy and fault tolerance ### Use Local Locking When: ✅ **Single Server Deployment** -- Running on a single machine -- No redundancy required -- Development/testing environments +* Running on a single machine +* No redundancy required +* Development/testing environments ✅ **Low Traffic Environments** -- Small teams or personal use -- Limited concurrent requests -- Resource-constrained environments +* Small teams or personal use +* Limited concurrent requests +* Resource-constrained environments ✅ **Simplified Operations** -- Want minimal infrastructure -- Distributed lock backend is not necessary -- Prefer embedded solutions (SQLite) +* Want minimal infrastructure +* Distributed lock backend is not necessary +* Prefer embedded solutions (SQLite) ## Configuration Guide @@ -176,16 +175,16 @@ ncps supports running multiple instances in a high-availability configuration us For high-availability mode, you need: -1. **Distributed Lock Backend** (one of the following): - - **Redis** (version 5.0 or later) - - **PostgreSQL** (version 9.1 or later) -1. **Shared Storage** (S3-compatible) - - AWS S3, MinIO, DigitalOcean Spaces, etc. - - All instances must access the same bucket -1. **Shared Database** (PostgreSQL or MySQL) - - PostgreSQL 12+ or MySQL 8.0+ recommended - - All instances must connect to the same database - - SQLite is NOT supported in HA mode +1. **Distributed Lock Backend** (one of the following): + * **Redis** (version 5.0 or later) + * **PostgreSQL** (version 9.1 or later) +2. **Shared Storage** (S3-compatible) + * AWS S3, MinIO, DigitalOcean Spaces, etc. + * All instances must access the same bucket +3. **Shared Database** (PostgreSQL or MySQL) + * PostgreSQL 12+ or MySQL 8.0+ recommended + * All instances must connect to the same database + * SQLite is NOT supported in HA mode ### Basic Configuration @@ -226,9 +225,9 @@ The `--cache-lock-backend` flag determines which mechanism ncps uses to coordina | --- | --- | --- | | `--cache-lock-backend` | Lock backend: `local`, `redis`, or `postgres` | `local` | -- **local**: Uses in-memory locks. Only suitable for single-instance deployments. -- **redis**: Uses Redis (Redlock algorithm). Best for high-traffic, multi-instance deployments. -- **postgres**: Uses PostgreSQL advisory locks. Good balance of simplicity and HA. +* **local**: Uses in-memory locks. Only suitable for single-instance deployments. +* **redis**: Uses Redis (Redlock algorithm). Best for high-traffic, multi-instance deployments. +* **postgres**: Uses PostgreSQL advisory locks. Good balance of simplicity and HA. ### Redis Configuration Options @@ -237,11 +236,11 @@ The `--cache-lock-backend` flag determines which mechanism ncps uses to coordina | Option | Description | Default | | --- | --- | --- | | `--cache-redis-addrs` | Comma-separated Redis addresses | (none - local mode) | -| `--cache-redis-username` | Username for Redis ACL | "" | -| `--cache-redis-password` | Password for authentication | "" | -| `--cache-redis-db` | Database number (0-15) | 0 | +| `--cache-redis-username` | Username for Redis ACL | "" | +| `--cache-redis-password` | Password for authentication | "" | +| `--cache-redis-db` | Database number (0-15) | 0 | | `--cache-redis-use-tls` | Enable TLS connections | false | -| `--cache-redis-pool-size` | Connection pool size | 10 | +| `--cache-redis-pool-size` | Connection pool size | 10 | #### Redis Lock Settings @@ -253,16 +252,16 @@ The `--cache-lock-backend` flag determines which mechanism ncps uses to coordina | Option | Description | Default | | --- | --- | --- | -| `--cache-lock-download-ttl` | Download lock timeout | 5m | +| `--cache-lock-download-ttl` | Download lock timeout | 5m | | `--cache-lock-lru-ttl` | LRU lock timeout | 30m | #### Retry Configuration | Option | Description | Default | | --- | --- | --- | -| `--cache-lock-retry-max-attempts` | Maximum retry attempts | 3 | +| `--cache-lock-retry-max-attempts` | Maximum retry attempts | 3 | | `--cache-lock-retry-initial-delay` | Initial retry delay | 100ms | -| `--cache-lock-retry-max-delay` | Maximum backoff delay | 2s | +| `--cache-lock-retry-max-delay` | Maximum backoff delay | 2s | | `--cache-lock-retry-jitter` | Enable jitter in retries | true | ### Advanced Configuration @@ -295,23 +294,23 @@ The `--cache-lock-backend` flag determines which mechanism ncps uses to coordina Advisory locks provide a distributed locking alternative for deployments that: -- Already use PostgreSQL as the primary database -- Want to minimize infrastructure dependencies (no Redis needed) -- Prefer a single database for both data and coordination +* Already use PostgreSQL as the primary database +* Want to minimize infrastructure dependencies (no Redis needed) +* Prefer a single database for both data and coordination #### Advisory Lock Prerequisites > [!IMPORTANT] > Database advisory locks require PostgreSQL 9.1+. SQLite and MySQL do not support advisory locks in ncps. If you use MySQL as your database, you must use Redis for distributed locking. -1. **Shared Database** (PostgreSQL) - - Version 9.1 or later (12+ recommended) - - Uses native advisory lock functions - - Must be shared across all ncps instances - - Requires no special configuration or extensions -1. **Shared Storage** (S3-compatible) - - Same requirement as Redis mode - - All instances must access the same bucket +1. **Shared Database** (PostgreSQL) + * Version 9.1 or later (12+ recommended) + * Uses native advisory lock functions + * Must be shared across all ncps instances + * Requires no special configuration or extensions +2. **Shared Storage** (S3-compatible) + * Same requirement as Redis mode + * All instances must access the same bucket #### Advisory Lock Configuration (CLI) @@ -360,11 +359,11 @@ These settings apply to both Redis and PostgreSQL backends: | Option | Description | Default | | --- | --- | --- | -| `--cache-lock-download-ttl` | TTL for download locks | 5m | +| `--cache-lock-download-ttl` | TTL for download locks | 5m | | `--cache-lock-lru-ttl` | TTL for LRU cleanup lock | 30m | -| `--cache-lock-retry-max-attempts` | Maximum retry attempts | 3 | +| `--cache-lock-retry-max-attempts` | Maximum retry attempts | 3 | | `--cache-lock-retry-initial-delay` | Initial retry delay | 100ms | -| `--cache-lock-retry-max-delay` | Maximum retry delay (exponential backoff cap) | 2s | +| `--cache-lock-retry-max-delay` | Maximum retry delay (exponential backoff cap) | 2s | | `--cache-lock-retry-jitter` | Enable random jitter in retries | `true` | #### How Advisory Locks Work @@ -387,10 +386,10 @@ SELECT pg_advisory_unlock_shared(key_hash); -- Release shared (read) lock **Key Features:** -- Locks are identified by 64-bit integers (ncps hashes string keys to int64) -- Automatically released when connection closes (prevents deadlocks) -- Native database feature - no configuration or extensions needed -- Same connection must be used for lock() and unlock() +* Locks are identified by 64-bit integers (ncps hashes string keys to int64) +* Automatically released when connection closes (prevents deadlocks) +* Native database feature - no configuration or extensions needed +* Same connection must be used for lock() and unlock() #### Connection Management & Scalability @@ -399,26 +398,26 @@ SELECT pg_advisory_unlock_shared(key_hash); -- Release shared (read) lock PostgreSQL advisory lock implementations in ncps use a **dedicated connection model**: -1. When `Lock(key)` is called, a dedicated connection is pulled from the pool (or created). -1. The lock is acquired on that connection. -1. The connection is **held open** and removed from the pool until `Unlock(key)` is called. +1. When `Lock(key)` is called, a dedicated connection is pulled from the pool (or created). +2. The lock is acquired on that connection. +3. The connection is **held open** and removed from the pool until `Unlock(key)` is called. **Implication:** If your database has `max_connections = 100` and you try to acquire 101 concurrent locks across your cluster, the 101st attempt will fail (and eventually trigger the circuit breaker). **Recommendation:** -- Carefully monitor `pg_stat_activity` or equivalent. -- Ensure your database's `max_connections` is comfortably higher than `(num_instances * max_concurrent_downloads) + (num_instances * pool_size)`. -- If you need thousands of concurrent locks, **use Redis**. +* Carefully monitor `pg_stat_activity` or equivalent. +* Ensure your database's `max_connections` is comfortably higher than `(num_instances * max_concurrent_downloads) + (num_instances * pool_size)`. +* If you need thousands of concurrent locks, **use Redis**. > [!CAUTION] > **Risk of Deadlock with Low Connection Pool Limits** > > When using PostgreSQL advisory locks, a single request that requires a download can consume up to **3 concurrent database connections**: > -> 1. One connection to hold the **shared cache lock** for the duration of the request. -> 1. One connection to hold the **exclusive download lock** while the asset is being pulled. -> 1. One connection for the **database transaction** to store the metadata once the download completes. +> 1. One connection to hold the **shared cache lock** for the duration of the request. +> 2. One connection to hold the **exclusive download lock** while the asset is being pulled. +> 3. One connection for the **database transaction** to store the metadata once the download completes. > > If your connection pool (`--cache-database-pool-max-open-conns`) is too small (e.g., 10), as few as 4-5 concurrent requests can completely exhaust the pool, causing a deadlock where all requests are waiting for a connection to start a transaction while holding locks on other connections. @@ -436,56 +435,56 @@ PostgreSQL advisory lock implementations in ncps use a **dedicated connection mo **Use Redis when:** -- ✅ You already have Redis infrastructure -- ✅ Need the highest performance (Redis is optimized for in-memory operations) -- ✅ Need true read-write lock semantics with high read concurrency -- ✅ Want to use Redis for other purposes (caching, pub/sub) -- ✅ High-traffic deployments with thousands of concurrent requests +* ✅ You already have Redis infrastructure +* ✅ Need the highest performance (Redis is optimized for in-memory operations) +* ✅ Need true read-write lock semantics with high read concurrency +* ✅ Want to use Redis for other purposes (caching, pub/sub) +* ✅ High-traffic deployments with thousands of concurrent requests **Use PostgreSQL Advisory Locks when:** -- ✅ You already use PostgreSQL as the database -- ✅ Want to minimize infrastructure (one less service to manage) -- ✅ Prefer keeping everything in the database -- ✅ Need true shared read locks for concurrent cache access -- ✅ Lock contention is moderate (database locks are fast but not as fast as Redis) -- ✅ Want automatic cleanup when instances crash (connection closes) +* ✅ You already use PostgreSQL as the database +* ✅ Want to minimize infrastructure (one less service to manage) +* ✅ Prefer keeping everything in the database +* ✅ Need true shared read locks for concurrent cache access +* ✅ Lock contention is moderate (database locks are fast but not as fast as Redis) +* ✅ Want automatic cleanup when instances crash (connection closes) **Use Local Locks when:** -- ✅ Running single instance only -- ✅ Development/testing environment -- ✅ No HA requirements +* ✅ Running single instance only +* ✅ Development/testing environment +* ✅ No HA requirements #### Performance Considerations PostgreSQL advisory locks are fast, but not as fast as Redis: -- **Redis** Lock acquisition: ~0.5-2ms -- **PostgreSQL** Lock acquisition: ~1-5ms (depends on database load) +* **Redis** Lock acquisition: ~0.5-2ms +* **PostgreSQL** Lock acquisition: ~1-5ms (depends on database load) For most deployments, PostgreSQL advisory locks provide excellent performance. Redis may be preferred for: -- Very high lock contention (hundreds of locks/second) -- Extremely latency-sensitive workloads -- Geographic distribution with distant database +* Very high lock contention (hundreds of locks/second) +* Extremely latency-sensitive workloads +* Geographic distribution with distant database ### Recommended Stack For best performance, reliability, and scalability in production: -1. **Distributed Locking:** **Redis** - - Why: Decouples locking load from your primary database. Handles thousands of concurrent locks with minimal connection overhead. -1. **Metadata Database:** **PostgreSQL** - - Why: Robust, transactional reliability for cache metadata. -1. **Storage:** **S3 (AWS or MinIO)** - - Why: Infinite scalability for binary artifacts. +1. **Distributed Locking:** **Redis** + * Why: Decouples locking load from your primary database. Handles thousands of concurrent locks with minimal connection overhead. +2. **Metadata Database:** **PostgreSQL** + * Why: Robust, transactional reliability for cache metadata. +3. **Storage:** **S3 (AWS or MinIO)** + * Why: Infinite scalability for binary artifacts. **Use Database Advisory Locks only if:** -- You cannot maintain a functional Redis setup. -- Your concurrency is low (< 100 concurrent downloads cluster-wide). -- You want strict "single dependency" simplicity over scalability. +* You cannot maintain a functional Redis setup. +* Your concurrency is low (< 100 concurrent downloads cluster-wide). +* You want strict "single dependency" simplicity over scalability. ## How It Works @@ -493,7 +492,7 @@ For best performance, reliability, and scalability in production: ncps uses two types of distributed locks: -#### 1. Download Locks (Exclusive) +#### 1\. Download Locks (Exclusive) **Purpose:** Prevent duplicate downloads of the same package @@ -504,14 +503,14 @@ ncps uses two types of distributed locks: **Behavior:** -- When instance A starts downloading a package, it acquires the lock -- Instance B requesting the same package will retry acquiring the lock -- Once instance A completes the download, it releases the lock -- Instance B then reads the package from shared storage (no download needed) +* When instance A starts downloading a package, it acquires the lock +* Instance B requesting the same package will retry acquiring the lock +* Once instance A completes the download, it releases the lock +* Instance B then reads the package from shared storage (no download needed) **TTL:** 5 minutes (configurable via `--cache-lock-download-ttl`) -#### 2. LRU Lock (Exclusive) +#### 2\. LRU Lock (Exclusive) **Purpose:** Coordinate cache cleanup across instances @@ -519,10 +518,10 @@ ncps uses two types of distributed locks: **Behavior:** -- Uses `TryLock()` - non-blocking acquisition -- If locked, the instance skips LRU and tries again next cycle -- Only one instance runs LRU cleanup at a time -- Prevents concurrent deletions that could corrupt the cache +* Uses `TryLock()` - non-blocking acquisition +* If locked, the instance skips LRU and tries again next cycle +* Only one instance runs LRU cleanup at a time +* Prevents concurrent deletions that could corrupt the cache **TTL:** 30 minutes (configurable via `--cache-lock-lru-ttl`) @@ -530,9 +529,9 @@ ncps uses two types of distributed locks: ncps uses the [Redlock algorithm](https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/) via [go-redsync](https://github.com/go-redsync/redsync): -1. **Acquire**: Try to SET with NX (only if not exists) and PX (expiry time) -1. **Release**: Delete the key when operation completes -1. **Expire**: Lock auto-expires after TTL if instance crashes (important for long-running downloads) +1. **Acquire**: Try to SET with NX (only if not exists) and PX (expiry time) +2. **Release**: Delete the key when operation completes +3. **Expire**: Lock auto-expires after TTL if instance crashes (important for long-running downloads) **Note**: Lock extension is not currently implemented. The TTL should be set long enough to accommodate the longest expected download operation. @@ -556,9 +555,9 @@ actual_delay = delay + random(0, delay * jitter_factor) **Why Jitter?** -- Prevents thundering herd when lock is released -- Distributes retry attempts across time -- Improves fairness in lock acquisition +* Prevents thundering herd when lock is released +* Distributes retry attempts across time +* Improves fairness in lock acquisition ### Cache Access Protection @@ -592,19 +591,19 @@ Read operations (GetNar, GetNarInfo) acquire read locks to prevent the LRU from The following OpenTelemetry metrics will be available for monitoring lock operations: -- `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisition attempts - - `type`: "download" or "lru" - - `result`: "success" or "failure" - - `mode`: "local" or "distributed" -- `ncps_lock_hold_duration_seconds{type,mode}` - Time locks are held - - Histogram of lock hold times - - Helps identify slow operations -- `ncps_lock_failures_total{type,reason,mode}` - Lock failures - - `reason`: "timeout", "redis_error", "circuit_breaker" - - Indicates infrastructure issues -- `ncps_lock_retry_attempts_total{type}` - Retry attempts before success/failure - - Shows lock contention levels - - High values indicate scaling needs +* `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisition attempts + * `type`: "download" or "lru" + * `result`: "success" or "failure" + * `mode`: "local" or "distributed" +* `ncps_lock_hold_duration_seconds{type,mode}` - Time locks are held + * Histogram of lock hold times + * Helps identify slow operations +* `ncps_lock_failures_total{type,reason,mode}` - Lock failures + * `reason`: "timeout", "redis\_error", "circuit\_breaker" + * Indicates infrastructure issues +* `ncps_lock_retry_attempts_total{type}` - Retry attempts before success/failure + * Shows lock contention levels + * High values indicate scaling needs ### Logging @@ -623,10 +622,10 @@ ncps logs lock operations with structured fields: **Important log messages:** -- `acquired download lock` - Successfully acquired lock for download -- `failed to acquire lock` - Lock acquisition failed after retries -- `another instance is running LRU` - LRU skipped (another instance running) -- `circuit breaker open: Redis is unavailable` - Redis connectivity issues +* `acquired download lock` - Successfully acquired lock for download +* `failed to acquire lock` - Lock acquisition failed after retries +* `another instance is running LRU` - LRU skipped (another instance running) +* `circuit breaker open: Redis is unavailable` - Redis connectivity issues ### Health Checks @@ -668,10 +667,10 @@ grep "acquired download lock" /var/log/ncps.log | wc -l **Common Causes:** -1. **Redis not configured** - Verify `--cache-redis-addrs` is set -1. **Network issues** - Check firewall rules, DNS resolution -1. **Redis authentication** - Verify username/password if ACL is enabled -1. **Different key prefixes** - Ensure all instances use the same `--cache-lock-redis-key-prefix` +1. **Redis not configured** - Verify `--cache-redis-addrs` is set +2. **Network issues** - Check firewall rules, DNS resolution +3. **Redis authentication** - Verify username/password if ACL is enabled +4. **Different key prefixes** - Ensure all instances use the same `--cache-lock-redis-key-prefix` **Solution:** @@ -703,20 +702,18 @@ redis-cli --scan --pattern "ncps:lock:download:*" | wc -l **Solutions:** -1. **Increase retry settings:** - - ``` - --cache-lock-retry-max-attempts=5 \ - --cache-lock-retry-max-delay=5s - ``` - -1. **Scale down instances** (if too many instances competing) +1. **Increase retry settings:** -1. **Increase lock TTL** for long-running operations: + ``` + --cache-lock-retry-max-attempts=5 \ + --cache-lock-retry-max-delay=5s + ``` +2. **Scale down instances** (if too many instances competing) +3. **Increase lock TTL** for long-running operations: - ``` - --cache-lock-download-ttl=10m - ``` + ``` + --cache-lock-download-ttl=10m + ``` ### LRU Not Running @@ -737,8 +734,8 @@ redis-cli GET "ncps:lock:lru" **Common Causes:** -1. **LRU lock stuck** - Lock held by crashed instance -1. **All instances skipping** - Each thinks another is running +1. **LRU lock stuck** - Lock held by crashed instance +2. **All instances skipping** - Each thinks another is running **Solution:** @@ -769,23 +766,21 @@ nc -zv redis-host 6379 **Solutions:** -1. **Verify Redis is running:** +1. **Verify Redis is running:** - ``` - systemctl start redis - ``` + ``` + systemctl start redis + ``` +2. **Check firewall rules:** -1. **Check firewall rules:** + ``` + sudo iptables -L | grep 6379 + ``` +3. **Verify TLS configuration** if using `--cache-redis-use-tls`: - ``` - sudo iptables -L | grep 6379 - ``` - -1. **Verify TLS configuration** if using `--cache-redis-use-tls`: - - ``` - openssl s_client -connect redis-host:6380 - ``` + ``` + openssl s_client -connect redis-host:6380 + ``` ## Performance Tuning @@ -793,43 +788,43 @@ nc -zv redis-host 6379 **Download Lock TTL** (`--cache-lock-download-ttl`): -- **Default:** 5 minutes -- **Increase if:** Large packages take longer to download -- **Decrease if:** Most downloads complete quickly (reduces stuck lock impact) +* **Default:** 5 minutes +* **Increase if:** Large packages take longer to download +* **Decrease if:** Most downloads complete quickly (reduces stuck lock impact) **LRU Lock TTL** (`--cache-lock-lru-ttl`): -- **Default:** 30 minutes -- **Increase if:** LRU cleanup takes longer (very large caches) -- **Decrease if:** Want faster failover if instance crashes during LRU +* **Default:** 30 minutes +* **Increase if:** LRU cleanup takes longer (very large caches) +* **Decrease if:** Want faster failover if instance crashes during LRU ### Retry Configuration **Max Attempts** (`--cache-lock-retry-max-attempts`): -- **Default:** 3 -- **Increase if:** High lock contention (many instances) -- **Decrease if:** Want faster failure feedback +* **Default:** 3 +* **Increase if:** High lock contention (many instances) +* **Decrease if:** Want faster failure feedback **Initial Delay** (`--cache-lock-retry-initial-delay`): -- **Default:** 100ms -- **Increase if:** Redis is slow or distant -- **Decrease if:** Redis is fast and local +* **Default:** 100ms +* **Increase if:** Redis is slow or distant +* **Decrease if:** Redis is fast and local **Max Delay** (`--cache-lock-retry-max-delay`): -- **Default:** 2s -- **Increase if:** Locks are held for long periods -- **Decrease if:** Want faster failure +* **Default:** 2s +* **Increase if:** Locks are held for long periods +* **Decrease if:** Want faster failure ### Redis Pool Size **Pool Size** (`--cache-redis-pool-size`): -- **Default:** 10 connections per instance -- **Increase if:** High concurrent download requests -- **Decrease if:** Running many instances (to reduce Redis load) +* **Default:** 10 connections per instance +* **Increase if:** High concurrent download requests +* **Decrease if:** Running many instances (to reduce Redis load) **Formula:** `total_connections = instances * pool_size` @@ -839,56 +834,56 @@ nc -zv redis-host 6379 ### Deployment -1. **Start Redis First** - - Ensure Redis is healthy before starting ncps instances - - Use health checks in orchestration (Kubernetes, Docker Compose) -1. **Gradual Rollout** - - Update instances one at a time - - Verify each instance is healthy before updating the next - - Monitor lock metrics during rollout -1. **Load Balancer Configuration** - - Use health check endpoint: `GET /pubkey` - - Configure session affinity if needed (not required) - - Set reasonable timeouts (downloads can be large) -1. **Shared Storage** - - Ensure all instances have identical S3 configuration - - Use IAM roles or credentials with proper permissions - - Enable S3 server-side encryption for security -1. **Database** - - Use connection pooling in PostgreSQL - - Configure appropriate timeouts - - Monitor connection counts +1. **Start Redis First** + * Ensure Redis is healthy before starting ncps instances + * Use health checks in orchestration (Kubernetes, Docker Compose) +2. **Gradual Rollout** + * Update instances one at a time + * Verify each instance is healthy before updating the next + * Monitor lock metrics during rollout +3. **Load Balancer Configuration** + * Use health check endpoint: `GET /pubkey` + * Configure session affinity if needed (not required) + * Set reasonable timeouts (downloads can be large) +4. **Shared Storage** + * Ensure all instances have identical S3 configuration + * Use IAM roles or credentials with proper permissions + * Enable S3 server-side encryption for security +5. **Database** + * Use connection pooling in PostgreSQL + * Configure appropriate timeouts + * Monitor connection counts ### Monitoring -1. **Key Metrics to Watch** - - Lock acquisition latency - - Retry attempt rates - - Redis connectivity - - Cache hit rates -1. **Alerting** - - Alert on high lock failures - - Alert on Redis unavailability - - Alert on excessive retry attempts -1. **Logging** - - Centralize logs (ELK, Loki, CloudWatch) - - Include structured fields for filtering - - Set appropriate log levels +1. **Key Metrics to Watch** + * Lock acquisition latency + * Retry attempt rates + * Redis connectivity + * Cache hit rates +2. **Alerting** + * Alert on high lock failures + * Alert on Redis unavailability + * Alert on excessive retry attempts +3. **Logging** + * Centralize logs (ELK, Loki, CloudWatch) + * Include structured fields for filtering + * Set appropriate log levels ### Operations -1. **Backup Strategy** - - Redis: Optional (locks are ephemeral) - - Database: Regular backups (contains metadata) - - S3: Enable versioning for disaster recovery -1. **Scaling** - - Add instances during high traffic - - Remove instances during maintenance - - Monitor for lock contention when scaling -1. **Maintenance** - - Update one instance at a time - - Redis can be restarted (locks will regenerate) - - Database migrations should be backward-compatible +1. **Backup Strategy** + * Redis: Optional (locks are ephemeral) + * Database: Regular backups (contains metadata) + * S3: Enable versioning for disaster recovery +2. **Scaling** + * Add instances during high traffic + * Remove instances during maintenance + * Monitor for lock contention when scaling +3. **Maintenance** + * Update one instance at a time + * Redis can be restarted (locks will regenerate) + * Database migrations should be backward-compatible ## Migration Guide @@ -896,65 +891,59 @@ nc -zv redis-host 6379 **Prerequisites:** -1. ✅ Set up PostgreSQL database -1. ✅ Migrate from SQLite (if applicable) -1. ✅ Set up S3-compatible storage -1. ✅ Deploy Redis server +1. ✅ Set up PostgreSQL database +2. ✅ Migrate from SQLite (if applicable) +3. ✅ Set up S3-compatible storage +4. ✅ Deploy Redis server **Migration Steps:** -1. **Migrate to S3 Storage:** - - ``` - # Sync local storage to S3 - aws s3 sync /var/lib/ncps/storage s3://ncps-cache/ - ``` +1. **Migrate to S3 Storage:** -1. **Migrate Database:** + ``` + # Sync local storage to S3 + aws s3 sync /var/lib/ncps/storage s3://ncps-cache/ + ``` +2. **Migrate Database:** - ``` - # Export SQLite data - sqlite3 ncps.db .dump > backup.sql + ``` + # Export SQLite data + sqlite3 ncps.db .dump > backup.sql - # Import to PostgreSQL (after schema conversion) - psql ncps < converted.sql - ``` + # Import to PostgreSQL (after schema conversion) + psql ncps < converted.sql + ``` +3. **Configure First Instance:** -1. **Configure First Instance:** + ``` + ncps serve \ + --cache-database-url=postgresql://... \ + --cache-storage-s3-bucket=ncps-cache \ + --cache-redis-addrs=redis:6379 + ``` +4. **Verify Functionality:** - ``` - ncps serve \ - --cache-database-url=postgresql://... \ - --cache-storage-s3-bucket=ncps-cache \ - --cache-redis-addrs=redis:6379 - ``` + * Test package downloads + * Check Redis for lock keys + * Verify cache hits +5. **Add Additional Instances:** -1. **Verify Functionality:** - - - Test package downloads - - Check Redis for lock keys - - Verify cache hits - -1. **Add Additional Instances:** - - - Use identical configuration - - Point to same Redis, S3, and database - - Add to load balancer + * Use identical configuration + * Point to same Redis, S3, and database + * Add to load balancer ### Rollback Plan If issues occur: -1. **Stop new instances** (keep first instance) - -1. **Continue using first instance** with Redis - -1. **Or temporarily disable Redis:** +1. **Stop new instances** (keep first instance) +2. **Continue using first instance** with Redis +3. **Or temporarily disable Redis:** - ``` - # Remove --cache-redis-addrs flag - # Falls back to local locks - ``` + ``` + # Remove --cache-redis-addrs flag + # Falls back to local locks + ``` **Note:** Rollback from S3 to local storage requires data sync: @@ -962,20 +951,20 @@ If issues occur: aws s3 sync s3://ncps-cache/ /var/lib/ncps/storage ``` -______________________________________________________________________ +--- ## Additional Resources -- **Redis Official Documentation:** [https://redis.io/docs/](https://redis.io/docs/) -- **Redlock Algorithm:** [https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/](https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/) -- **go-redsync Library:** [https://github.com/go-redsync/redsync](https://github.com/go-redsync/redsync) -- **ncps Configuration Reference:** See [`config.example.yaml`](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) -- **High Availability Best Practices:** AWS Well-Architected Framework +* **Redis Official Documentation:** [https://redis.io/docs/](https://redis.io/docs/) +* **Redlock Algorithm:** [https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/](https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/) +* **go-redsync Library:** [https://github.com/go-redsync/redsync](https://github.com/go-redsync/redsync) +* **ncps Configuration Reference:** See [`config.example.yaml`](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) +* **High Availability Best Practices:** AWS Well-Architected Framework ## Support For issues or questions: -- **GitHub Issues:** [https://github.com/kalbasit/ncps/issues](https://github.com/kalbasit/ncps/issues) -- **Discussions:** [https://github.com/kalbasit/ncps/discussions](https://github.com/kalbasit/ncps/discussions) -- **CONTRIBUTING.md:** Development and testing guide +* **GitHub Issues:** [https://github.com/kalbasit/ncps/issues](https://github.com/kalbasit/ncps/issues) +* **Discussions:** [https://github.com/kalbasit/ncps/discussions](https://github.com/kalbasit/ncps/discussions) +* **CONTRIBUTING.md:** Development and testing guide \ No newline at end of file diff --git a/docs/docs/User Guide/Deployment/High Availability.md b/docs/docs/User Guide/Deployment/High Availability.md index 80700613..477c84c5 100644 --- a/docs/docs/User Guide/Deployment/High Availability.md +++ b/docs/docs/User Guide/Deployment/High Availability.md @@ -1,5 +1,4 @@ -# High Availability - +# High Availability ## High Availability Deployment Deploy multiple ncps instances for zero-downtime operation, load distribution, and redundancy. @@ -8,11 +7,11 @@ Deploy multiple ncps instances for zero-downtime operation, load distribution, a Running multiple ncps instances provides: -- ✅ **Zero Downtime** - Instance failures don't interrupt service -- ✅ **Load Distribution** - Requests spread across multiple servers -- ✅ **Horizontal Scaling** - Add instances to handle more traffic -- ✅ **Geographic Distribution** - Deploy instances closer to clients -- ✅ **Rolling Updates** - Update instances one at a time without downtime +* ✅ **Zero Downtime** - Instance failures don't interrupt service +* ✅ **Load Distribution** - Requests spread across multiple servers +* ✅ **Horizontal Scaling** - Add instances to handle more traffic +* ✅ **Geographic Distribution** - Deploy instances closer to clients +* ✅ **Rolling Updates** - Update instances one at a time without downtime ## Architecture @@ -47,26 +46,26 @@ Running multiple ncps instances provides: ### Required Components -1. **Multiple ncps instances** (2+, recommended 3+) -1. **Distributed locking backend** - - **Redis server** (version 5.0+) - - **PostgreSQL advisory locks** (version 9.1+) -1. **S3-compatible storage** (shared across all instances) - - AWS S3, MinIO, DigitalOcean Spaces, etc. -1. **PostgreSQL or MySQL database** (shared across all instances) - - PostgreSQL 12+ or MySQL 8.0+ - - **SQLite is NOT supported for HA** - - **NOTE: MySQL is only supported for data storage, NOT for distributed locking. If using MySQL, you must use Redis for locking.** -1. **Load balancer** to distribute requests - - nginx, HAProxy, cloud load balancer, etc. +1. **Multiple ncps instances** (2+, recommended 3+) +2. **Distributed locking backend** + * **Redis server** (version 5.0+) + * **PostgreSQL advisory locks** (version 9.1+) +3. **S3-compatible storage** (shared across all instances) + * AWS S3, MinIO, DigitalOcean Spaces, etc. +4. **PostgreSQL or MySQL database** (shared across all instances) + * PostgreSQL 12+ or MySQL 8.0+ + * **SQLite is NOT supported for HA** + * **NOTE: MySQL is only supported for data storage, NOT for distributed locking. If using MySQL, you must use Redis for locking.** +5. **Load balancer** to distribute requests + * nginx, HAProxy, cloud load balancer, etc. ### Network Requirements -- All instances must reach Redis -- All instances must reach S3 storage -- All instances must reach shared database -- Load balancer must reach all instances -- Clients reach load balancer +* All instances must reach Redis +* All instances must reach S3 storage +* All instances must reach shared database +* Load balancer must reach all instances +* Clients reach load balancer ## Quick Start @@ -319,29 +318,29 @@ ncps uses Redis to coordinate multiple instances: When multiple instances request the same package: -1. Instance A acquires download lock for hash `abc123` -1. Instance B tries to download same package -1. Instance B cannot acquire lock (Instance A holds it) -1. Instance B retries with exponential backoff -1. Instance A completes download and releases lock -1. Instance B acquires lock, finds package in S3, serves it -1. Result: Only one download from upstream +1. Instance A acquires download lock for hash `abc123` +2. Instance B tries to download same package +3. Instance B cannot acquire lock (Instance A holds it) +4. Instance B retries with exponential backoff +5. Instance A completes download and releases lock +6. Instance B acquires lock, finds package in S3, serves it +7. Result: Only one download from upstream ### LRU Coordination Only one instance runs cache cleanup at a time: -1. Instances try to acquire global LRU lock -1. First instance to acquire lock runs LRU -1. Other instances skip LRU (lock held) -1. After cleanup, lock is released -1. Next scheduled LRU cycle, another instance may acquire lock +1. Instances try to acquire global LRU lock +2. First instance to acquire lock runs LRU +3. Other instances skip LRU (lock held) +4. After cleanup, lock is released +5. Next scheduled LRU cycle, another instance may acquire lock **Benefits:** -- Prevents concurrent deletions -- Avoids cache corruption -- Distributes LRU load +* Prevents concurrent deletions +* Avoids cache corruption +* Distributes LRU load See Distributed Locking for technical details and database advisory lock configuration (PostgreSQL). @@ -415,11 +414,11 @@ spec: ### Key Metrics -- **Instance health**: Up/down status -- **Lock acquisition rate**: Download and LRU locks -- **Lock contention**: Retry attempts -- **Redis connectivity**: Connection status -- **Cache hit rate**: Per-instance and aggregate +* **Instance health**: Up/down status +* **Lock acquisition rate**: Download and LRU locks +* **Lock contention**: Retry attempts +* **Redis connectivity**: Connection status +* **Cache hit rate**: Per-instance and aggregate ### Example Prometheus Queries @@ -462,9 +461,9 @@ grep "acquired download lock" /var/log/ncps.log **Solutions:** -1. Increase retry settings -1. Increase lock TTLs for long operations -1. Scale down instances if too many +1. Increase retry settings +2. Increase lock TTLs for long operations +3. Scale down instances if too many See Distributed Locking for detailed troubleshooting. @@ -472,21 +471,21 @@ See Distributed Locki ### Prerequisites -1. ✅ Set up PostgreSQL or MySQL database -1. ✅ Migrate from SQLite (if applicable) -1. ✅ Set up S3-compatible storage -1. ✅ Deploy Redis server +1. ✅ Set up PostgreSQL or MySQL database +2. ✅ Migrate from SQLite (if applicable) +3. ✅ Set up S3-compatible storage +4. ✅ Deploy Redis server ### Migration Steps -**1. Migrate to S3 Storage:** +**1\. Migrate to S3 Storage:** ``` # Sync local storage to S3 aws s3 sync /var/lib/ncps s3://ncps-cache/ ``` -**2. Migrate Database:** +**2\. Migrate Database:** ``` # Export SQLite data @@ -497,45 +496,45 @@ pgloader sqlite:///var/lib/ncps/db/db.sqlite \ postgresql://ncps:password@localhost:5432/ncps ``` -**3. Configure First Instance:** +**3\. Configure First Instance:** ```yaml # Update config.yaml to use S3 and PostgreSQL # Add Redis configuration ``` -**4. Verify Functionality:** +**4\. Verify Functionality:** -- Test package downloads -- Check Redis for lock keys -- Verify cache hits +* Test package downloads +* Check Redis for lock keys +* Verify cache hits -**5. Add Additional Instances:** +**5\. Add Additional Instances:** -- Use identical configuration -- Point to same Redis, S3, and database -- Add to load balancer +* Use identical configuration +* Point to same Redis, S3, and database +* Add to load balancer ## Best Practices -1. **Start Redis First** - Ensure Redis is healthy before starting ncps instances -1. **Use Health Checks** - Configure load balancer health checks -1. **Monitor Lock Metrics** - Watch for contention and failures -1. **Plan Capacity** - 3+ instances recommended for true HA -1. **Test Failover** - Regularly test instance failures -1. **Centralize Logs** - Use log aggregation for troubleshooting -1. **Set Up Alerts** - Alert on high lock failures, Redis unavailability +1. **Start Redis First** - Ensure Redis is healthy before starting ncps instances +2. **Use Health Checks** - Configure load balancer health checks +3. **Monitor Lock Metrics** - Watch for contention and failures +4. **Plan Capacity** - 3+ instances recommended for true HA +5. **Test Failover** - Regularly test instance failures +6. **Centralize Logs** - Use log aggregation for troubleshooting +7. **Set Up Alerts** - Alert on high lock failures, Redis unavailability ## Next Steps -1. Client Setup - Set up Nix clients -1. Distributed Locking - Understand locking in depth -1. Monitoring - Configure observability -1. Operations - Learn about backups, upgrades +1. Client Setup - Set up Nix clients +2. Distributed Locking - Understand locking in depth +3. Monitoring - Configure observability +4. Operations - Learn about backups, upgrades ## Related Documentation -- Distributed Locking - Deep dive into Redis locking -- Helm Chart - Simplified HA deployment -- Reference - All HA options -- Monitoring - HA-specific monitoring +* Distributed Locking - Deep dive into Redis locking +* Helm Chart - Simplified HA deployment +* Reference - All HA options +* Monitoring - HA-specific monitoring \ No newline at end of file diff --git a/docs/docs/User Guide/Deployment/Single Instance.md b/docs/docs/User Guide/Deployment/Single Instance.md index ee90875d..edaf7755 100644 --- a/docs/docs/User Guide/Deployment/Single Instance.md +++ b/docs/docs/User Guide/Deployment/Single Instance.md @@ -1,5 +1,4 @@ -# Single Instance - +# Single Instance ## Single-Instance Deployment Deploy ncps as a single server for simplified operations and maintenance. @@ -8,11 +7,11 @@ Deploy ncps as a single server for simplified operations and maintenance. Single-instance deployment is ideal for: -- **Development and testing environments** -- **Small to medium teams** (1-100+ users) -- **Single-location deployments** -- **Simpler operational requirements** -- **Cost-conscious deployments** +* **Development and testing environments** +* **Small to medium teams** (1-100+ users) +* **Single-location deployments** +* **Simpler operational requirements** +* **Cost-conscious deployments** ## Architecture @@ -42,15 +41,15 @@ Single-instance deployment is ideal for: **Pros:** -- Simple setup -- Fast (local I/O) -- No external dependencies +* Simple setup +* Fast (local I/O) +* No external dependencies **Cons:** -- Limited to server disk size -- No redundancy -- Cannot scale to HA +* Limited to server disk size +* No redundancy +* Cannot scale to HA **Configuration:** @@ -66,15 +65,15 @@ cache: **Pros:** -- Scalable storage -- Easy migration to HA later -- Built-in redundancy +* Scalable storage +* Easy migration to HA later +* Built-in redundancy **Cons:** -- Requires S3 service -- Slight latency overhead -- Additional cost (if using cloud S3) +* Requires S3 service +* Slight latency overhead +* Additional cost (if using cloud S3) **Configuration:** @@ -98,14 +97,14 @@ cache: **Pros:** -- No external service required -- Zero configuration -- Perfect for single instance +* No external service required +* Zero configuration +* Perfect for single instance **Cons:** -- Cannot be used for HA -- Single connection limit +* Cannot be used for HA +* Single connection limit **Configuration:** @@ -118,14 +117,14 @@ cache: **Pros:** -- Better performance under load -- Easier migration to HA later -- Better concurrent access +* Better performance under load +* Easier migration to HA later +* Better concurrent access **Cons:** -- Requires PostgreSQL service -- More complex setup +* Requires PostgreSQL service +* More complex setup **Configuration:** @@ -205,27 +204,27 @@ prometheus: ### Minimum -- **CPU**: 2 cores -- **RAM**: 4GB -- **Disk**: 50GB (for local storage) -- **Network**: 100Mbps +* **CPU**: 2 cores +* **RAM**: 4GB +* **Disk**: 50GB (for local storage) +* **Network**: 100Mbps ### Recommended -- **CPU**: 4+ cores -- **RAM**: 8GB+ -- **Disk**: 200GB-1TB (for local storage) -- **Network**: 1Gbps +* **CPU**: 4+ cores +* **RAM**: 8GB+ +* **Disk**: 200GB-1TB (for local storage) +* **Network**: 1Gbps ## Installation Methods Choose your preferred installation method: -- Docker - Quickest setup -- Docker Compose - Automated deployment -- Nixos - Native NixOS integration -- Kubernetes - For K8s environments -- Helm - Simplified K8s deployment +* Docker - Quickest setup +* Docker Compose - Automated deployment +* Nixos - Native NixOS integration +* Kubernetes - For K8s environments +* Helm - Simplified K8s deployment ## Deployment Checklist @@ -270,10 +269,10 @@ See Monitoring Single-instance deployments have these limitations: -- **No redundancy**: Server downtime = cache downtime -- **No load distribution**: One server handles all requests -- **No zero-downtime updates**: Updates require service restart -- **Limited scalability**: Cannot add more instances +* **No redundancy**: Server downtime = cache downtime +* **No load distribution**: One server handles all requests +* **No zero-downtime updates**: Updates require service restart +* **Limited scalability**: Cannot add more instances **When you outgrow single-instance:** See High Availability for migration. @@ -319,15 +318,15 @@ See the Troub ## Next Steps -1. Client Setup - Set up Nix clients -1. Monitoring - Set up observability -1. Operations - Learn about backups, upgrades, etc. -1. **Consider** High Availability - When you need to scale +1. Client Setup - Set up Nix clients +2. Monitoring - Set up observability +3. Operations - Learn about backups, upgrades, etc. +4. **Consider** High Availability - When you need to scale ## Related Documentation -- Installation - Installation methods -- Reference - All configuration options -- Storage - Storage backend details -- Database - Database backend details -- High Availability - Migrate to HA when needed +* Installation - Installation methods +* Reference - All configuration options +* Storage - Storage backend details +* Database - Database backend details +* High Availability - Migrate to HA when needed \ No newline at end of file diff --git a/docs/docs/User Guide/Getting Started.md b/docs/docs/User Guide/Getting Started.md index ccb01d4e..105d9970 100644 --- a/docs/docs/User Guide/Getting Started.md +++ b/docs/docs/User Guide/Getting Started.md @@ -1,13 +1,12 @@ -# Getting Started - +# Getting Started ## Getting Started with ncps This section will help you get up and running with ncps quickly and understand the core concepts. ## Quick Links -- Quick Start - Get ncps running in minutes with Docker -- Concepts - Understand how ncps works and why to use it +* Quick Start - Get ncps running in minutes with Docker +* Concepts - Understand how ncps works and why to use it ## What You'll Learn @@ -15,46 +14,46 @@ This section will help you get up and running with ncps quickly and understand t Learn how to: -- Install ncps with Docker in minutes -- Run with local storage (simplest setup) -- Run with S3 storage (scalable setup) -- Verify your installation works -- Get the public key for client configuration +* Install ncps with Docker in minutes +* Run with local storage (simplest setup) +* Run with S3 storage (scalable setup) +* Verify your installation works +* Get the public key for client configuration ### Core Concepts Understand: -- What ncps is and the problems it solves -- How the request flow works -- Storage architecture (local vs S3) -- Database options (SQLite, PostgreSQL, MySQL) -- When to use single-instance vs high-availability mode +* What ncps is and the problems it solves +* How the request flow works +* Storage architecture (local vs S3) +* Database options (SQLite, PostgreSQL, MySQL) +* When to use single-instance vs high-availability mode ## Next Steps After completing the getting started guides: -1. **Installation** - Choose your [installation method](Installation.md) -1. **Configuration** - Review the [configuration options](Configuration/Reference.md) -1. **Client Setup** - Configure your [Nix clients](Usage/Client%20Setup.md) -1. **Deployment** - Plan your [deployment strategy](Deployment.md) +1. **Installation** - Choose your [installation method](Installation.md) +2. **Configuration** - Review the [configuration options](Configuration/Reference.md) +3. **Client Setup** - Configure your [Nix clients](Usage/Client%20Setup.md) +4. **Deployment** - Plan your [deployment strategy](Deployment.md) ## Common Questions **Do I need Redis?** -- No, not for single-instance deployments -- Yes, for high-availability with multiple instances +* No, not for single-instance deployments +* Yes, for high-availability with multiple instances **Should I use S3 or local storage?** -- Local storage: Simple, single-instance deployments -- S3 storage: Multi-instance HA deployments or cloud-native setups +* Local storage: Simple, single-instance deployments +* S3 storage: Multi-instance HA deployments or cloud-native setups **Which database should I use?** -- SQLite: Simple, single-instance deployments -- PostgreSQL/MySQL: Multi-instance HA deployments +* SQLite: Simple, single-instance deployments +* PostgreSQL/MySQL: Multi-instance HA deployments -See Concepts for detailed explanations. +See Concepts for detailed explanations. \ No newline at end of file diff --git a/docs/docs/User Guide/Getting Started/Concepts.md b/docs/docs/User Guide/Getting Started/Concepts.md index bc3fbece..31d78a08 100644 --- a/docs/docs/User Guide/Getting Started/Concepts.md +++ b/docs/docs/User Guide/Getting Started/Concepts.md @@ -1,5 +1,4 @@ -# Concepts - +# Concepts ## Core Concepts This guide explains what ncps is, the problems it solves, and how it works under the hood. @@ -12,28 +11,28 @@ ncps (Nix Cache Proxy Server) is a high-performance proxy server that acts as a When multiple machines running NixOS or Nix pull packages, they often download the same dependencies from remote caches, leading to: -- **Redundant downloads** - Each machine downloads identical files -- **High bandwidth usage** - Significant network traffic for large projects -- **Slower build times** - Network latency impacts development velocity -- **Internet dependency** - Every build requires external connectivity +* **Redundant downloads** - Each machine downloads identical files +* **High bandwidth usage** - Significant network traffic for large projects +* **Slower build times** - Network latency impacts development velocity +* **Internet dependency** - Every build requires external connectivity ### Real-World Example Imagine a team of 10 developers all working on the same Nix-based project: -- A large dependency (500MB) gets updated -- Without ncps: 10 machines × 500MB = 5GB of internet bandwidth used -- With ncps: 500MB downloaded once from internet, then served locally 9 times +* A large dependency (500MB) gets updated +* Without ncps: 10 machines × 500MB = 5GB of internet bandwidth used +* With ncps: 500MB downloaded once from internet, then served locally 9 times ## The Solution ncps solves these issues by acting as a **centralized cache** on your local network: -1. **Single Download**: Package downloaded once from upstream -1. **Local Distribution**: Served to all local machines from cache -1. **Bandwidth Savings**: Dramatic reduction in internet usage -1. **Faster Builds**: Local network speeds vs internet speeds -1. **Offline Capability**: Cached packages available without internet +1. **Single Download**: Package downloaded once from upstream +2. **Local Distribution**: Served to all local machines from cache +3. **Bandwidth Savings**: Dramatic reduction in internet usage +4. **Faster Builds**: Local network speeds vs internet speeds +5. **Offline Capability**: Cached packages available without internet ## How It Works @@ -66,15 +65,15 @@ ncps solves these issues by acting as a **centralized cache** on your local netw **Step-by-step:** -1. **Request** - Nix client requests a store path (e.g., `/nix/store/abc123-package`) -1. **Cache Check** - ncps checks if NarInfo metadata exists in database -1. **Cache Hit** - If cached, serve directly from storage -1. **Cache Miss** - If not cached: - - Fetch NarInfo and NAR from upstream cache - - Store NAR file in storage backend - - Store NarInfo metadata in database - - Sign NarInfo with ncps private key -1. **Serve** - Deliver the path to the requesting client +1. **Request** - Nix client requests a store path (e.g., `/nix/store/abc123-package`) +2. **Cache Check** - ncps checks if NarInfo metadata exists in database +3. **Cache Hit** - If cached, serve directly from storage +4. **Cache Miss** - If not cached: + * Fetch NarInfo and NAR from upstream cache + * Store NAR file in storage backend + * Store NarInfo metadata in database + * Sign NarInfo with ncps private key +5. **Serve** - Deliver the path to the requesting client ### Storage Architecture @@ -99,16 +98,16 @@ ncps uses a flexible storage architecture with separate components for different Stores metadata about cached packages: -- **SQLite** (default): Embedded, no external dependencies, single-instance only -- **PostgreSQL**: Production-ready, supports concurrent access, required for HA -- **MySQL/MariaDB**: Production-ready, supports concurrent access, works for HA +* **SQLite** (default): Embedded, no external dependencies, single-instance only +* **PostgreSQL**: Production-ready, supports concurrent access, required for HA +* **MySQL/MariaDB**: Production-ready, supports concurrent access, works for HA #### Storage Backend (Binary Data) Stores actual package files: -- **Local Filesystem**: Traditional file storage, simple setup, single-instance -- **S3-Compatible**: AWS S3, MinIO, etc., required for HA, scalable +* **Local Filesystem**: Traditional file storage, simple setup, single-instance +* **S3-Compatible**: AWS S3, MinIO, etc., required for HA, scalable ### Key Concepts @@ -116,38 +115,38 @@ Stores actual package files: A NAR is an archive format containing the actual package files. When you install a package, Nix downloads the NAR and unpacks it into `/nix/store`. -- Binary package data -- Typically compressed (xz, zstd) -- Can be very large (500MB+ for some packages) -- Stored in the storage backend +* Binary package data +* Typically compressed (xz, zstd) +* Can be very large (500MB+ for some packages) +* Stored in the storage backend #### NarInfo NarInfo is metadata about a NAR file: -- Hash and size of the NAR -- Compression type -- References to other store paths -- Digital signature -- Stored in the database +* Hash and size of the NAR +* Compression type +* References to other store paths +* Digital signature +* Stored in the database #### Signing ncps signs all cached NarInfo files with its own private key: -- Clients trust ncps by adding its public key to their configuration -- Ensures integrity and authenticity of cached packages -- Private key generated automatically on first run -- Public key available at `http://your-ncps/pubkey` +* Clients trust ncps by adding its public key to their configuration +* Ensures integrity and authenticity of cached packages +* Private key generated automatically on first run +* Public key available at `http://your-ncps/pubkey` #### Upstream Caches ncps fetches packages from configured upstream caches: -- Primary: `cache.nixos.org` (official Nix cache) -- Secondary: Custom caches, Cachix, etc. -- Failover support: tries next upstream if one fails -- Respects upstream public keys for verification +* Primary: `cache.nixos.org` (official Nix cache) +* Secondary: Custom caches, Cachix, etc. +* Failover support: tries next upstream if one fails +* Respects upstream public keys for verification ### Deployment Modes @@ -178,18 +177,18 @@ ncps fetches packages from configured upstream caches: **Characteristics:** -- Single ncps server -- Local locks (no Redis needed) -- Simple to set up and manage -- Perfect for teams up to 100+ users -- Can use any storage and database option +* Single ncps server +* Local locks (no Redis needed) +* Simple to set up and manage +* Perfect for teams up to 100+ users +* Can use any storage and database option **When to Use:** -- Development teams -- Single location deployments -- Simpler operations preferred -- No need for zero-downtime updates +* Development teams +* Single location deployments +* Simpler operations preferred +* No need for zero-downtime updates #### High Availability Mode @@ -219,26 +218,26 @@ ncps fetches packages from configured upstream caches: **Characteristics:** -- Multiple ncps instances (2+) -- Redis for distributed locking -- Shared S3 storage (required) -- Shared PostgreSQL/MySQL (required, SQLite NOT supported) -- Load balancer distributes requests +* Multiple ncps instances (2+) +* Redis for distributed locking +* Shared S3 storage (required) +* Shared PostgreSQL/MySQL (required, SQLite NOT supported) +* Load balancer distributes requests **When to Use:** -- Production deployments -- Need zero-downtime updates -- Geographic distribution -- Very high traffic (1000+ users) -- SLA requirements +* Production deployments +* Need zero-downtime updates +* Geographic distribution +* Very high traffic (1000+ users) +* SLA requirements **Key Features:** -- **Download Deduplication**: Only one instance downloads each package -- **LRU Coordination**: Only one instance runs cache cleanup at a time -- **Automatic Failover**: Instance failures don't interrupt service -- **Horizontal Scaling**: Add instances to handle more load +* **Download Deduplication**: Only one instance downloads each package +* **LRU Coordination**: Only one instance runs cache cleanup at a time +* **Automatic Failover**: Instance failures don't interrupt service +* **Horizontal Scaling**: Add instances to handle more load See the High Availability for detailed setup instructions. @@ -248,39 +247,39 @@ See the H Typical cache hit rates depend on usage patterns: -- Stable environments: 80-95% hit rate -- Active development: 50-80% hit rate -- Fresh installations: 0-20% hit rate (builds up over time) +* Stable environments: 80-95% hit rate +* Active development: 50-80% hit rate +* Fresh installations: 0-20% hit rate (builds up over time) ### Speed Improvements Typical speed improvements with ncps: -- **Local network**: 10-100× faster than internet download -- **Example**: 1Gbps LAN vs 100Mbps internet = 10× faster -- **Latency**: Sub-millisecond vs 10-100ms to upstream +* **Local network**: 10-100× faster than internet download +* **Example**: 1Gbps LAN vs 100Mbps internet = 10× faster +* **Latency**: Sub-millisecond vs 10-100ms to upstream ### Storage Requirements Plan storage based on usage: -- **Small team (5-10 users)**: 20-50GB -- **Medium team (10-50 users)**: 50-200GB -- **Large team (50+ users)**: 200GB-1TB+ -- **LRU cleanup**: Automatically manages size with `--cache-max-size` +* **Small team (5-10 users)**: 20-50GB +* **Medium team (10-50 users)**: 50-200GB +* **Large team (50+ users)**: 200GB-1TB+ +* **LRU cleanup**: Automatically manages size with `--cache-max-size` ## Next Steps Now that you understand how ncps works: -1. Installation - Docker, Kubernetes, NixOS, etc. -1. Storage - Local vs S3 -1. Database - SQLite vs PostgreSQL/MySQL -1. Deployment - Single-instance vs High Availability -1. Client Setup - Configure Nix to use your cache +1. Installation - Docker, Kubernetes, NixOS, etc. +2. Storage - Local vs S3 +3. Database - SQLite vs PostgreSQL/MySQL +4. Deployment - Single-instance vs High Availability +5. Client Setup - Configure Nix to use your cache ## Related Documentation -- Quick Start - Get ncps running quickly -- [Deep dive into internals](../../Developer%20Guide/Architecture.md) - Deep dive into internals -- Reference - All configuration options +* Quick Start - Get ncps running quickly +* [Deep dive into internals](../../Developer%20Guide/Architecture.md) - Deep dive into internals +* Reference - All configuration options \ No newline at end of file diff --git a/docs/docs/User Guide/Getting Started/Quick Start.md b/docs/docs/User Guide/Getting Started/Quick Start.md index 693d0ba2..97a296d0 100644 --- a/docs/docs/User Guide/Getting Started/Quick Start.md +++ b/docs/docs/User Guide/Getting Started/Quick Start.md @@ -1,14 +1,13 @@ -# Quick Start - +# Quick Start ## Quick Start Guide Get ncps up and running in minutes. This guide shows you the fastest path from zero to a working ncps instance. ## Prerequisites -- Docker installed and running -- Basic understanding of Nix package manager -- Network access to upstream caches (cache.nixos.org) +* Docker installed and running +* Basic understanding of Nix package manager +* Network access to upstream caches (cache.nixos.org) ## Option 1: Local Storage (Recommended for Getting Started) @@ -119,9 +118,9 @@ docker run -d \ **Replace:** -- `my-ncps-cache` with your S3 bucket name -- `YOUR_ACCESS_KEY` and `YOUR_SECRET_KEY` with your S3 credentials -- Adjust `endpoint` and `region` for your S3 provider +* `my-ncps-cache` with your S3 bucket name +* `YOUR_ACCESS_KEY` and `YOUR_SECRET_KEY` with your S3 credentials +* Adjust `endpoint` and `region` for your S3 provider ### Step 5: Verify Installation @@ -138,41 +137,41 @@ curl http://localhost:8501/pubkey Your ncps instance is now: -- Listening on port 8501 -- Caching packages from cache.nixos.org -- Storing data in Docker volume (local) or S3 bucket -- Signing cached paths with its own private key -- Ready to serve Nix clients +* Listening on port 8501 +* Caching packages from cache.nixos.org +* Storing data in Docker volume (local) or S3 bucket +* Signing cached paths with its own private key +* Ready to serve Nix clients ## Next Steps -1. Client Setup - Set up your Nix clients to use ncps -1. Concepts - Learn how ncps works under the hood -1. Installation - Pick the best installation method for your needs -1. Reference - Explore more configuration options +1. Client Setup - Set up your Nix clients to use ncps +2. Concepts - Learn how ncps works under the hood +3. Installation - Pick the best installation method for your needs +4. Reference - Explore more configuration options ## Quick Troubleshooting **Container exits immediately:** -- Check you provided all required flags: `--cache-hostname`, storage, database, upstream -- Check logs: `docker logs ncps` +* Check you provided all required flags: `--cache-hostname`, storage, database, upstream +* Check logs: `docker logs ncps` **Can't access** [**http://localhost:8501**](http://localhost:8501)**:** -- Verify container is running: `docker ps | grep ncps` -- Check port mapping: `-p 8501:8501` -- Try from inside container: `docker exec ncps wget -O- http://localhost:8501/nix-cache-info` +* Verify container is running: `docker ps | grep ncps` +* Check port mapping: `-p 8501:8501` +* Try from inside container: `docker exec ncps wget -O- http://localhost:8501/nix-cache-info` **Database errors:** -- Ensure you ran the database migration step -- Verify database path matches between migration and serve commands +* Ensure you ran the database migration step +* Verify database path matches between migration and serve commands See the Troubleshooting for more help. ## Related Documentation -- Docker - Detailed Docker setup -- Docker Compose - Automated setup -- Reference - All configuration options +* Docker - Detailed Docker setup +* Docker Compose - Automated setup +* Reference - All configuration options \ No newline at end of file diff --git a/docs/docs/User Guide/Installation.md b/docs/docs/User Guide/Installation.md index 1cbc51b0..8e4e6c98 100644 --- a/docs/docs/User Guide/Installation.md +++ b/docs/docs/User Guide/Installation.md @@ -1,5 +1,4 @@ -# Installation - +# Installation ## Installation Guide Choose the installation method that best fits your environment and requirements. @@ -20,88 +19,86 @@ Choose the installation method that best fits your environment and requirements. **Use** Docker -- Fastest setup (5 minutes) -- No infrastructure required -- Perfect for trying ncps +* Fastest setup (5 minutes) +* No infrastructure required +* Perfect for trying ncps ### For Small Teams (1-10 users) **Use** Docker Compose or NixOS -- Automated setup and management -- Easy to maintain -- Good for single-server deployments +* Automated setup and management +* Easy to maintain +* Good for single-server deployments ### For Production (Single Instance) **Use** Kubernetes or Helm Chart -- Better resource management -- Built-in health checks and restarts -- Integration with existing infrastructure +* Better resource management +* Built-in health checks and restarts +* Integration with existing infrastructure ### For Production (High Availability) **Use** Helm Chart -- Simplified multi-instance deployment -- Built-in HA configuration -- Handles Redis, load balancing, and more +* Simplified multi-instance deployment +* Built-in HA configuration +* Handles Redis, load balancing, and more ## Prerequisites by Method ### Docker -- Docker installed (version 20.10+) -- 2GB+ available disk space -- Network access to a container registry (GHCR or Docker Hub) +* Docker installed (version 20.10+) +* 2GB+ available disk space +* Network access to a container registry (GHCR or Docker Hub) ### Docker Compose -- Docker and Docker Compose installed -- 2GB+ available disk space +* Docker and Docker Compose installed +* 2GB+ available disk space ### Kubernetes -- Kubernetes cluster (version 1.20+) -- kubectl configured -- PersistentVolume provisioner -- 2GB+ available storage +* Kubernetes cluster (version 1.20+) +* kubectl configured +* PersistentVolume provisioner +* 2GB+ available storage ### Helm -- Kubernetes cluster (version 1.20+) -- Helm installed (version 3.0+) -- kubectl configured +* Kubernetes cluster (version 1.20+) +* Helm installed (version 3.0+) +* kubectl configured ### NixOS -- NixOS 25.05 or later -- Sufficient disk space for cache +* NixOS 25.05 or later +* Sufficient disk space for cache ## Common Post-Installation Steps After installing ncps with any method: -1. **Verify Installation** - - ``` - # Test cache info endpoint - curl http://your-ncps-hostname:8501/nix-cache-info - - # Get public key - curl http://your-ncps-hostname:8501/pubkey - ``` +1. **Verify Installation** -1. Client Setup + ``` + # Test cache info endpoint + curl http://your-ncps-hostname:8501/nix-cache-info - - Add ncps as a substituter - - Add public key to trusted keys + # Get public key + curl http://your-ncps-hostname:8501/pubkey + ``` +2. Client Setup -1. Monitoring (Optional but recommended) + * Add ncps as a substituter + * Add public key to trusted keys +3. Monitoring (Optional but recommended) - - Enable Prometheus metrics - - Set up alerts + * Enable Prometheus metrics + * Set up alerts ## Comparison: Local vs S3 Storage @@ -109,29 +106,29 @@ After installing ncps with any method: **Pros:** -- Simple setup, no external dependencies -- Lower latency for single-instance -- No S3 costs +* Simple setup, no external dependencies +* Lower latency for single-instance +* No S3 costs **Cons:** -- Not suitable for HA deployments -- Limited to single server's disk -- No built-in redundancy +* Not suitable for HA deployments +* Limited to single server's disk +* No built-in redundancy ### S3 Storage **Pros:** -- Required for HA deployments -- Scalable and redundant -- Works with AWS S3, MinIO, and others +* Required for HA deployments +* Scalable and redundant +* Works with AWS S3, MinIO, and others **Cons:** -- Requires S3 service setup -- Potential costs (AWS S3) -- Slight latency overhead +* Requires S3 service setup +* Potential costs (AWS S3) +* Slight latency overhead See Storage for details. @@ -141,42 +138,42 @@ See Storage for **Pros:** -- Embedded, no external service -- Zero configuration -- Perfect for single-instance +* Embedded, no external service +* Zero configuration +* Perfect for single-instance **Cons:** -- NOT supported for HA -- Single connection limit -- File-based limitations +* NOT supported for HA +* Single connection limit +* File-based limitations ### PostgreSQL/MySQL **Pros:** -- Required for HA deployments -- Handles concurrent connections -- Production-ready scaling +* Required for HA deployments +* Handles concurrent connections +* Production-ready scaling **Cons:** -- Requires database service -- More complex setup -- Additional maintenance +* Requires database service +* More complex setup +* Additional maintenance See Database for details. ## Need Help? -- Troubleshooting -- [Configuration Reference](Configuration/Reference.md) -- [GitHub Discussions](https://github.com/kalbasit/ncps/discussions) +* Troubleshooting +* [Configuration Reference](Configuration/Reference.md) +* [GitHub Discussions](https://github.com/kalbasit/ncps/discussions) ## Next Steps After installation: -1. [Configure ncps](Configuration/Reference.md) -1. [Set up Nix clients](Usage/Client%20Setup.md) -1. [Monitor your cache](Operations/Monitoring.md) +1. [Configure ncps](Configuration/Reference.md) +2. [Set up Nix clients](Usage/Client%20Setup.md) +3. [Monitor your cache](Operations/Monitoring.md) \ No newline at end of file diff --git a/docs/docs/User Guide/Installation/Docker Compose.md b/docs/docs/User Guide/Installation/Docker Compose.md index 43ae6377..fe6b6a78 100644 --- a/docs/docs/User Guide/Installation/Docker Compose.md +++ b/docs/docs/User Guide/Installation/Docker Compose.md @@ -1,14 +1,13 @@ -# Docker Compose - +# Docker Compose ## Docker Compose Installation Install ncps using Docker Compose for automated, reproducible deployments. This method is ideal for production single-instance deployments and development environments. ## Prerequisites -- Docker and Docker Compose installed -- Basic familiarity with Docker Compose -- 2GB+ available disk space +* Docker and Docker Compose installed +* Basic familiarity with Docker Compose +* 2GB+ available disk space ## Basic Setup (Local Storage) @@ -78,9 +77,9 @@ docker compose up -d This will: -1. Create directories with correct permissions -1. Run database migrations -1. Start ncps server +1. Create directories with correct permissions +2. Run database migrations +3. Start ncps server ### Step 3: Verify Installation @@ -230,16 +229,16 @@ volumes: **This setup includes:** -- PostgreSQL for shared database -- Redis for distributed locking -- MinIO for S3-compatible storage -- Two ncps instances for high availability +* PostgreSQL for shared database +* Redis for distributed locking +* MinIO for S3-compatible storage +* Two ncps instances for high availability **Access points:** -- ncps instance 1: [http://localhost:8501](http://localhost:8501) -- ncps instance 2: [http://localhost:8502](http://localhost:8502) -- MinIO console: [http://localhost:9001](http://localhost:9001) +* ncps instance 1: [http://localhost:8501](http://localhost:8501) +* ncps instance 2: [http://localhost:8502](http://localhost:8502) +* MinIO console: [http://localhost:9001](http://localhost:9001) ## Using Configuration File @@ -405,14 +404,14 @@ See the Troub ## Next Steps -1. Client Setup - Set up Nix clients to use your cache -1. Monitoring - Set up Prometheus and Grafana -1. Reference - Explore more options -1. Deployment - Consider deployment strategies +1. Client Setup - Set up Nix clients to use your cache +2. Monitoring - Set up Prometheus and Grafana +3. Reference - Explore more options +4. Deployment - Consider deployment strategies ## Related Documentation -- Docker - Manual Docker setup -- Kubernetes - For K8s environments -- High Availability - HA setup guide -- Reference - All configuration options +* Docker - Manual Docker setup +* Kubernetes - For K8s environments +* High Availability - HA setup guide +* Reference - All configuration options \ No newline at end of file diff --git a/docs/docs/User Guide/Installation/Docker.md b/docs/docs/User Guide/Installation/Docker.md index b98ce6f0..198e9e21 100644 --- a/docs/docs/User Guide/Installation/Docker.md +++ b/docs/docs/User Guide/Installation/Docker.md @@ -1,15 +1,14 @@ -# Docker - +# Docker ## Docker Installation Install and run ncps using Docker. This is the simplest installation method, perfect for testing and single-instance deployments. ## Prerequisites -- Docker installed (version 20.10 or later) -- Basic familiarity with Docker commands -- 2GB+ available disk space -- Network access to upstream caches +* Docker installed (version 20.10 or later) +* Basic familiarity with Docker commands +* 2GB+ available disk space +* Network access to upstream caches ## Step 1: Pull the Image @@ -22,9 +21,9 @@ docker pull ghcr.io/kalbasit/ncps **Available tags:** -- `latest` - Latest stable release -- `vX.Y.Z` - Specific version (recommended for production) -- See [Docker Hub](https://hub.docker.com/r/kalbasit/ncps) or [GitHub packages](https://github.com/kalbasit/ncps/pkgs/container/ncps) for all tags +* `latest` - Latest stable release +* `vX.Y.Z` - Specific version (recommended for production) +* See [Docker Hub](https://hub.docker.com/r/kalbasit/ncps) or [GitHub packages](https://github.com/kalbasit/ncps/pkgs/container/ncps) for all tags ### Step 2: Initialize Storage and Database @@ -47,10 +46,10 @@ docker run --rm -v ncps-storage:/storage ghcr.io/kalbasit/ncps \ **What this does:** -- Creates a Docker volume for persistent storage -- Sets up the directory structure -- **Sets ownership to UID 1000** (ncps user in the container) -- Runs database migrations to create required tables +* Creates a Docker volume for persistent storage +* Sets up the directory structure +* **Sets ownership to UID 1000** (ncps user in the container) +* Runs database migrations to create required tables **Important:** The ncps Docker container runs as a non-root user (`ncps`, UID 1000, GID 1000) for security. All storage directories must be owned by UID 1000 for the container to access them. @@ -77,11 +76,11 @@ docker run -d \ **Flags explained:** -- `-d` - Run in detached mode (background) -- `--name ncps` - Container name for easy reference -- `-p 8501:8501` - Expose port 8501 -- `-v ncps-storage:/storage` - Mount persistent volume -- `--restart unless-stopped` - Auto-restart on failures +* `-d` - Run in detached mode (background) +* `--name ncps` - Container name for easy reference +* `-p 8501:8501` - Expose port 8501 +* `-v ncps-storage:/storage` - Mount persistent volume +* `--restart unless-stopped` - Auto-restart on failures ### Step 4: Verify Installation @@ -101,9 +100,9 @@ curl http://localhost:8501/pubkey **Expected output:** -- Container status: "Up" -- Cache info: JSON with StoreDir, Priority, etc. -- Public key: `your-ncps-hostname:base64encodedkey` +* Container status: "Up" +* Cache info: JSON with StoreDir, Priority, etc. +* Public key: `your-ncps-hostname:base64encodedkey` ## Using S3 Storage @@ -241,9 +240,9 @@ docker logs ncps **Common causes:** -- Missing required flags (--cache-hostname, storage, database, upstream) -- Database not initialized (missing migration step) -- Invalid configuration +* Missing required flags (--cache-hostname, storage, database, upstream) +* Database not initialized (missing migration step) +* Invalid configuration ### Can't Access [http://localhost:8501](http://localhost:8501) @@ -290,14 +289,14 @@ See the Troub ## Next Steps -1. Client Setup - Set up Nix clients to use your cache -1. Monitoring - Enable Prometheus metrics -1. Reference - Explore more options -1. **Consider** Docker Compose - For easier management +1. Client Setup - Set up Nix clients to use your cache +2. Monitoring - Enable Prometheus metrics +3. Reference - Explore more options +4. **Consider** Docker Compose - For easier management ## Related Documentation -- Docker Compose - Automated Docker setup -- Reference - All configuration options -- Storage - Local vs S3 storage -- Operations - Monitoring, backup, and maintenance +* Docker Compose - Automated Docker setup +* Reference - All configuration options +* Storage - Local vs S3 storage +* Operations - Monitoring, backup, and maintenance \ No newline at end of file diff --git a/docs/docs/User Guide/Installation/Helm Chart.md b/docs/docs/User Guide/Installation/Helm Chart.md index 2b5c601c..721b1ec0 100644 --- a/docs/docs/User Guide/Installation/Helm Chart.md +++ b/docs/docs/User Guide/Installation/Helm Chart.md @@ -1,13 +1,12 @@ -# Helm Chart - +# Helm Chart Install ncps on Kubernetes using Helm for simplified configuration and management. This is the recommended method for production Kubernetes deployments. ## Prerequisites -- Kubernetes 1.19+ -- Helm 3.8+ -- kubectl configured and connected to your cluster -- PV provisioner support in the underlying infrastructure (for local storage with persistence) +* Kubernetes 1.19+ +* Helm 3.8+ +* kubectl configured and connected to your cluster +* PV provisioner support in the underlying infrastructure (for local storage with persistence) ## Quick Start @@ -34,10 +33,10 @@ helm install ncps . -f values.yaml --namespace ncps This installs ncps with: -- Single replica (StatefulSet mode) -- Local storage (PersistentVolumeClaim, 20Gi) -- SQLite database -- Default upstream: cache.nixos.org +* Single replica (StatefulSet mode) +* Local storage (PersistentVolumeClaim, 20Gi) +* SQLite database +* Default upstream: cache.nixos.org ### Verify Installation @@ -61,9 +60,9 @@ The chart supports two deployment modes: Best for: -- Single instance deployments -- Local persistent storage -- SQLite database +* Single instance deployments +* Local persistent storage +* SQLite database ```yaml mode: statefulset @@ -83,9 +82,9 @@ config: Best for: -- High availability (multiple replicas) -- S3 storage -- PostgreSQL/MySQL database +* High availability (multiple replicas) +* S3 storage +* PostgreSQL/MySQL database ```yaml mode: deployment @@ -599,10 +598,10 @@ ingress: ### From Single Instance to HA -1. Migrate from SQLite to PostgreSQL/MySQL -1. Switch from local storage to S3 -1. Enable Redis -1. Increase replica count +1. Migrate from SQLite to PostgreSQL/MySQL +2. Switch from local storage to S3 +3. Enable Redis +4. Increase replica count ``` # Step 1: Backup SQLite database @@ -650,20 +649,20 @@ kubectl -n ncps logs job/ncps-migration **Pod fails to start with "database file not found":** -- For SQLite + S3 deployments, ensure `storage.local.persistence.enabled: true` is set -- SQLite requires persistent storage even when using S3 for NAR files +* For SQLite + S3 deployments, ensure `storage.local.persistence.enabled: true` is set +* SQLite requires persistent storage even when using S3 for NAR files **Migration job fails:** -- Check migration job logs: `kubectl -n ncps logs job/ncps-migration` -- Verify database credentials are correct -- Ensure database is accessible from the cluster +* Check migration job logs: `kubectl -n ncps logs job/ncps-migration` +* Verify database credentials are correct +* Ensure database is accessible from the cluster **S3 connection errors:** -- Verify S3 credentials and endpoint -- For MinIO, ensure `config.storage.s3.forcePathStyle: true` is set -- Check endpoint includes proper scheme (http:// or https://) +* Verify S3 credentials and endpoint +* For MinIO, ensure `config.storage.s3.forcePathStyle: true` is set +* Check endpoint includes proper scheme (http:// or https://) ## Complete Values Reference @@ -671,6 +670,6 @@ See the Char ## Next Steps -- Client Setup -- Monitoring -- High Availability +* Client Setup +* Monitoring +* High Availability \ No newline at end of file diff --git a/docs/docs/User Guide/Installation/Helm Chart/Chart Reference.md b/docs/docs/User Guide/Installation/Helm Chart/Chart Reference.md index 9dc62c74..c9f44b15 100644 --- a/docs/docs/User Guide/Installation/Helm Chart/Chart Reference.md +++ b/docs/docs/User Guide/Installation/Helm Chart/Chart Reference.md @@ -1,5 +1,4 @@ -# Chart Reference - +# Chart Reference ## Introduction This chart bootstraps a ncps deployment on a Kubernetes cluster using the Helm package manager. ncps is a local binary cache proxy for Nix that fetches store paths from upstream caches and caches them locally, reducing download times and bandwidth usage. @@ -9,9 +8,9 @@ This chart bootstraps a ncps deployment on a Kubernetes cluster using the Helm p ## Prerequisites -- Kubernetes 1.19+ -- Helm 3.8+ -- PV provisioner support in the underlying infrastructure (for local storage with persistence) +* Kubernetes 1.19+ +* Helm 3.8+ +* PV provisioner support in the underlying infrastructure (for local storage with persistence) ## Installation @@ -571,9 +570,9 @@ helm test ncps When using `helm template` (manually or via tools like nixidy), Helm hook annotations are ignored and the test pod gets rendered as a regular resource, causing issues: -- The pod runs once and completes -- It appears as degraded/failed in your cluster -- Updates to the pod fail (can't update completed pods) +* The pod runs once and completes +* It appears as degraded/failed in your cluster +* Updates to the pod fail (can't update completed pods) ```yaml # values.yaml when using helm template @@ -583,8 +582,8 @@ tests: **Note for ArgoCD/Flux users**: These tools may use `helm template` internally. Check your configuration: -- ArgoCD: Depends on your Application's source configuration -- Flux: HelmRelease with `spec.install.disableHooks: true` has this issue +* ArgoCD: Depends on your Application's source configuration +* Flux: HelmRelease with `spec.install.disableHooks: true` has this issue To test your deployment when using templating, use the readiness/liveness probes or manually verify: @@ -602,16 +601,16 @@ The chart includes validation to prevent incompatible configurations: **Error: "High availability mode requires Redis"** -- Enable Redis when using multiple replicas: `config.redis.enabled=true` +* Enable Redis when using multiple replicas: `config.redis.enabled=true` **Error: "High availability mode is not compatible with SQLite"** -- Use PostgreSQL or MySQL: `config.database.type=postgresql` +* Use PostgreSQL or MySQL: `config.database.type=postgresql` **Error: "High availability mode with Deployment requires S3 storage"** -- Either use S3: `config.storage.type=s3` -- Or switch to StatefulSet with NFS: `mode=statefulset` +* Either use S3: `config.storage.type=s3` +* Or switch to StatefulSet with NFS: `mode=statefulset` ### Pods Not Starting @@ -672,8 +671,8 @@ kubectl get secret -ncps -o jsonpath='{.data.redis-password}' | ba ## Further Information -- User Guide -- Installation -- Helm Chart -- [ncps GitHub Repository](https://github.com/kalbasit/ncps) -- [Helm Documentation](https://helm.sh/docs/) +* User Guide +* Installation +* Helm Chart +* [ncps GitHub Repository](https://github.com/kalbasit/ncps) +* [Helm Documentation](https://helm.sh/docs/) \ No newline at end of file diff --git a/docs/docs/User Guide/Installation/Kubernetes.md b/docs/docs/User Guide/Installation/Kubernetes.md index 99596023..649911d2 100644 --- a/docs/docs/User Guide/Installation/Kubernetes.md +++ b/docs/docs/User Guide/Installation/Kubernetes.md @@ -1,15 +1,14 @@ -# Kubernetes - +# Kubernetes ## Kubernetes Installation Deploy ncps on Kubernetes for production-ready, scalable deployments with manual control over resources. ## Prerequisites -- Kubernetes cluster (version 1.20+) -- kubectl configured and connected to your cluster -- PersistentVolume provisioner available -- 2GB+ available storage +* Kubernetes cluster (version 1.20+) +* kubectl configured and connected to your cluster +* PersistentVolume provisioner available +* 2GB+ available storage ## Quick Start @@ -394,9 +393,9 @@ For HA with multiple replicas: ### Prerequisites -- Redis deployed in cluster -- S3 storage configured -- PostgreSQL or MySQL database +* Redis deployed in cluster +* S3 storage configured +* PostgreSQL or MySQL database ### Create Deployment with Multiple Replicas @@ -488,14 +487,14 @@ See the Troub ## Next Steps -1. Client Setup - Set up Nix clients -1. Monitoring - Set up observability -1. Reference - Explore more options -1. **Consider** Helm - For simplified management +1. Client Setup - Set up Nix clients +2. Monitoring - Set up observability +3. Reference - Explore more options +4. **Consider** Helm - For simplified management ## Related Documentation -- Helm - Simplified Kubernetes deployment -- Docker Compose - For non-K8s environments -- High Availability - HA setup guide -- Reference - All configuration options +* Helm - Simplified Kubernetes deployment +* Docker Compose - For non-K8s environments +* High Availability - HA setup guide +* Reference - All configuration options \ No newline at end of file diff --git a/docs/docs/User Guide/Installation/NixOS.md b/docs/docs/User Guide/Installation/NixOS.md index 3c038075..200ee98b 100644 --- a/docs/docs/User Guide/Installation/NixOS.md +++ b/docs/docs/User Guide/Installation/NixOS.md @@ -1,14 +1,13 @@ -# NixOS - +# NixOS ## NixOS Installation Install ncps on NixOS using the built-in service module for native integration and simplified management. ## Prerequisites -- NixOS 25.05 or later (earlier versions don't include the ncps module) -- Sufficient disk space for cache storage -- Basic familiarity with NixOS configuration +* NixOS 25.05 or later (earlier versions don't include the ncps module) +* Sufficient disk space for cache storage +* Basic familiarity with NixOS configuration ## Quick Start @@ -43,10 +42,10 @@ sudo nixos-rebuild switch The service will: -- Create the ncps user and group automatically -- Set up directories with correct permissions -- Initialize the database -- Start the ncps service +* Create the ncps user and group automatically +* Set up directories with correct permissions +* Initialize the database +* Start the ncps service ### Verify Installation @@ -175,8 +174,8 @@ curl http://localhost:8501/pubkey To use S3 storage with NixOS today: -- Install ncps via Docker/Podman on NixOS -- Use the Docker +* Install ncps via Docker/Podman on NixOS +* Use the Docker ## Observability Configuration @@ -380,14 +379,14 @@ sudo nixos-rebuild switch ## Next Steps -1. Client Setup - Set up your Nix clients to use the cache -1. Reference - Explore more configuration options -1. Monitoring - Configure observability -1. High Availability - Consider high availability (use Docker/K8s) +1. Client Setup - Set up your Nix clients to use the cache +2. Reference - Explore more configuration options +3. Monitoring - Configure observability +4. High Availability - Consider high availability (use Docker/K8s) ## Related Documentation -- NixOS Options Search - All module options -- Docker - For S3 storage on NixOS -- Reference - All configuration options -- Client Setup - Configure Nix clients +* NixOS Options Search - All module options +* Docker - For S3 storage on NixOS +* Reference - All configuration options +* Client Setup - Configure Nix clients \ No newline at end of file diff --git a/docs/docs/User Guide/Operations.md b/docs/docs/User Guide/Operations.md index fdd89f3f..419b7f3f 100644 --- a/docs/docs/User Guide/Operations.md +++ b/docs/docs/User Guide/Operations.md @@ -1,52 +1,51 @@ -# Operations - +# Operations ## Operations Guide Operational guides for running ncps in production. ## Guides -- Monitoring - Set up metrics, dashboards, and alerts -- Troubleshooting - Solve common issues -- [Backup & Restore](Operations/Backup%20Restore.md) - Backup strategies and recovery -- Upgrading - Upgrade procedures and migration -- NarInfo Migration - Migrate narinfo metadata to database +* Monitoring - Set up metrics, dashboards, and alerts +* Troubleshooting - Solve common issues +* [Backup & Restore](Operations/Backup%20Restore.md) - Backup strategies and recovery +* Upgrading - Upgrade procedures and migration +* NarInfo Migration - Migrate narinfo metadata to database ## Quick Links ### Monitoring -- [Prometheus Setup](Operations/Monitoring.md) -- [Grafana Dashboards](Operations/Monitoring.md) -- [Alert Manager](Operations/Monitoring.md) +* [Prometheus Setup](Operations/Monitoring.md) +* [Grafana Dashboards](Operations/Monitoring.md) +* [Alert Manager](Operations/Monitoring.md) ### Troubleshooting -- [Common Errors](Operations/Troubleshooting.md) -- [Logs & Debugging](Operations/Troubleshooting.md) -- [Network Connectivity](Operations/Troubleshooting.md) +* [Common Errors](Operations/Troubleshooting.md) +* [Logs & Debugging](Operations/Troubleshooting.md) +* [Network Connectivity](Operations/Troubleshooting.md) ### Backups -- [Database Backups](Operations/Backup%20Restore.md) -- [S3 Object Retention](Operations/Backup%20Restore.md) -- [Disaster Recovery](Operations/Backup%20Restore.md) +* [Database Backups](Operations/Backup%20Restore.md) +* [S3 Object Retention](Operations/Backup%20Restore.md) +* [Disaster Recovery](Operations/Backup%20Restore.md) ### Upgrades -- [Release Notes](Operations/Upgrading.md) -- [Database Migrations](Operations/Upgrading.md) -- [Rollback Procedures](Operations/Upgrading.md) +* [Release Notes](Operations/Upgrading.md) +* [Database Migrations](Operations/Upgrading.md) +* [Rollback Procedures](Operations/Upgrading.md) ### NarInfo Migration -- [Migration Strategies](Operations/NarInfo%20Migration.md) -- [CLI Migration Guide](Operations/NarInfo%20Migration.md) -- [Progress Monitoring](Operations/NarInfo%20Migration.md) -- [Troubleshooting Migration](Operations/NarInfo%20Migration.md) +* [Migration Strategies](Operations/NarInfo%20Migration.md) +* [CLI Migration Guide](Operations/NarInfo%20Migration.md) +* [Progress Monitoring](Operations/NarInfo%20Migration.md) +* [Troubleshooting Migration](Operations/NarInfo%20Migration.md) ## Related Documentation -- [Configuration Reference](Configuration/Reference.md) - All configuration options -- [Deployment Guides](Deployment.md) - Deployment strategies -- [Usage Guides](Usage.md) - Client setup and usage +* [Configuration Reference](Configuration/Reference.md) - All configuration options +* [Deployment Guides](Deployment.md) - Deployment strategies +* [Usage Guides](Usage.md) - Client setup and usage \ No newline at end of file diff --git a/docs/docs/User Guide/Operations/Backup Restore.md b/docs/docs/User Guide/Operations/Backup Restore.md index ceb6abeb..3b4b4c92 100644 --- a/docs/docs/User Guide/Operations/Backup Restore.md +++ b/docs/docs/User Guide/Operations/Backup Restore.md @@ -1,5 +1,4 @@ -# Backup Restore - +# Backup Restore ## Backup & Restore Guide Backup strategies and recovery procedures. @@ -87,29 +86,29 @@ aws s3api put-bucket-versioning \ ### Development -- Database: Daily backups -- Storage: Optional (can rebuild) +* Database: Daily backups +* Storage: Optional (can rebuild) ### Production Single-Instance -- Database: Daily automated backups -- Storage: Weekly backups or S3 with versioning +* Database: Daily automated backups +* Storage: Weekly backups or S3 with versioning ### Production HA -- Database: Automated backups with replication -- Storage: S3 with versioning (built-in) -- Redis: Optional (ephemeral locks) +* Database: Automated backups with replication +* Storage: S3 with versioning (built-in) +* Redis: Optional (ephemeral locks) ## Disaster Recovery -1. Stop ncps instances -1. Restore database from backup -1. Restore storage from backup (if local) -1. Start ncps instances -1. Verify functionality +1. Stop ncps instances +2. Restore database from backup +3. Restore storage from backup (if local) +4. Start ncps instances +5. Verify functionality ## Related Documentation -- Database - Database setup -- Storage - Storage setup +* Database - Database setup +* Storage - Storage setup \ No newline at end of file diff --git a/docs/docs/User Guide/Operations/Monitoring.md b/docs/docs/User Guide/Operations/Monitoring.md index 7d3b2ef3..da2f06ba 100644 --- a/docs/docs/User Guide/Operations/Monitoring.md +++ b/docs/docs/User Guide/Operations/Monitoring.md @@ -1,5 +1,4 @@ -# Monitoring - +# Monitoring ## Monitoring Guide Set up monitoring, metrics, and alerting for ncps. @@ -19,35 +18,35 @@ Access metrics at: `http://your-ncps:8501/metrics` (for `serve`) or via stdout/O **HTTP Metrics:** -- `http_server_requests_total` - Total HTTP requests -- `http_server_request_duration_seconds` - Request duration -- `http_server_active_requests` - Active requests +* `http_server_requests_total` - Total HTTP requests +* `http_server_request_duration_seconds` - Request duration +* `http_server_active_requests` - Active requests **Cache Metrics:** -- `ncps_nar_served_total` - NAR files served -- `ncps_narinfo_served_total` - NarInfo files served +* `ncps_nar_served_total` - NAR files served +* `ncps_narinfo_served_total` - NarInfo files served **Lock Metrics (HA):** -- `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisitions -- `ncps_lock_hold_duration_seconds{type,mode}` - Lock hold time -- `ncps_lock_failures_total{type,reason,mode}` - Lock failures +* `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisitions +* `ncps_lock_hold_duration_seconds{type,mode}` - Lock hold time +* `ncps_lock_failures_total{type,reason,mode}` - Lock failures **Migration Metrics:** -- `ncps_migration_narinfos_total{operation,result}` - NarInfos migrated - - Labels: `operation` (migrate/delete), `result` (success/failure/skipped) -- `ncps_migration_duration_seconds{operation}` - Migration operation duration - - Label: `operation` (migrate/delete) -- `ncps_migration_batch_size` - Migration batch sizes +* `ncps_migration_narinfos_total{operation,result}` - NarInfos migrated + * Labels: `operation` (migrate/delete), `result` (success/failure/skipped) +* `ncps_migration_duration_seconds{operation}` - Migration operation duration + * Label: `operation` (migrate/delete) +* `ncps_migration_batch_size` - Migration batch sizes **Background Migration Metrics:** -- `ncps_background_migration_narinfos_total{operation,result}` - Background NarInfos migrated - - Labels: `operation` (migrate/delete), `result` (success/failure) -- `ncps_background_migration_duration_seconds{operation}` - Background migration operation duration - - Label: `operation` (migrate/delete) +* `ncps_background_migration_narinfos_total{operation,result}` - Background NarInfos migrated + * Labels: `operation` (migrate/delete), `result` (success/failure) +* `ncps_background_migration_duration_seconds{operation}` - Background migration operation duration + * Label: `operation` (migrate/delete) ## Prometheus Configuration @@ -67,15 +66,15 @@ scrape_configs: **Cache Performance:** -- Cache hit rate -- NAR served rate -- Request duration (p50, p95, p99) +* Cache hit rate +* NAR served rate +* Request duration (p50, p95, p99) **HA Lock Performance:** -- Lock acquisition success rate -- Lock retry attempts -- Lock hold duration +* Lock acquisition success rate +* Lock retry attempts +* Lock hold duration ### Example PromQL Queries @@ -150,5 +149,5 @@ curl -f http://localhost:8501/nix-cache-info || exit 1 ## Related Documentation -- Observability - Configure metrics -- Troubleshooting - Debug issues +* Observability - Configure metrics +* Troubleshooting - Debug issues \ No newline at end of file diff --git a/docs/docs/User Guide/Operations/NarInfo Migration.md b/docs/docs/User Guide/Operations/NarInfo Migration.md index 7b852640..b00e312d 100644 --- a/docs/docs/User Guide/Operations/NarInfo Migration.md +++ b/docs/docs/User Guide/Operations/NarInfo Migration.md @@ -1,5 +1,4 @@ -# NarInfo Migration - +# NarInfo Migration ## Overview NarInfo migration moves NarInfo metadata from storage (filesystem or S3) into the database. This provides faster lookups, better querying capabilities, and prepares for advanced features. @@ -8,16 +7,16 @@ NarInfo migration moves NarInfo metadata from storage (filesystem or S3) into th **Benefits:** -- **Faster lookups** - Database queries vs. file I/O -- **Better scalability** - Indexed queries on millions of entries -- **Advanced features** - Enables future features requiring relational data -- **Reduced storage I/O** - Less filesystem/S3 traffic +* **Faster lookups** - Database queries vs. file I/O +* **Better scalability** - Indexed queries on millions of entries +* **Advanced features** - Enables future features requiring relational data +* **Reduced storage I/O** - Less filesystem/S3 traffic **When to migrate:** -- Upgrading from pre-database versions -- Moving to high-availability deployments -- Experiencing performance issues with large caches +* Upgrading from pre-database versions +* Moving to high-availability deployments +* Experiencing performance issues with large caches ## Migration Strategies @@ -27,24 +26,24 @@ NarInfo metadata is automatically migrated during normal operation when accessed **Advantages:** -- Zero downtime -- No manual intervention -- Gradual migration over time -- Works alongside normal cache operation +* Zero downtime +* No manual intervention +* Gradual migration over time +* Works alongside normal cache operation **How it works:** -1. Client requests a package -1. NCPS checks database first -1. If not in database, reads from storage -1. Migrates to database transparently -1. Subsequent requests use database +1. Client requests a package +2. NCPS checks database first +3. If not in database, reads from storage +4. Migrates to database transparently +5. Subsequent requests use database **Best for:** -- Production systems -- Caches with moderate traffic -- When downtime is unacceptable +* Production systems +* Caches with moderate traffic +* When downtime is unacceptable ### Explicit CLI Migration @@ -52,22 +51,22 @@ Bulk migration using the CLI command for faster results. **Advantages:** -- Faster completion -- Predictable timeline -- Progress monitoring -- Deletes from storage after migration +* Faster completion +* Predictable timeline +* Progress monitoring +* Deletes from storage after migration **Disadvantages:** -- Requires downtime (if deleting) -- More manual process +* Requires downtime (if deleting) +* More manual process **Best for:** -- Large caches (millions of narinfos) -- Maintenance windows -- When migration speed is important -- Storage space constraints (migration deletes files) +* Large caches (millions of narinfos) +* Maintenance windows +* When migration speed is important +* Storage space constraints (migration deletes files) ## CLI Migration Guide @@ -98,29 +97,29 @@ ncps migrate-narinfo \ **With Redis locking:** -- Migration can run safely while ncps is serving requests -- Multiple migration workers coordinate to avoid duplicate work -- Uses distributed locks to prevent race conditions -- Same Redis configuration as your running ncps instances +* Migration can run safely while ncps is serving requests +* Multiple migration workers coordinate to avoid duplicate work +* Uses distributed locks to prevent race conditions +* Same Redis configuration as your running ncps instances **Without Redis locking:** -- Uses in-memory locking (no coordination with other instances) -- Should only run when ncps instances are stopped -- Still safe for single-instance deployments +* Uses in-memory locking (no coordination with other instances) +* Should only run when ncps instances are stopped +* Still safe for single-instance deployments **Redis flags:** -- `--cache-redis-addrs` - Comma-separated Redis server addresses (enables distributed locking) -- `--cache-redis-username` - Redis username (optional) -- `--cache-redis-password` - Redis password (optional) -- `--cache-redis-db` - Redis database number (default: 0) -- `--cache-redis-use-tls` - Use TLS for Redis connections (optional) -- `--cache-redis-pool-size` - Redis connection pool size (default: 10) -- `--cache-lock-backend` - Lock backend to use: 'local', 'redis', or 'postgres' (default: 'local') -- `--cache-lock-redis-key-prefix` - Prefix for Redis lock keys (default: 'ncps:lock:') -- `--cache-lock-allow-degraded-mode` - Fallback to local locks if Redis is down -- `--cache-lock-retry-max-attempts` - Max lock retry attempts (default: 3) +* `--cache-redis-addrs` - Comma-separated Redis server addresses (enables distributed locking) +* `--cache-redis-username` - Redis username (optional) +* `--cache-redis-password` - Redis password (optional) +* `--cache-redis-db` - Redis database number (default: 0) +* `--cache-redis-use-tls` - Use TLS for Redis connections (optional) +* `--cache-redis-pool-size` - Redis connection pool size (default: 10) +* `--cache-lock-backend` - Lock backend to use: 'local', 'redis', or 'postgres' (default: 'local') +* `--cache-lock-redis-key-prefix` - Prefix for Redis lock keys (default: 'ncps:lock:') +* `--cache-lock-allow-degraded-mode` - Fallback to local locks if Redis is down +* `--cache-lock-retry-max-attempts` - Max lock retry attempts (default: 3) ### Dry Run @@ -182,10 +181,10 @@ Adjust worker count based on your database capacity: **Guidelines:** -- **SQLite**: 5-10 workers (single-writer limitation) -- **PostgreSQL**: 20-100 workers (depends on connection pool) -- **MySQL/MariaDB**: 20-100 workers (depends on connection pool) -- **S3 Storage**: Higher concurrency OK (parallel uploads) +* **SQLite**: 5-10 workers (single-writer limitation) +* **PostgreSQL**: 20-100 workers (depends on connection pool) +* **MySQL/MariaDB**: 20-100 workers (depends on connection pool) +* **S3 Storage**: Higher concurrency OK (parallel uploads) ## Progress Monitoring @@ -202,11 +201,11 @@ INFO migration completed found=10000 processed=10000 succeeded=9987 failed=13 du **Metrics explained:** -- **found**: Total narinfos discovered -- **processed**: Entered worker pool -- **succeeded**: Successfully migrated -- **failed**: Errors during migration -- **rate**: Narinfos processed per second +* **found**: Total narinfos discovered +* **processed**: Entered worker pool +* **succeeded**: Successfully migrated +* **failed**: Errors during migration +* **rate**: Narinfos processed per second ### OpenTelemetry @@ -221,7 +220,7 @@ ncps migrate-narinfo \ If OpenTelemetry is enabled, monitor via metrics: -**ncps_migration_narinfos_total** +**ncps\_migration\_narinfos\_total** ``` # Total migrations @@ -232,7 +231,7 @@ sum(rate(ncps_migration_narinfos_total{result="success"}[5m])) / sum(rate(ncps_migration_narinfos_total[5m])) ``` -**ncps_migration_duration_seconds** +**ncps\_migration\_duration\_seconds** ``` # Average migration time @@ -242,7 +241,7 @@ histogram_quantile(0.5, ncps_migration_duration_seconds) histogram_quantile(0.99, ncps_migration_duration_seconds) ``` -**ncps_migration_batch_size** +**ncps\_migration\_batch\_size** ``` # Batch sizes @@ -290,23 +289,19 @@ WHERE hash = 'n5glp21rsz314qssw9fbvfswgy3kc68f'; **Solutions:** -1. **Increase worker count** (if database can handle it) - - ```sh - --concurrency=50 - ``` - -1. **Check database connection pool** - - ```sh - --cache-database-pool-max-open-conns=100 - ``` - -1. **Verify network latency** to database +1. **Increase worker count** (if database can handle it) -1. **Run during low-traffic period** + ```sh + --concurrency=50 + ``` +2. **Check database connection pool** -1. **For SQLite**: Consider PostgreSQL/MySQL for better concurrency + ```sh + --cache-database-pool-max-open-conns=100 + ``` +3. **Verify network latency** to database +4. **Run during low-traffic period** +5. **For SQLite**: Consider PostgreSQL/MySQL for better concurrency ### Duplicate Key Errors in Logs @@ -330,9 +325,9 @@ ncps migrate-narinfo \ **How it works:** -- Migration is idempotent -- Already-migrated narinfos are deleted from storage -- Database migration step is skipped +* Migration is idempotent +* Already-migrated narinfos are deleted from storage +* Database migration step is skipped ### Transaction Deadlocks @@ -340,13 +335,12 @@ ncps migrate-narinfo \ **Solutions:** -1. **Reduce worker count** +1. **Reduce worker count** - ```sh - --concurrency=5 - ``` - -1. **Use PostgreSQL/MySQL** instead of SQLite (better concurrent writes) + ```sh + --concurrency=5 + ``` +2. **Use PostgreSQL/MySQL** instead of SQLite (better concurrent writes) ### Out of Memory @@ -354,55 +348,51 @@ ncps migrate-narinfo \ **Solutions:** -1. **Migration loads all migrated hashes** into memory by default - - - For very large caches (millions of narinfos), this can use significant RAM - - Solution: Ensure adequate memory or use background migration instead +1. **Migration loads all migrated hashes** into memory by default -1. **Reduce worker count** to lower memory pressure + * For very large caches (millions of narinfos), this can use significant RAM + * Solution: Ensure adequate memory or use background migration instead +2. **Reduce worker count** to lower memory pressure - ```sh - --concurrency=10 - ``` + ```sh + --concurrency=10 + ``` ## Best Practices ### Before Migration -1. **Backup database** before starting - - ```sh - # SQLite - cp /var/lib/ncps/db.sqlite /var/lib/ncps/db.sqlite.backup - - # PostgreSQL - pg_dump ncps > ncps_backup.sql - ``` - -1. **Test with dry run** +1. **Backup database** before starting - ``` - ncps migrate-narinfo --dry-run ... - ``` + ```sh + # SQLite + cp /var/lib/ncps/db.sqlite /var/lib/ncps/db.sqlite.backup -1. **Check available disk space** as the database will grow. + # PostgreSQL + pg_dump ncps > ncps_backup.sql + ``` +2. **Test with dry run** -1. **Plan for a maintenance window** since this is a destructive operation. + ``` + ncps migrate-narinfo --dry-run ... + ``` +3. **Check available disk space** as the database will grow. +4. **Plan for a maintenance window** since this is a destructive operation. ### During Migration -1. **Monitor progress** via console or OpenTelemetry -1. **Watch error count** - some failures OK, many failures = investigate -1. **Check database performance** - watch for resource constraints -1. **Keep backups available** for quick rollback if needed +1. **Monitor progress** via console or OpenTelemetry +2. **Watch error count** - some failures OK, many failures = investigate +3. **Check database performance** - watch for resource constraints +4. **Keep backups available** for quick rollback if needed ### After Migration -1. **Verify migration count** matches expected -1. **Spot check** several narinfos for data integrity -1. **Test cache operation** - fetch a few packages -1. **Keep storage files** for a few days before deleting (safety) -1. **Monitor cache performance** - should improve after migration +1. **Verify migration count** matches expected +2. **Spot check** several narinfos for data integrity +3. **Test cache operation** - fetch a few packages +4. **Keep storage files** for a few days before deleting (safety) +5. **Monitor cache performance** - should improve after migration ## Common Workflows @@ -443,10 +433,10 @@ ncps migrate-narinfo \ **Benefits:** -- No downtime required -- Migration coordinates with running instances via distributed locks -- Safe to run multiple migration processes simultaneously -- Each narinfo is migrated exactly once (lock prevents duplicates) +* No downtime required +* Migration coordinates with running instances via distributed locks +* Safe to run multiple migration processes simultaneously +* Each narinfo is migrated exactly once (lock prevents duplicates) **Option 2: Maintenance window (without Redis)** @@ -466,8 +456,8 @@ systemctl start ncps@* **When to use each approach:** -- **With Redis**: Production systems where downtime is unacceptable, or when you want to parallelize migration across multiple machines -- **Without Redis**: Maintenance windows, single-instance deployments, or when Redis is not available +* **With Redis**: Production systems where downtime is unacceptable, or when you want to parallelize migration across multiple machines +* **Without Redis**: Maintenance windows, single-instance deployments, or when Redis is not available ### Emergency Rollback @@ -488,12 +478,12 @@ Storage files are still available (unless you used `--delete`). ## Next Steps -- Monitoring - Track migration metrics -- Upgrading - Upgrade procedures -- Database - Database configuration +* Monitoring - Track migration metrics +* Upgrading - Upgrade procedures +* Database - Database configuration ## Related Documentation -- Storage - Storage backends -- Database - Database setup -- Troubleshooting - Common issues +* Storage - Storage backends +* Database - Database setup +* Troubleshooting - Common issues \ No newline at end of file diff --git a/docs/docs/User Guide/Operations/Troubleshooting.md b/docs/docs/User Guide/Operations/Troubleshooting.md index c68b1430..bedb2382 100644 --- a/docs/docs/User Guide/Operations/Troubleshooting.md +++ b/docs/docs/User Guide/Operations/Troubleshooting.md @@ -1,5 +1,4 @@ -# Troubleshooting - +# Troubleshooting ## Troubleshooting Guide Common issues and solutions. @@ -20,10 +19,10 @@ journalctl -u ncps -f **Common causes:** -- Missing required flags -- Database not initialized -- Permission errors -- Port already in use +* Missing required flags +* Database not initialized +* Permission errors +* Port already in use ### Can't Access Cache @@ -35,10 +34,10 @@ curl http://your-ncps:8501/nix-cache-info **Check:** -- Service is running -- Port 8501 is open -- Firewall rules -- Network connectivity +* Service is running +* Port 8501 is open +* Firewall rules +* Network connectivity ## Database Issues @@ -46,9 +45,9 @@ curl http://your-ncps:8501/nix-cache-info SQLite only allows one writer: -- Check no other processes are accessing the database -- Restart ncps -- Use PostgreSQL/MySQL for concurrent access +* Check no other processes are accessing the database +* Restart ncps +* Use PostgreSQL/MySQL for concurrent access ### Migration Errors @@ -83,17 +82,17 @@ sudo chown -R ncps:ncps /var/lib/ncps **Check:** -- Redis is configured and reachable -- All instances use same Redis -- Check logs for lock messages +* Redis is configured and reachable +* All instances use same Redis +* Check logs for lock messages ### High Lock Contention **Solutions:** -- Increase retry settings -- Increase lock TTLs -- Scale down instances if too many +* Increase retry settings +* Increase lock TTLs +* Scale down instances if too many See Distributed Locking. @@ -115,5 +114,5 @@ ncps serve --log-level=debug ## Related Documentation -- Monitoring - Set up monitoring -- Operations - All operational guides +* Monitoring - Set up monitoring +* Operations - All operational guides \ No newline at end of file diff --git a/docs/docs/User Guide/Operations/Upgrading.md b/docs/docs/User Guide/Operations/Upgrading.md index 6f4faba2..b4552b54 100644 --- a/docs/docs/User Guide/Operations/Upgrading.md +++ b/docs/docs/User Guide/Operations/Upgrading.md @@ -1,5 +1,4 @@ -# Upgrading - +# Upgrading ## Upgrading Guide Upgrade ncps to newer versions. @@ -73,9 +72,9 @@ spec: Database schema migrations run automatically on startup. Ensure: -1. Backup database before upgrading -1. Migrations complete successfully (check logs) -1. All instances use same database schema version +1. Backup database before upgrading +2. Migrations complete successfully (check logs) +3. All instances use same database schema version ### NarInfo Migration @@ -83,18 +82,18 @@ When upgrading from versions before database-backed narinfo metadata, you have t **Option 1: Background Migration (Recommended)** -- Continue normal operation -- NarInfo migrated automatically on access -- Zero downtime -- Gradual migration over time -- No manual intervention required +* Continue normal operation +* NarInfo migrated automatically on access +* Zero downtime +* Gradual migration over time +* No manual intervention required **Option 2: Explicit CLI Migration** -- Faster bulk migration -- Use during maintenance window -- Deletion from storage (saves space) -- Progress monitoring and metrics with OpenTelemetry +* Faster bulk migration +* Use during maintenance window +* Deletion from storage (saves space) +* Progress monitoring and metrics with OpenTelemetry **Example CLI migration:** @@ -144,5 +143,5 @@ helm rollback ncps -n ncps ## Related Documentation -- Installation - Installation methods -- Deployment - Deployment strategies +* Installation - Installation methods +* Deployment - Deployment strategies \ No newline at end of file diff --git a/docs/docs/User Guide/Usage.md b/docs/docs/User Guide/Usage.md index 3d2e95c1..aa9d210f 100644 --- a/docs/docs/User Guide/Usage.md +++ b/docs/docs/User Guide/Usage.md @@ -1,28 +1,27 @@ -# Usage - +# Usage ## Usage Guide Learn how to use ncps effectively. ## Guides -- Client Setup - Configure Nix clients to use your cache -- Cache Management - Manage cache size and cleanup +* Client Setup - Configure Nix clients to use your cache +* Cache Management - Manage cache size and cleanup ## Quick Links ### Setting Up Clients -1. [NixOS Configuration](Usage/Client%20Setup.md) -1. [Non-NixOS Linux](Usage/Client%20Setup.md) -1. [macOS Setup](Usage/Client%20Setup.md) -1. [CI/CD Integration](Usage/Client%20Setup.md) +1. [NixOS Configuration](Usage/Client%20Setup.md) +2. [Non-NixOS Linux](Usage/Client%20Setup.md) +3. [macOS Setup](Usage/Client%20Setup.md) +4. [CI/CD Integration](Usage/Client%20Setup.md) ### Managing Your Cache -1. [Automatic GC](Usage/Cache%20Management.md) -1. [Manual Cleanup](Usage/Cache%20Management.md) -1. [Size Monitoring](Usage/Cache%20Management.md) +1. [Automatic GC](Usage/Cache%20Management.md) +2. [Manual Cleanup](Usage/Cache%20Management.md) +3. [Size Monitoring](Usage/Cache%20Management.md) ## Common Tasks @@ -39,6 +38,6 @@ nix-build --option substituters "http://your-ncps:8501" ... ## Related Documentation -- Configuration Reference - Configuration options -- [Monitoring Guide](Operations/Monitoring.md) - Monitor cache performance -- [Troubleshooting Guide](Operations/Troubleshooting.md) - Solve common issues +* Configuration Reference - Configuration options +* [Monitoring Guide](Operations/Monitoring.md) - Monitor cache performance +* [Troubleshooting Guide](Operations/Troubleshooting.md) - Solve common issues \ No newline at end of file diff --git a/docs/docs/User Guide/Usage/Cache Management.md b/docs/docs/User Guide/Usage/Cache Management.md index 19d29dc7..6614b60e 100644 --- a/docs/docs/User Guide/Usage/Cache Management.md +++ b/docs/docs/User Guide/Usage/Cache Management.md @@ -1,5 +1,4 @@ -# Cache Management - +# Cache Management ## Cache Management Guide Manage cache size, cleanup, and optimization. @@ -23,10 +22,10 @@ cache: **Size formats:** -- `10K` - 10 kilobytes -- `100M` - 100 megabytes -- `50G` - 50 gigabytes -- `1T` - 1 terabyte +* `10K` - 10 kilobytes +* `100M` - 100 megabytes +* `50G` - 50 gigabytes +* `1T` - 1 terabyte ### Check Current Size @@ -59,9 +58,9 @@ cache: **Cron schedule examples:** -- `0 2 * * *` - Daily at 2 AM -- `0 */6 * * *` - Every 6 hours -- `0 3 * * 0` - Weekly on Sunday at 3 AM +* `0 2 * * *` - Daily at 2 AM +* `0 */6 * * *` - Every 6 hours +* `0 3 * * 0` - Weekly on Sunday at 3 AM ### Manual Cleanup @@ -87,12 +86,12 @@ If Prometheus is enabled: **Cache size:** -- Custom script to export size metrics +* Custom script to export size metrics **Cache hits/misses:** -- `ncps_nar_served_total` - Total NARs served -- `ncps_narinfo_served_total` - Total NarInfo served +* `ncps_nar_served_total` - Total NARs served +* `ncps_narinfo_served_total` - Total NarInfo served **Query cache hit rate:** @@ -144,10 +143,10 @@ NarInfo metadata is automatically migrated during normal operation when accessed **How it works:** -- Client requests a package -- NCPS checks database first -- If not found, reads from storage and migrates -- Subsequent requests use faster database lookups +* Client requests a package +* NCPS checks database first +* If not found, reads from storage and migrates +* Subsequent requests use faster database lookups ### Explicit Migration (CLI) @@ -185,9 +184,9 @@ ncps migrate-narinfo --dry-run \ Monitor migration progress through: -- **Console logs** - Progress updates every 5 seconds -- **OpenTelemetry** - Export traces and metrics (enable with `--otel-enabled`) -- **Final summary** - Completion report with statistics +* **Console logs** - Progress updates every 5 seconds +* **OpenTelemetry** - Export traces and metrics (enable with `--otel-enabled`) +* **Final summary** - Completion report with statistics **Example output:** @@ -201,35 +200,35 @@ INFO migration completed found=10000 processed=10000 succeeded=9987 failed=13 du **Use background migration when:** -- Running in production with uptime requirements -- Cache has moderate traffic -- No rush to complete migration +* Running in production with uptime requirements +* Cache has moderate traffic +* No rush to complete migration **Use CLI migration when:** -- Large cache (millions of narinfos) -- Need faster completion -- Storage space is limited (migration deletes narinfos) -- Upgrading from pre-database versions +* Large cache (millions of narinfos) +* Need faster completion +* Storage space is limited (migration deletes narinfos) +* Upgrading from pre-database versions See [NarInfo Migration Guide](../Operations/NarInfo%20Migration.md) for comprehensive documentation. ## Best Practices -1. **Set reasonable max-size** - Based on available disk space -1. **Enable LRU cleanup** - Automatic management -1. **Monitor cache usage** - Watch for growth trends -1. **Plan for growth** - Cache size increases over time -1. **Use S3 for large caches** - Better for 1TB+ caches -1. **Migrate narinfo to database** - Improves lookup performance +1. **Set reasonable max-size** - Based on available disk space +2. **Enable LRU cleanup** - Automatic management +3. **Monitor cache usage** - Watch for growth trends +4. **Plan for growth** - Cache size increases over time +5. **Use S3 for large caches** - Better for 1TB+ caches +6. **Migrate narinfo to database** - Improves lookup performance ## Next Steps -- Monitoring - Track cache performance -- Reference - All cache options +* Monitoring - Track cache performance +* Reference - All cache options ## Related Documentation -- Storage - Storage backends -- Monitoring - Monitor cache metrics -- Troubleshooting - Solve issues +* Storage - Storage backends +* Monitoring - Monitor cache metrics +* Troubleshooting - Solve issues \ No newline at end of file diff --git a/docs/docs/User Guide/Usage/Client Setup.md b/docs/docs/User Guide/Usage/Client Setup.md index ceac0276..249dbaf2 100644 --- a/docs/docs/User Guide/Usage/Client Setup.md +++ b/docs/docs/User Guide/Usage/Client Setup.md @@ -1,5 +1,4 @@ -# Client Setup - +# Client Setup ## Client Setup Guide Configure your Nix clients to use your ncps cache. @@ -118,8 +117,8 @@ nix-build '' -A hello Look for log messages like: -- `serving nar from cache` - Cache hit! -- `downloading nar from upstream` - Cache miss, fetching from upstream +* `serving nar from cache` - Cache hit! +* `downloading nar from upstream` - Cache miss, fetching from upstream ## Priority and Order @@ -217,9 +216,9 @@ nix.settings.trusted-users = [ "root" "youruser" ]; **Possible causes:** -1. ncps doesn't have the package cached yet (first download) -1. ncps cache listed after official cache (order matters) -1. Public key not trusted +1. ncps doesn't have the package cached yet (first download) +2. ncps cache listed after official cache (order matters) +3. Public key not trusted **Check ncps logs** to see if requests are reaching it. @@ -227,12 +226,12 @@ See the Troub ## Next Steps -1. Monitoring - Set up monitoring -1. Cache Management - Configure LRU cleanup -1. Reference - Explore more options +1. Monitoring - Set up monitoring +2. Cache Management - Configure LRU cleanup +3. Reference - Explore more options ## Related Documentation -- Reference - All configuration options -- Monitoring - Monitor cache hits/misses -- Troubleshooting - Solve issues +* Reference - All configuration options +* Monitoring - Monitor cache hits/misses +* Troubleshooting - Solve issues \ No newline at end of file From 9de831145d9193c7ab8d4a78ac633a092f70b28f Mon Sep 17 00:00:00 2001 From: Wael Nasreddine Date: Sat, 31 Jan 2026 23:27:25 -0800 Subject: [PATCH 2/2] run nix fmt --- docs/docs.md | 11 +- docs/docs/Developer Guide.md | 23 +- docs/docs/Developer Guide/Architecture.md | 25 +- .../Architecture/Components.md | 91 +-- .../Architecture/Request Flow.md | 9 +- .../Architecture/Storage Backends.md | 37 +- .../S3 Storage Implementation.md | 59 +- docs/docs/Developer Guide/Contributing.md | 363 +++++------ docs/docs/Developer Guide/Testing.md | 35 +- docs/docs/User Guide.md | 81 +-- docs/docs/User Guide/Configuration.md | 99 +-- .../User Guide/Configuration/Analytics.md | 174 +++--- .../docs/User Guide/Configuration/Database.md | 23 +- .../Database/Migration Between Databases.md | 9 +- .../Database/MySQLMariaDB Configuration.md | 23 +- .../Database/PostgreSQL Configuration.md | 31 +- .../Database/SQLite Configuration.md | 27 +- .../Configuration/Database/Troubleshooting.md | 41 +- .../User Guide/Configuration/Observability.md | 139 ++--- .../User Guide/Configuration/Reference.md | 97 +-- docs/docs/User Guide/Configuration/Storage.md | 21 +- .../Storage/Local Filesystem Storage.md | 29 +- .../Storage/Migration Between Storage Back.md | 5 +- .../Storage/S3-Compatible Storage.md | 63 +- .../Storage/Storage Comparison.md | 5 +- .../Configuration/Storage/Troubleshooting.md | 23 +- docs/docs/User Guide/Deployment.md | 125 ++-- .../Deployment/Distributed Locking.md | 585 +++++++++--------- .../Deployment/High Availability.md | 153 ++--- .../User Guide/Deployment/Single Instance.md | 109 ++-- docs/docs/User Guide/Getting Started.md | 49 +- .../User Guide/Getting Started/Concepts.md | 171 ++--- .../User Guide/Getting Started/Quick Start.md | 53 +- docs/docs/User Guide/Installation.md | 143 ++--- .../User Guide/Installation/Docker Compose.md | 45 +- docs/docs/User Guide/Installation/Docker.md | 63 +- .../User Guide/Installation/Helm Chart.md | 61 +- .../Helm Chart/Chart Reference.md | 37 +- .../User Guide/Installation/Kubernetes.md | 33 +- docs/docs/User Guide/Installation/NixOS.md | 37 +- docs/docs/User Guide/Operations.md | 51 +- .../User Guide/Operations/Backup Restore.md | 31 +- docs/docs/User Guide/Operations/Monitoring.md | 53 +- .../Operations/NarInfo Migration.md | 248 ++++---- .../User Guide/Operations/Troubleshooting.md | 41 +- docs/docs/User Guide/Operations/Upgrading.md | 31 +- docs/docs/User Guide/Usage.md | 27 +- .../docs/User Guide/Usage/Cache Management.md | 73 +-- docs/docs/User Guide/Usage/Client Setup.md | 25 +- 49 files changed, 1936 insertions(+), 1851 deletions(-) diff --git a/docs/docs.md b/docs/docs.md index 62733f82..f83124eb 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -1,4 +1,5 @@ -# docs +# docs + ## ncps: Nix Cache Proxy Server Welcome to the official documentation for **ncps** (Nix Cache Proxy Server). @@ -9,8 +10,8 @@ Welcome to the official documentation for **ncps** (Nix Cache Proxy Server). Please choose one of the following guides to get started: -* [**User Guide**](docs/User%20Guide.md) Everything you need to know about installing, configuring, deploying, and operating ncps. Start here if you are setting up ncps for yourself or your organization. -* [**Developer Guide**](docs/Developer%20Guide.md) Detailed information on the system architecture, component design, and contribution guidelines. Head here if you want to understand the internals or contribute to the project. +- [**User Guide**](docs/User%20Guide.md) Everything you need to know about installing, configuring, deploying, and operating ncps. Start here if you are setting up ncps for yourself or your organization. +- [**Developer Guide**](docs/Developer%20Guide.md) Detailed information on the system architecture, component design, and contribution guidelines. Head here if you want to understand the internals or contribute to the project. ## About the Author @@ -18,5 +19,5 @@ Please choose one of the following guides to get started: If you find this project useful, check out my blog or consider supporting my work: -* **Blog**: [https://wael.nasreddine.com/](https://wael.nasreddine.com/) -* **Sponsor**: [https://github.com/sponsors/kalbasit](https://github.com/sponsors/kalbasit) \ No newline at end of file +- **Blog**: [https://wael.nasreddine.com/](https://wael.nasreddine.com/) +- **Sponsor**: [https://github.com/sponsors/kalbasit](https://github.com/sponsors/kalbasit) diff --git a/docs/docs/Developer Guide.md b/docs/docs/Developer Guide.md index cf7869d4..41c800e4 100644 --- a/docs/docs/Developer Guide.md +++ b/docs/docs/Developer Guide.md @@ -1,4 +1,5 @@ -# Developer Guide +# Developer Guide + ## Development Guide Information for contributing to ncps development. @@ -25,9 +26,9 @@ nix develop **Available tools in dev shell:** -* go, golangci-lint, sqlc, sqlfluff -* dbmate, delve, watchexec -* Integration test helpers +- go, golangci-lint, sqlc, sqlfluff +- dbmate, delve, watchexec +- Integration test helpers ## Development Workflow @@ -55,10 +56,10 @@ nix run .#deps This starts: -* **MinIO** (port 9000) - S3-compatible storage -* **PostgreSQL** (port 5432) - Database -* **MySQL/MariaDB** (port 3306) - Database -* **Redis** (port 6379) - Distributed locks +- **MinIO** (port 9000) - S3-compatible storage +- **PostgreSQL** (port 5432) - Database +- **MySQL/MariaDB** (port 3306) - Database +- **Redis** (port 6379) - Distributed locks ### Code Quality @@ -96,6 +97,6 @@ See Testing  ## Related Documentation -* Contributing - Full contribution guide -* Architecture - Deep dive into design -* Testing - Testing procedures \ No newline at end of file +- Contributing - Full contribution guide +- Architecture - Deep dive into design +- Testing - Testing procedures diff --git a/docs/docs/Developer Guide/Architecture.md b/docs/docs/Developer Guide/Architecture.md index b916e047..b33730cc 100644 --- a/docs/docs/Developer Guide/Architecture.md +++ b/docs/docs/Developer Guide/Architecture.md @@ -1,13 +1,14 @@ -# Architecture +# Architecture + ## Architecture Documentation Deep dive into ncps internals and design. ## Guides -* Components - System components and their interactions -* Storage Backends - Local and S3 storage implementation -* Request Flow - Detailed request processing flow +- Components - System components and their interactions +- Storage Backends - Local and S3 storage implementation +- Request Flow - Detailed request processing flow ## Overview @@ -15,10 +16,10 @@ ncps is designed as a modular caching proxy with pluggable storage and database ## Key Design Principles -1. **Modularity** - Separate concerns (storage, database, locks, server) -2. **Flexibility** - Support multiple backends for storage and database -3. **Scalability** - Scale from single instance to high availability -4. **Simplicity** - Easy to deploy and operate +1. **Modularity** - Separate concerns (storage, database, locks, server) +1. **Flexibility** - Support multiple backends for storage and database +1. **Scalability** - Scale from single instance to high availability +1. **Simplicity** - Easy to deploy and operate ## System Architecture @@ -43,7 +44,7 @@ ncps is designed as a modular caching proxy with pluggable storage and database ## Related Documentation -* Components - Detailed component breakdown -* Storage Backends - Storage implementation -* Request Flow - Request processing -* Developer Guide - Contributing \ No newline at end of file +- Components - Detailed component breakdown +- Storage Backends - Storage implementation +- Request Flow - Request processing +- Developer Guide - Contributing diff --git a/docs/docs/Developer Guide/Architecture/Components.md b/docs/docs/Developer Guide/Architecture/Components.md index b0c1cbad..d1d40604 100644 --- a/docs/docs/Developer Guide/Architecture/Components.md +++ b/docs/docs/Developer Guide/Architecture/Components.md @@ -1,4 +1,5 @@ -# Components +# Components + Detailed breakdown of ncps system components. ## HTTP Server (pkg/server/) @@ -7,33 +8,33 @@ Detailed breakdown of ncps system components. **Responsibilities:** -* Handle HTTP requests -* Route requests to handlers -* Serve static files (pubkey, nix-cache-info) -* Middleware (logging, metrics, tracing) +- Handle HTTP requests +- Route requests to handlers +- Serve static files (pubkey, nix-cache-info) +- Middleware (logging, metrics, tracing) **Key Endpoints:** -* `GET /pubkey` - Public key -* `GET /nix-cache-info` - Cache metadata -* `GET /.narinfo` - Package metadata -* `GET /nar/` - Package archive -* `GET /metrics` - Prometheus metrics (if enabled) +- `GET /pubkey` - Public key +- `GET /nix-cache-info` - Cache metadata +- `GET /.narinfo` - Package metadata +- `GET /nar/` - Package archive +- `GET /metrics` - Prometheus metrics (if enabled) ## Cache Layer (pkg/cache/) **Responsibilities:** -* Check if package exists in cache -* Fetch from upstream if not cached -* Sign NarInfo files -* Coordinate downloads (HA mode) +- Check if package exists in cache +- Fetch from upstream if not cached +- Sign NarInfo files +- Coordinate downloads (HA mode) **Key Functions:** -* `GetNarInfo()` - Get package metadata -* `GetNar()` - Get package archive -* `DownloadAndCache()` - Fetch from upstream +- `GetNarInfo()` - Get package metadata +- `GetNar()` - Get package archive +- `DownloadAndCache()` - Fetch from upstream ## Storage Backends (pkg/storage/) @@ -41,14 +42,14 @@ Detailed breakdown of ncps system components. **Implementations:** -* **Local** (`storage/local/`) - Filesystem storage -* **S3** (`storage/s3/`) - S3-compatible storage +- **Local** (`storage/local/`) - Filesystem storage +- **S3** (`storage/s3/`) - S3-compatible storage **Responsibilities:** -* Store and retrieve NAR files -* Store and retrieve NarInfo files -* Store secret keys +- Store and retrieve NAR files +- Store and retrieve NarInfo files +- Store secret keys ## Database Backends (pkg/database/) @@ -56,47 +57,47 @@ Detailed breakdown of ncps system components. **Implementations:** -* **SQLite** (`database/sqlitedb/`) -* **PostgreSQL** (`database/postgresdb/`) -* **MySQL** (`database/mysqldb/`) +- **SQLite** (`database/sqlitedb/`) +- **PostgreSQL** (`database/postgresdb/`) +- **MySQL** (`database/mysqldb/`) **Schema:** `db/schema.sql` **Queries:** `db/query.*.sql` **Responsibilities:** -* Store NarInfo metadata -* Track cache size -* Store download state +- Store NarInfo metadata +- Track cache size +- Store download state ## Lock Manager (pkg/lock/) **Implementations:** -* **Local** (`lock/local/`) - In-process locks (sync.Mutex, sync.RWMutex) -* **Redis** (`lock/redis/`) - Distributed locks (Redlock algorithm) -* **PostgreSQL** (`lock/postgres/`) - Distributed locks (PostgreSQL advisory locks) +- **Local** (`lock/local/`) - In-process locks (sync.Mutex, sync.RWMutex) +- **Redis** (`lock/redis/`) - Distributed locks (Redlock algorithm) +- **PostgreSQL** (`lock/postgres/`) - Distributed locks (PostgreSQL advisory locks) **Responsibilities:** -* Coordinate downloads (prevent duplicates) -* Coordinate LRU cleanup -* Handle lock retries -* Provide both exclusive and shared (read-write) locking +- Coordinate downloads (prevent duplicates) +- Coordinate LRU cleanup +- Handle lock retries +- Provide both exclusive and shared (read-write) locking **Lock Types:** -* `Locker` - Exclusive locks only (Lock/Unlock/TryLock) -* `RWLocker` - Read-write locks (Lock/Unlock/RLock/RUnlock) - * PostgreSQL: True shared read locks via `pg_advisory_lock_shared()` - * Redis: True shared read locks via Redis hash sets +- `Locker` - Exclusive locks only (Lock/Unlock/TryLock) +- `RWLocker` - Read-write locks (Lock/Unlock/RLock/RUnlock) + - PostgreSQL: True shared read locks via `pg_advisory_lock_shared()` + - Redis: True shared read locks via Redis hash sets ## NAR Handler (pkg/nar/) **Responsibilities:** -* Parse NAR format -* Handle compression (xz, zstd) -* Extract metadata +- Parse NAR format +- Handle compression (xz, zstd) +- Extract metadata ## Component Interaction @@ -114,6 +115,6 @@ Response ## Related Documentation -* Storage Backends - Storage details -* Request Flow - Request processing -* Developer Guide - Code structure \ No newline at end of file +- Storage Backends - Storage details +- Request Flow - Request processing +- Developer Guide - Code structure diff --git a/docs/docs/Developer Guide/Architecture/Request Flow.md b/docs/docs/Developer Guide/Architecture/Request Flow.md index 12bcc41e..989e1617 100644 --- a/docs/docs/Developer Guide/Architecture/Request Flow.md +++ b/docs/docs/Developer Guide/Architecture/Request Flow.md @@ -1,4 +1,5 @@ -# Request Flow +# Request Flow + ## NarInfo Request Flow ``` @@ -97,6 +98,6 @@ Result: Only one download from upstream! ## Related Documentation -* Components - System components -* Distributed Locking - Lock details -* High Availability - HA deployment \ No newline at end of file +- Components - System components +- Distributed Locking - Lock details +- High Availability - HA deployment diff --git a/docs/docs/Developer Guide/Architecture/Storage Backends.md b/docs/docs/Developer Guide/Architecture/Storage Backends.md index 9befed46..dd83bec3 100644 --- a/docs/docs/Developer Guide/Architecture/Storage Backends.md +++ b/docs/docs/Developer Guide/Architecture/Storage Backends.md @@ -1,4 +1,5 @@ -# Storage Backends +# Storage Backends + Implementation details of local and S3 storage backends. ## Storage Interface @@ -30,9 +31,9 @@ type NarStore interface { **Implementation:** -* Files stored directly on filesystem -* Simple directory structure -* Atomic writes using temp files +- Files stored directly on filesystem +- Simple directory structure +- Atomic writes using temp files **Directory Structure:** @@ -48,14 +49,14 @@ type NarStore interface { **Pros:** -* Fast (local I/O) -* Simple implementation -* No external dependencies +- Fast (local I/O) +- Simple implementation +- No external dependencies **Cons:** -* Not suitable for HA -* Limited to single server +- Not suitable for HA +- Limited to single server ## S3-Compatible Backend @@ -63,9 +64,9 @@ type NarStore interface { **Implementation:** -* Uses MinIO Go SDK -* Supports all S3-compatible services -* Concurrent-safe +- Uses MinIO Go SDK +- Supports all S3-compatible services +- Concurrent-safe **Object Structure:** @@ -78,17 +79,17 @@ s3://bucket/ **Pros:** -* Scalable -* Redundant See S3 Storage Implementation for detailed implementation. +- Scalable +- Redundant See S3 Storage Implementation for detailed implementation. **Cons:** -* Network latency -* Requires S3 service +- Network latency +- Requires S3 service **Implementation Details:** See S3 Storage Implementation for detailed implementation. ## Related Documentation -* [Storage Configuration](../../User%20Guide/Configuration/Storage.md) - Configure storage -* Components - All components \ No newline at end of file +- [Storage Configuration](../../User%20Guide/Configuration/Storage.md) - Configure storage +- Components - All components diff --git a/docs/docs/Developer Guide/Architecture/Storage Backends/S3 Storage Implementation.md b/docs/docs/Developer Guide/Architecture/Storage Backends/S3 Storage Implementation.md index aecc311f..acb02fef 100644 --- a/docs/docs/Developer Guide/Architecture/Storage Backends/S3 Storage Implementation.md +++ b/docs/docs/Developer Guide/Architecture/Storage Backends/S3 Storage Implementation.md @@ -1,15 +1,16 @@ -# S3 Storage Implementation +# S3 Storage Implementation + ## S3 Storage Implementation This package provides an S3-compatible storage backend for ncps (Nix Cache Proxy Server). It implements the same interface as the local storage but uses S3 or S3-compatible services like MinIO for backend storage. ## Features -* **S3 Compatibility**: Works with AWS S3 and any S3-compatible service (MinIO, Ceph, etc.) -* **Drop-in Replacement**: Implements the same interface as local storage -* **Configurable**: Supports custom endpoints, regions, and authentication -* **MinIO Optimized**: Built using the MinIO Go SDK for optimal compatibility -* **Telemetry**: Includes OpenTelemetry tracing for monitoring +- **S3 Compatibility**: Works with AWS S3 and any S3-compatible service (MinIO, Ceph, etc.) +- **Drop-in Replacement**: Implements the same interface as local storage +- **Configurable**: Supports custom endpoints, regions, and authentication +- **MinIO Optimized**: Built using the MinIO Go SDK for optimal compatibility +- **Telemetry**: Includes OpenTelemetry tracing for monitoring ## Configuration @@ -28,9 +29,9 @@ type Config struct { ### Important Notes -* **Endpoint Format**: The endpoint **must** include the URL scheme (e.g., `"http://localhost:9000"` or `"https://s3.us-west-2.amazonaws.com"`). The scheme determines whether SSL/TLS is used. -* **Region**: Optional for MinIO, but typically required for AWS S3. -* **ForcePathStyle**: Set to `true` for MinIO and other S3-compatible services that require path-style addressing. Set to `false` for AWS S3 (which uses virtual-hosted-style by default). +- **Endpoint Format**: The endpoint **must** include the URL scheme (e.g., `"http://localhost:9000"` or `"https://s3.us-west-2.amazonaws.com"`). The scheme determines whether SSL/TLS is used. +- **Region**: Optional for MinIO, but typically required for AWS S3. +- **ForcePathStyle**: Set to `true` for MinIO and other S3-compatible services that require path-style addressing. Set to `false` for AWS S3 (which uses virtual-hosted-style by default). ## Usage @@ -104,18 +105,18 @@ Files are automatically sharded using the first 1-2 characters of their hash to The implementation properly handles S3-specific errors: -* `NoSuchKey` errors are converted to `storage.ErrNotFound` -* Configuration validation ensures required fields are provided -* Bucket existence is verified during initialization -* Returns `storage.ErrAlreadyExists` when attempting to overwrite existing objects +- `NoSuchKey` errors are converted to `storage.ErrNotFound` +- Configuration validation ensures required fields are provided +- Bucket existence is verified during initialization +- Returns `storage.ErrAlreadyExists` when attempting to overwrite existing objects ### Telemetry All operations include OpenTelemetry tracing with relevant attributes: -* Operation names (e.g., "s3.GetNarInfo", "s3.PutNar") -* Object keys and paths -* Hash values and NAR URLs +- Operation names (e.g., "s3.GetNarInfo", "s3.PutNar") +- Object keys and paths +- Hash values and NAR URLs ### Streaming Uploads @@ -131,18 +132,18 @@ go test ./pkg/storage/s3/... ## Dependencies -* `github.com/minio/minio-go/v7` - MinIO Go SDK for S3 operations -* `github.com/nix-community/go-nix` - Nix-specific types and utilities -* `go.opentelemetry.io/otel` - OpenTelemetry for tracing +- `github.com/minio/minio-go/v7` - MinIO Go SDK for S3 operations +- `github.com/nix-community/go-nix` - Nix-specific types and utilities +- `go.opentelemetry.io/otel` - OpenTelemetry for tracing ## Migration from Local Storage To migrate from local storage to S3 storage: -1. Create an S3 bucket or MinIO instance -2. Configure the S3 storage with appropriate credentials -3. Replace the local storage initialization with S3 storage -4. The rest of your application code remains unchanged +1. Create an S3 bucket or MinIO instance +1. Configure the S3 storage with appropriate credentials +1. Replace the local storage initialization with S3 storage +1. The rest of your application code remains unchanged ```go // Before (local storage) @@ -160,9 +161,9 @@ s3Store, err := s3.New(ctx, s3.Config{ ## Security Considerations -* Store credentials securely (environment variables, IAM roles, etc.) -* Use IAM policies to restrict bucket access (for AWS S3) -* Consider using temporary credentials for production -* Enable bucket versioning for data protection -* Use appropriate bucket policies for access control -* Always use HTTPS in production (e.g., `Endpoint: "https://s3.amazonaws.com"`) \ No newline at end of file +- Store credentials securely (environment variables, IAM roles, etc.) +- Use IAM policies to restrict bucket access (for AWS S3) +- Consider using temporary credentials for production +- Enable bucket versioning for data protection +- Use appropriate bucket policies for access control +- Always use HTTPS in production (e.g., `Endpoint: "https://s3.amazonaws.com"`) diff --git a/docs/docs/Developer Guide/Contributing.md b/docs/docs/Developer Guide/Contributing.md index c96a599d..d09613c7 100644 --- a/docs/docs/Developer Guide/Contributing.md +++ b/docs/docs/Developer Guide/Contributing.md @@ -1,4 +1,5 @@ -# Contributing +# Contributing + ## Contributing to ncps Thank you for your interest in contributing to ncps! This document provides guidelines and instructions for contributing to the project. @@ -9,36 +10,37 @@ Thank you for your interest in contributing to ncps! This document provides guid The project uses **Nix flakes** with **direnv** for reproducible development environments. You'll need: -1. **Nix with flakes enabled** - [Installation guide](https://nixos.org/download.html) -2. **direnv** - [Installation guide](https://direnv.net/docs/installation.html) +1. **Nix with flakes enabled** - [Installation guide](https://nixos.org/download.html) +1. **direnv** - [Installation guide](https://direnv.net/docs/installation.html) ### Initial Setup -1. **Clone the repository:** +1. **Clone the repository:** + + ```sh + git clone https://github.com/kalbasit/ncps.git + cd ncps + ``` - ```sh - git clone https://github.com/kalbasit/ncps.git - cd ncps - ``` -2. **Allow direnv:** +1. **Allow direnv:** - ```sh - direnv allow - ``` + ```sh + direnv allow + ``` - This will automatically load the development environment with all required tools: + This will automatically load the development environment with all required tools: - * Go - * golangci-lint - * sqlc - * dbmate - * delve (debugger) - * watchexec - * sqlfluff - * MinIO (for S3 testing) - * PostgreSQL (for database testing) - * MySQL/MariaDB (for database testing) - * Redis (for distributed locking testing) + - Go + - golangci-lint + - sqlc + - dbmate + - delve (debugger) + - watchexec + - sqlfluff + - MinIO (for S3 testing) + - PostgreSQL (for database testing) + - MySQL/MariaDB (for database testing) + - Redis (for distributed locking testing) ## Development Environment @@ -70,21 +72,21 @@ nix run .#deps This starts: -* **MinIO** - S3-compatible storage server (port 9000, console on 9001) - * Test bucket: `test-bucket` - * Credentials: `test-access-key` / `test-secret-key` - * Self-validation ensures proper setup -* **PostgreSQL** - Database server (port 5432) - * Test database: `test-db` - * Credentials: `test-user` / `test-password` - * Connection URL: `postgresql://test-user:test-password@127.0.0.1:5432/test-db?sslmode=disable` -* **MariaDB** - MySQL-compatible database server (port 3306) - * Test database: `test-db` - * Credentials: `test-user` / `test-password` - * Connection URL: `mysql://test-user:test-password@127.0.0.1:3306/test-db` -* **Redis** - Distributed locking server (port 6379) - * No authentication required (test environment) - * Used for distributed lock testing +- **MinIO** - S3-compatible storage server (port 9000, console on 9001) + - Test bucket: `test-bucket` + - Credentials: `test-access-key` / `test-secret-key` + - Self-validation ensures proper setup +- **PostgreSQL** - Database server (port 5432) + - Test database: `test-db` + - Credentials: `test-user` / `test-password` + - Connection URL: `postgresql://test-user:test-password@127.0.0.1:5432/test-db?sslmode=disable` +- **MariaDB** - MySQL-compatible database server (port 3306) + - Test database: `test-db` + - Credentials: `test-user` / `test-password` + - Connection URL: `mysql://test-user:test-password@127.0.0.1:3306/test-db` +- **Redis** - Distributed locking server (port 6379) + - No authentication required (test environment) + - Used for distributed lock testing ## Development Workflow @@ -112,23 +114,27 @@ The server automatically restarts when you modify code files. The documentation for this project is managed using Trilium. Follow these steps to contribute to the documentation: -1. **Run the documentation editor:** +1. **Run the documentation editor:** + + ```sh + trilium-edit-docs + ``` + + This tool is available in the `PATH` provided by the Nix flake, see [Development Environment in the Developer Guide](../Developer%20Guide.md) for more information. - ```sh - trilium-edit-docs - ``` +1. **Edit the documentation through Trilium:** The Trilium interface will open, allowing you to edit the notes. Trilium automatically exports the markdown files back to the repository as you make changes. - This tool is available in the `PATH` provided by the Nix flake, see [Development Environment in the Developer Guide](../Developer%20Guide.md) for more information. -2. **Edit the documentation through Trilium:** The Trilium interface will open, allowing you to edit the notes. Trilium automatically exports the markdown files back to the repository as you make changes. -3. **Wait and close:** Wait 5 minutes after you have finished all your edits to ensure all changes are synced, then close Trilium. -4. **Format the documentation:** +1. **Wait and close:** Wait 5 minutes after you have finished all your edits to ensure all changes are synced, then close Trilium. - Run the project formatter to ensure the markdown files follow the project's standards: +1. **Format the documentation:** - ```sh - nix fmt - ``` -5. **Submit your changes:** Submit a Pull Request with your changes. + Run the project formatter to ensure the markdown files follow the project's standards: + + ```sh + nix fmt + ``` + +1. **Submit your changes:** Submit a Pull Request with your changes. ### Database Migrations @@ -142,9 +148,9 @@ dbmate --migrations-dir db/migrations/mysql new migration_name The `dbmate` command is a wrapper that automatically: -* Detects database type from the URL scheme -* Selects the appropriate migrations directory (`db/migrations/sqlite/`, `db/migrations/postgres/`, or `db/migrations/mysql/`) -* Creates timestamped migration files +- Detects database type from the URL scheme +- Selects the appropriate migrations directory (`db/migrations/sqlite/`, `db/migrations/postgres/`, or `db/migrations/mysql/`) +- Creates timestamped migration files **Applying migrations:** @@ -166,9 +172,9 @@ sqlc generate This generates type-safe Go code from: -* `db/query.sqlite.sql` → `pkg/database/sqlitedb/` -* `db/query.postgres.sql` → `pkg/database/postgresdb/` -* `db/query.mysql.sql` → `pkg/database/mysqldb/` +- `db/query.sqlite.sql` → `pkg/database/sqlitedb/` +- `db/query.postgres.sql` → `pkg/database/postgresdb/` +- `db/query.mysql.sql` → `pkg/database/mysqldb/` ## Code Quality Standards @@ -183,13 +189,13 @@ nix fmt The project uses: -* **gofumpt** - Stricter Go formatting -* **goimports** - Import organization -* **gci** - Import grouping (standard → default → alias → localmodule) -* **nixfmt** - Nix code formatting -* **sqlfluff** - SQL formatting and linting -* **yamlfmt** - YAML formatting -* **mdformat** - Markdown formatting +- **gofumpt** - Stricter Go formatting +- **goimports** - Import organization +- **gci** - Import grouping (standard → default → alias → localmodule) +- **nixfmt** - Nix code formatting +- **sqlfluff** - SQL formatting and linting +- **yamlfmt** - YAML formatting +- **mdformat** - Markdown formatting ### Linting @@ -208,11 +214,11 @@ golangci-lint run ./pkg/server/... The project uses 30+ linters including: -* **err113** - Explicit error wrapping -* **exhaustive** - Exhaustive switch statements -* **gosec** - Security checks -* **paralleltest** - Parallel test detection -* **testpackage** - Test package naming +- **err113** - Explicit error wrapping +- **exhaustive** - Exhaustive switch statements +- **gosec** - Security checks +- **paralleltest** - Parallel test detection +- **testpackage** - Test package naming See `.golangci.yml` for complete linter configuration. @@ -300,28 +306,28 @@ eval "$(disable-integration-tests)" The helper commands output shell export statements that you evaluate in your current shell: -* `**enable-s3-tests**` exports: - * `NCPS_TEST_S3_BUCKET=test-bucket` - * `NCPS_TEST_S3_ENDPOINT=http://127.0.0.1:9000` - * `NCPS_TEST_S3_REGION=us-east-1` - * `NCPS_TEST_S3_ACCESS_KEY_ID=test-access-key` - * `NCPS_TEST_S3_SECRET_ACCESS_KEY=test-secret-key` -* `**enable-postgres-tests**` exports: - * `NCPS_TEST_POSTGRES_URL=postgresql://test-user:test-password@127.0.0.1:5432/test-db?sslmode=disable` -* `**enable-mysql-tests**` exports: - * `NCPS_TEST_MYSQL_URL=mysql://test-user:test-password@127.0.0.1:3306/test-db` -* `**enable-redis-tests**` exports: - * `NCPS_ENABLE_REDIS_TESTS=1` +- `**enable-s3-tests**` exports: + - `NCPS_TEST_S3_BUCKET=test-bucket` + - `NCPS_TEST_S3_ENDPOINT=http://127.0.0.1:9000` + - `NCPS_TEST_S3_REGION=us-east-1` + - `NCPS_TEST_S3_ACCESS_KEY_ID=test-access-key` + - `NCPS_TEST_S3_SECRET_ACCESS_KEY=test-secret-key` +- `**enable-postgres-tests**` exports: + - `NCPS_TEST_POSTGRES_URL=postgresql://test-user:test-password@127.0.0.1:5432/test-db?sslmode=disable` +- `**enable-mysql-tests**` exports: + - `NCPS_TEST_MYSQL_URL=mysql://test-user:test-password@127.0.0.1:3306/test-db` +- `**enable-redis-tests**` exports: + - `NCPS_ENABLE_REDIS_TESTS=1` Tests automatically skip if these environment variables aren't set, so you can run `go test -race ./...` without enabling integration tests and only unit tests will run. ### Test Requirements -* Use **testify** for assertions -* Enable race detector (`-race` flag) -* Use `_test` package suffix (enforced by `testpackage` linter) -* Write parallel tests where possible (checked by `paralleltest` linter) -* Each test should be isolated and not depend on other tests +- Use **testify** for assertions +- Enable race detector (`-race` flag) +- Use `_test` package suffix (enforced by `testpackage` linter) +- Write parallel tests where possible (checked by `paralleltest` linter) +- Each test should be isolated and not depend on other tests ### Nix Build Tests @@ -335,11 +341,11 @@ nix build The Nix build automatically: -1. Starts MinIO, PostgreSQL, MariaDB, and Redis in `preCheck` phase -2. Creates test databases and buckets -3. Exports test environment variables -4. Runs all tests (including integration tests) -5. Stops services in `postCheck` phase +1. Starts MinIO, PostgreSQL, MariaDB, and Redis in `preCheck` phase +1. Creates test databases and buckets +1. Exports test environment variables +1. Runs all tests (including integration tests) +1. Stops services in `postCheck` phase ### Helm Chart Testing @@ -347,10 +353,10 @@ The project includes comprehensive Helm chart testing using a local Kind cluster **Prerequisites:** -* Docker -* kubectl -* helm -* kind +- Docker +- kubectl +- helm +- kind **Setup (one-time):** @@ -396,15 +402,15 @@ DOCKER_IMAGE_TAGS="yourregistry.com/ncps:sha$(git rev-parse --short HEAD)" nix r The generate-test-values.sh script creates 10 different test configurations: -* **Single Instance with Local Storage:** - * SQLite, PostgreSQL, or MariaDB database -* **Single Instance with S3 Storage:** - * SQLite, PostgreSQL, or MariaDB database - * Tests S3 configuration and MinIO compatibility -* **High Availability:** - * 2 replicas with S3 storage - * PostgreSQL or MariaDB database - * Redis for distributed locking +- **Single Instance with Local Storage:** + - SQLite, PostgreSQL, or MariaDB database +- **Single Instance with S3 Storage:** + - SQLite, PostgreSQL, or MariaDB database + - Tests S3 configuration and MinIO compatibility +- **High Availability:** + - 2 replicas with S3 storage + - PostgreSQL or MariaDB database + - Redis for distributed locking **Testing Individual Deployments:** @@ -446,61 +452,68 @@ helm upgrade --install ncps-single-local-postgres . \ ### Before Submitting -1. **Format your code:** +1. **Format your code:** + + ``` + nix fmt + ``` - ``` - nix fmt - ``` -2. **Fix linting issues:** +1. **Fix linting issues:** - ``` - golangci-lint run --fix - ``` -3. **Run tests:** + ``` + golangci-lint run --fix + ``` - ``` - go test -race ./... - ``` -4. **Build successfully:** +1. **Run tests:** - ``` - nix build - ``` + ``` + go test -race ./... + ``` + +1. **Build successfully:** + + ``` + nix build + ``` ### Commit Guidelines -* Use clear, descriptive commit messages -* Follow [Conventional Commits](https://www.conventionalcommits.org/) when possible: - * `feat:` - New features - * `fix:` - Bug fixes - * `docs:` - Documentation changes - * `refactor:` - Code refactoring - * `test:` - Test additions/changes - * `chore:` - Build/tooling changes +- Use clear, descriptive commit messages +- Follow [Conventional Commits](https://www.conventionalcommits.org/) when possible: + - `feat:` - New features + - `fix:` - Bug fixes + - `docs:` - Documentation changes + - `refactor:` - Code refactoring + - `test:` - Test additions/changes + - `chore:` - Build/tooling changes ### Pull Request Guidelines -1. **Create a feature branch:** +1. **Create a feature branch:** + + ``` + git checkout -b feature/your-feature-name + ``` + +1. **Make your changes** following code quality standards + +1. **Update documentation** if needed (README.md, CLAUDE.md, etc.) + +1. **Add tests** for new functionality - ``` - git checkout -b feature/your-feature-name - ``` -2. **Make your changes** following code quality standards -3. **Update documentation** if needed (README.md, CLAUDE.md, etc.) -4. **Add tests** for new functionality -5. **Submit PR** with: +1. **Submit PR** with: - * Clear description of changes - * Reference to related issues - * Screenshots/examples if applicable + - Clear description of changes + - Reference to related issues + - Screenshots/examples if applicable ### CI/CD Notes The project uses GitHub Actions for CI/CD: -* Workflows only run on PRs targeting `main` branch -* This supports Graphite-style stacked PRs efficiently -* When modifying workflows, maintain the `branches: [main]` restriction +- Workflows only run on PRs targeting `main` branch +- This supports Graphite-style stacked PRs efficiently +- When modifying workflows, maintain the `branches: [main]` restriction ## Project Structure @@ -545,24 +558,24 @@ ncps/ **Storage (**`**pkg/storage/store.go**`**):** -* `ConfigStore` - Secret key storage -* `NarInfoStore` - NarInfo metadata storage -* `NarStore` - NAR file storage +- `ConfigStore` - Secret key storage +- `NarInfoStore` - NarInfo metadata storage +- `NarStore` - NAR file storage Both local and S3 backends implement these interfaces. **Locks (**`**pkg/lock/lock.go**`**):** -* `Locker` - Exclusive locking for download deduplication -* `RWLocker` - Read-write locking for LRU coordination +- `Locker` - Exclusive locking for download deduplication +- `RWLocker` - Read-write locking for LRU coordination Both local (sync.Mutex) and Redis (Redlock) backends implement these interfaces. Redis locks enable high-availability deployments with multiple instances. **Database:** -* Supports SQLite, PostgreSQL, and MySQL via sqlc -* Database selection via URL scheme in `--cache-database-url` -* Type-safe queries generated from `db/query.*.sql` files +- Supports SQLite, PostgreSQL, and MySQL via sqlc +- Database selection via URL scheme in `--cache-database-url` +- Type-safe queries generated from `db/query.*.sql` files ## Common Development Tasks @@ -602,9 +615,9 @@ dbmate --url "mysql://..." up Edit the appropriate query file: -* db/query.sqlite.sql (SQLite-specific queries) -* db/query.postgres.sql (PostgreSQL-specific queries) -* db/query.mysql.sql (MySQL-specific queries) +- db/query.sqlite.sql (SQLite-specific queries) +- db/query.postgres.sql (PostgreSQL-specific queries) +- db/query.mysql.sql (MySQL-specific queries) ### Generating SQL Code @@ -617,23 +630,23 @@ go generate ./pkg/database This generates type-safe Go code from: -* `db/query.sqlite.sql` → `pkg/database/sqlitedb/` -* `db/query.postgres.sql` → `pkg/database/postgresdb/` -* `db/query.mysql.sql` → `pkg/database/mysqldb/` +- `db/query.sqlite.sql` → `pkg/database/sqlitedb/` +- `db/query.postgres.sql` → `pkg/database/postgresdb/` +- `db/query.mysql.sql` → `pkg/database/mysqldb/` And automatically updates: -* `pkg/database/querier.go` (Common interface) -* `pkg/database/models.go` (Common models) -* `pkg/database/wrapper_*.go` (Engine adaptors) +- `pkg/database/querier.go` (Common interface) +- `pkg/database/models.go` (Common models) +- `pkg/database/wrapper_*.go` (Engine adaptors) ### Adding a New Storage Backend -1. Implement the storage interfaces in `pkg/storage/` -2. Add configuration flags in `cmd/serve.go` -3. Update documentation in README.md and CLAUDE.md -4. Add integration tests -5. Update Docker and Kubernetes examples if applicable +1. Implement the storage interfaces in `pkg/storage/` +1. Add configuration flags in `cmd/serve.go` +1. Update documentation in README.md and CLAUDE.md +1. Add integration tests +1. Update Docker and Kubernetes examples if applicable ### Debugging @@ -664,22 +677,22 @@ DOCKER_IMAGE_TAGS="kalbasit/ncps:latest kalbasit/ncps:v1.0.0" nix run .#push-doc ## Getting Help -* **Documentation Issues:** Check CLAUDE.md for detailed development guidance -* **Bug Reports:** [Open an issue](https://github.com/kalbasit/ncps/issues) -* **Questions:** [Start a discussion](https://github.com/kalbasit/ncps/discussions) -* **Security Issues:** Contact maintainers privately +- **Documentation Issues:** Check CLAUDE.md for detailed development guidance +- **Bug Reports:** [Open an issue](https://github.com/kalbasit/ncps/issues) +- **Questions:** [Start a discussion](https://github.com/kalbasit/ncps/discussions) +- **Security Issues:** Contact maintainers privately ## Code of Conduct -* Be respectful and inclusive -* Provide constructive feedback -* Focus on what's best for the project -* Show empathy towards other contributors +- Be respectful and inclusive +- Provide constructive feedback +- Focus on what's best for the project +- Show empathy towards other contributors ## License By contributing to ncps, you agree that your contributions will be licensed under the MIT License. ---- +______________________________________________________________________ -Thank you for contributing to ncps! 🎉 \ No newline at end of file +Thank you for contributing to ncps! 🎉 diff --git a/docs/docs/Developer Guide/Testing.md b/docs/docs/Developer Guide/Testing.md index ef785753..fce1edc1 100644 --- a/docs/docs/Developer Guide/Testing.md +++ b/docs/docs/Developer Guide/Testing.md @@ -1,4 +1,5 @@ -# Testing +# Testing + ## Testing Guide Testing procedures and integration test setup. @@ -38,12 +39,12 @@ eval "$(disable-integration-tests)" **Available helpers:** -* `enable-s3-tests` - S3/MinIO tests -* `enable-postgres-tests` - PostgreSQL tests -* `enable-mysql-tests` - MySQL tests -* `enable-redis-tests` - Redis lock tests -* `enable-integration-tests` - All integration tests -* `disable-integration-tests` - Disable all +- `enable-s3-tests` - S3/MinIO tests +- `enable-postgres-tests` - PostgreSQL tests +- `enable-mysql-tests` - MySQL tests +- `enable-redis-tests` - Redis lock tests +- `enable-integration-tests` - All integration tests +- `disable-integration-tests` - Disable all ### CI/CD Testing @@ -55,9 +56,9 @@ nix flake check This automatically: -1. Starts all dependencies (MinIO, PostgreSQL, MariaDB, Redis) -2. Runs all tests including integration tests -3. Stops all services +1. Starts all dependencies (MinIO, PostgreSQL, MariaDB, Redis) +1. Runs all tests including integration tests +1. Stops all services ## Test Structure @@ -115,11 +116,11 @@ golangci-lint run path/to/file.go **Key linters:** -* err113 - Error handling -* exhaustive - Switch exhaustiveness -* gosec - Security -* paralleltest - Parallel testing -* testpackage - Test package naming +- err113 - Error handling +- exhaustive - Switch exhaustiveness +- gosec - Security +- paralleltest - Parallel testing +- testpackage - Test package naming ## Code Formatting @@ -152,5 +153,5 @@ go tool cover -html=coverage.out ## Related Documentation -* Contributing - Contribution guidelines -* Developer Guide - Development environment guide \ No newline at end of file +- Contributing - Contribution guidelines +- Developer Guide - Development environment guide diff --git a/docs/docs/User Guide.md b/docs/docs/User Guide.md index 2c27189c..ea11a0c5 100644 --- a/docs/docs/User Guide.md +++ b/docs/docs/User Guide.md @@ -1,4 +1,5 @@ -# User Guide +# User Guide + ## ncps Documentation Welcome to the comprehensive documentation for ncps (Nix Cache Proxy Server). This documentation is organized to help you quickly find the information you need, whether you're just getting started or managing a production deployment. @@ -22,60 +23,60 @@ Welcome to the comprehensive documentation for ncps (Nix Cache Proxy Server). Th **Get Started** -* [Run ncps for the first time](User%20Guide/Getting%20Started/Quick%20Start.md) -* [Understand how ncps works](User%20Guide/Getting%20Started/Concepts.md) -* [Choose the right deployment method](User%20Guide/Installation.md) +- [Run ncps for the first time](User%20Guide/Getting%20Started/Quick%20Start.md) +- [Understand how ncps works](User%20Guide/Getting%20Started/Concepts.md) +- [Choose the right deployment method](User%20Guide/Installation.md) **Install ncps** -* [Install with Docker](User%20Guide/Installation/Docker.md) -* [Install with Docker Compose](User%20Guide/Installation/Docker%20Compose.md) -* [Deploy on Kubernetes](User%20Guide/Installation/Kubernetes.md) -* [Use the Helm chart](User%20Guide/Installation/Helm%20Chart.md) -* [Configure on NixOS](User%20Guide/Installation/NixOS.md) +- [Install with Docker](User%20Guide/Installation/Docker.md) +- [Install with Docker Compose](User%20Guide/Installation/Docker%20Compose.md) +- [Deploy on Kubernetes](User%20Guide/Installation/Kubernetes.md) +- [Use the Helm chart](User%20Guide/Installation/Helm%20Chart.md) +- [Configure on NixOS](User%20Guide/Installation/NixOS.md) **Configure ncps** -* [See all configuration options](User%20Guide/Configuration/Reference.md) -* [Configure storage backends](User%20Guide/Configuration/Storage.md) -* [Choose and configure a database](User%20Guide/Configuration/Database.md) -* [Configure analytics reporting](User%20Guide/Configuration/Analytics.md) -* [Set up observability](User%20Guide/Configuration/Observability.md) +- [See all configuration options](User%20Guide/Configuration/Reference.md) +- [Configure storage backends](User%20Guide/Configuration/Storage.md) +- [Choose and configure a database](User%20Guide/Configuration/Database.md) +- [Configure analytics reporting](User%20Guide/Configuration/Analytics.md) +- [Set up observability](User%20Guide/Configuration/Observability.md) **Deploy for Production** -* [Deploy a single instance](User%20Guide/Deployment/Single%20Instance.md) -* [Set up high availability](User%20Guide/Deployment/High%20Availability.md) -* [Configure distributed locking](User%20Guide/Deployment/Distributed%20Locking.md) +- [Deploy a single instance](User%20Guide/Deployment/Single%20Instance.md) +- [Set up high availability](User%20Guide/Deployment/High%20Availability.md) +- [Configure distributed locking](User%20Guide/Deployment/Distributed%20Locking.md) **Use ncps** -* [Configure Nix clients](User%20Guide/Usage/Client%20Setup.md) -* [Manage the cache](User%20Guide/Usage/Cache%20Management.md) +- [Configure Nix clients](User%20Guide/Usage/Client%20Setup.md) +- [Manage the cache](User%20Guide/Usage/Cache%20Management.md) **Operate and Maintain** -* [Monitor ncps](User%20Guide/Operations/Monitoring.md) -* [Troubleshoot issues](User%20Guide/Operations/Troubleshooting.md) -* [Backup and restore](User%20Guide/Operations/Backup%20Restore.md) -* [Upgrade ncps](User%20Guide/Operations/Upgrading.md) +- [Monitor ncps](User%20Guide/Operations/Monitoring.md) +- [Troubleshoot issues](User%20Guide/Operations/Troubleshooting.md) +- [Backup and restore](User%20Guide/Operations/Backup%20Restore.md) +- [Upgrade ncps](User%20Guide/Operations/Upgrading.md) **Understand Internals** -* [Learn about system components](Developer%20Guide/Architecture/Components.md) -* [Understand storage backends](Developer%20Guide/Architecture/Storage%20Backends.md) -* [Helm Chart Documentation](User%20Guide/Installation/Helm%20Chart/Chart%20Reference.md) - Comprehensive Helm chart reference -* [Follow request flow](Developer%20Guide/Architecture/Request%20Flow.md) -* [Set up development environment](Developer%20Guide.md) -* [See contribution guidelines](Developer%20Guide/Contributing.md) +- [Learn about system components](Developer%20Guide/Architecture/Components.md) +- [Understand storage backends](Developer%20Guide/Architecture/Storage%20Backends.md) +- [Helm Chart Documentation](User%20Guide/Installation/Helm%20Chart/Chart%20Reference.md) - Comprehensive Helm chart reference +- [Follow request flow](Developer%20Guide/Architecture/Request%20Flow.md) +- [Set up development environment](Developer%20Guide.md) +- [See contribution guidelines](Developer%20Guide/Contributing.md) ## Additional Resources -* [Helm Chart Documentation](User%20Guide/Installation/Helm%20Chart/Chart%20Reference.md) - Comprehensive Helm chart reference -* [See contribution guidelines](Developer%20Guide/Contributing.md) - Development and contribution guidelines -* [Configuration Example](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) - Complete configuration file example -* [**GitHub Issues**](https://github.com/kalbasit/ncps/issues) - Report bugs and request features -* [**Discussions**](https://github.com/kalbasit/ncps/discussions) - Ask questions and share ideas +- [Helm Chart Documentation](User%20Guide/Installation/Helm%20Chart/Chart%20Reference.md) - Comprehensive Helm chart reference +- [See contribution guidelines](Developer%20Guide/Contributing.md) - Development and contribution guidelines +- [Configuration Example](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) - Complete configuration file example +- [**GitHub Issues**](https://github.com/kalbasit/ncps/issues) - Report bugs and request features +- [**Discussions**](https://github.com/kalbasit/ncps/discussions) - Ask questions and share ideas ## Documentation Versions @@ -85,11 +86,11 @@ This documentation is for the latest version of ncps. For version-specific docum Found an error or want to improve the documentation? Contributions are welcome! -1. Documentation source files are in the `/docs` directory -2. Submit pull requests with improvements -3. Follow the existing structure and style -4. See Contributing for guidelines +1. Documentation source files are in the `/docs` directory +1. Submit pull requests with improvements +1. Follow the existing structure and style +1. See Contributing for guidelines ---- +______________________________________________________________________ -**Need Help?** Check the Troubleshooting or ask in [Discussions](https://github.com/kalbasit/ncps/discussions). \ No newline at end of file +**Need Help?** Check the Troubleshooting or ask in [Discussions](https://github.com/kalbasit/ncps/discussions). diff --git a/docs/docs/User Guide/Configuration.md b/docs/docs/User Guide/Configuration.md index 5953474e..97237002 100644 --- a/docs/docs/User Guide/Configuration.md +++ b/docs/docs/User Guide/Configuration.md @@ -1,15 +1,16 @@ -# Configuration +# Configuration + ## Configuration Guide Learn how to configure ncps for your specific needs. ## Configuration Files -* Reference - Complete reference of all configuration options -* Storage - Configure local or S3 storage backends -* Database - Configure SQLite, PostgreSQL, or MySQL -* Analytics - Configure anonymous usage statistics reporting -* Observability - Set up metrics, logging, and tracing +- Reference - Complete reference of all configuration options +- Storage - Configure local or S3 storage backends +- Database - Configure SQLite, PostgreSQL, or MySQL +- Analytics - Configure anonymous usage statistics reporting +- Observability - Set up metrics, logging, and tracing ## Quick Links @@ -17,39 +18,39 @@ Learn how to configure ncps for your specific needs. **Getting Started** -* [All configuration options](Configuration/Reference.md) -* [Example Configuration](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) +- [All configuration options](Configuration/Reference.md) +- [Example Configuration](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) **Storage** -* Local Filesystem Storage -* S3-Compatible Storage -* Storage Comparison +- Local Filesystem Storage +- S3-Compatible Storage +- Storage Comparison **Database** -* SQLite Configuration -* PostgreSQL Configuration -* MySQL/MariaDB Configuration -* [Database Migrations](Configuration/Database/Migration%20Between%20Databases.md) +- SQLite Configuration +- PostgreSQL Configuration +- MySQL/MariaDB Configuration +- [Database Migrations](Configuration/Database/Migration%20Between%20Databases.md) **Observability** -* [Prometheus Metrics](Configuration/Observability.md) -* [Logging Setup](Configuration/Observability.md) -* [Tracing Setup](Configuration/Observability.md) +- [Prometheus Metrics](Configuration/Observability.md) +- [Logging Setup](Configuration/Observability.md) +- [Tracing Setup](Configuration/Observability.md) **Privacy & Analytics** -* [Analytics Overview](Configuration/Analytics.md) -* [Data Collection](Configuration/Analytics.md) -* [Opt-out Guide](Configuration/Analytics.md) +- [Analytics Overview](Configuration/Analytics.md) +- [Data Collection](Configuration/Analytics.md) +- [Opt-out Guide](Configuration/Analytics.md) ## Configuration Methods ncps supports multiple ways to configure the service: -### 1\. Command-line Flags +### 1. Command-line Flags ```sh ncps serve \ @@ -60,7 +61,7 @@ ncps serve \ --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ``` -### 2\. Environment Variables +### 2. Environment Variables ```sh export CACHE_HOSTNAME=cache.example.com @@ -72,7 +73,7 @@ export CACHE_UPSTREAM_PUBLIC_KEYS=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ1 ncps serve ``` -### 3\. Configuration File +### 3. Configuration File Create `config.yaml`: @@ -97,20 +98,20 @@ ncps serve --config=config.yaml **Supported formats:** -* YAML (`.yaml`, `.yml`) -* TOML (`.toml`) -* JSON (`.json`) +- YAML (`.yaml`, `.yml`) +- TOML (`.toml`) +- JSON (`.json`) See [Example Configuration](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) for a complete example. -### 4\. Combination +### 4. Combination Configuration methods can be combined. Priority (highest to lowest): -1. Command-line flags -2. Environment variables -3. Configuration file -4. Defaults +1. Command-line flags +1. Environment variables +1. Configuration file +1. Defaults ## Common Configuration Scenarios @@ -190,19 +191,19 @@ cache: These must be set for ncps to start: -* `cache.hostname` - Hostname for key generation -* Storage backend (choose one): - * `cache.storage.local` OR - * `cache.storage.s3.*` (bucket, endpoint, credentials) -* `cache.upstream.urls` - At least one upstream cache -* `cache.upstream.public-keys` - Corresponding public keys +- `cache.hostname` - Hostname for key generation +- Storage backend (choose one): + - `cache.storage.local` OR + - `cache.storage.s3.*` (bucket, endpoint, credentials) +- `cache.upstream.urls` - At least one upstream cache +- `cache.upstream.public-keys` - Corresponding public keys ### Optional But Recommended -* `cache.max-size` - Prevent unbounded cache growth -* `cache.lru.schedule` - Automatic cleanup -* `prometheus.enabled` - Metrics for monitoring -* `cache.database-url` - For shared database (default: embedded SQLite) +- `cache.max-size` - Prevent unbounded cache growth +- `cache.lru.schedule` - Automatic cleanup +- `prometheus.enabled` - Metrics for monitoring +- `cache.database-url` - For shared database (default: embedded SQLite) ## Validation @@ -218,13 +219,13 @@ ncps serve --config=config.yaml --log-level=debug ## Next Steps -1. Reference - See all available options -2. Storage - Choose and configure storage backend -3. Database - Choose and configure database -4. Observability - Set up monitoring +1. Reference - See all available options +1. Storage - Choose and configure storage backend +1. Database - Choose and configure database +1. Observability - Set up monitoring ## Related Documentation -* [Example configuration file](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) - Complete configuration example -* [Installation Guides](Installation.md) - Installation-specific configuration -* [Observability Configuration](Configuration/Observability.md) - Observability-specific configuration \ No newline at end of file +- [Example configuration file](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) - Complete configuration example +- [Installation Guides](Installation.md) - Installation-specific configuration +- [Observability Configuration](Configuration/Observability.md) - Observability-specific configuration diff --git a/docs/docs/User Guide/Configuration/Analytics.md b/docs/docs/User Guide/Configuration/Analytics.md index 845201cb..717235f2 100644 --- a/docs/docs/User Guide/Configuration/Analytics.md +++ b/docs/docs/User Guide/Configuration/Analytics.md @@ -1,4 +1,5 @@ -# Analytics +# Analytics + ## Analytics Reporting Configure anonymous usage statistics reporting to help improve ncps. @@ -9,16 +10,16 @@ ncps includes an optional analytics reporting system that collects anonymous usa **Key Points:** -* **Enabled by default** - Can be disabled with `--analytics-reporting-enabled=false` -* **Fully anonymous** - No personal data, IP addresses, or cache contents -* **Minimal overhead** - Metrics sent once per hour, logs only on startup and errors -* **Privacy-focused** - Only collects configuration metadata and aggregate statistics +- **Enabled by default** - Can be disabled with `--analytics-reporting-enabled=false` +- **Fully anonymous** - No personal data, IP addresses, or cache contents +- **Minimal overhead** - Metrics sent once per hour, logs only on startup and errors +- **Privacy-focused** - Only collects configuration metadata and aggregate statistics ## What Data is Collected? Analytics reporting collects three types of data: -### 1\. Resource Attributes (Metadata) +### 1. Resource Attributes (Metadata) These attributes are attached to all metrics and logs: @@ -32,7 +33,7 @@ These attributes are attached to all metrics and logs: **Note:** The `cluster_uuid` is randomly generated and stored in your database. It helps identify unique installations but contains no identifying information about your organization or infrastructure. -### 2\. Metrics (Sent Hourly) +### 2. Metrics (Sent Hourly) Aggregate statistics about cache usage: @@ -44,7 +45,7 @@ Aggregate statistics about cache usage: These metrics are sent every **1 hour** to minimize network overhead. -### 3\. Logs +### 3. Logs Event logs for application lifecycle: @@ -59,14 +60,14 @@ Event logs for application lifecycle: Analytics reporting explicitly **does not** collect: -* **Personal information** - No usernames, emails, or other PII -* **Network information** - No IP addresses, hostnames, or network topology -* **Host information** - No hostname or process owner user -* **Cache contents** - No store paths, package names, or derivation data -* **Configuration secrets** - No passwords, keys, or authentication tokens -* **Request logs** - No HTTP requests, client information, or access patterns -* **Storage paths** - No file paths, bucket names, or storage configuration -* **Upstream URLs** - No upstream cache URLs or authentication details +- **Personal information** - No usernames, emails, or other PII +- **Network information** - No IP addresses, hostnames, or network topology +- **Host information** - No hostname or process owner user +- **Cache contents** - No store paths, package names, or derivation data +- **Configuration secrets** - No passwords, keys, or authentication tokens +- **Request logs** - No HTTP requests, client information, or access patterns +- **Storage paths** - No file paths, bucket names, or storage configuration +- **Upstream URLs** - No upstream cache URLs or authentication details ## Analytics Endpoint @@ -78,9 +79,9 @@ otlp.ncps.dev:443 This endpoint receives OpenTelemetry data over HTTPS using: -* **OTLP/HTTP** protocol -* **gzip compression** to minimize bandwidth -* **TLS encryption** for secure transmission +- **OTLP/HTTP** protocol +- **gzip compression** to minimize bandwidth +- **TLS encryption** for secure transmission ## Privacy and Security @@ -88,8 +89,8 @@ This endpoint receives OpenTelemetry data over HTTPS using: Analytics data is retained for: -* **Metrics**: 90 days (for trend analysis) -* **Logs**: 30 days (for bug identification) +- **Metrics**: 90 days (for trend analysis) +- **Logs**: 30 days (for bug identification) After this period, data is automatically deleted. @@ -97,25 +98,25 @@ After this period, data is automatically deleted. Analytics data is used exclusively for: -* Understanding deployment patterns (database types, HA vs single-instance) -* Identifying common cache sizes to inform default configurations -* Detecting bugs through panic logs -* Measuring upstream health trends -* Planning future development priorities +- Understanding deployment patterns (database types, HA vs single-instance) +- Identifying common cache sizes to inform default configurations +- Detecting bugs through panic logs +- Measuring upstream health trends +- Planning future development priorities Analytics data is **never**: -* Sold to third parties -* Used for advertising or tracking -* Shared outside the ncps project maintainers -* Used to identify individual users or organizations +- Sold to third parties +- Used for advertising or tracking +- Shared outside the ncps project maintainers +- Used to identify individual users or organizations ### Security -* All data transmission uses TLS encryption -* No authentication tokens or credentials are collected -* Panic logs are sanitized to remove environment variables -* The cluster UUID is randomly generated and cannot be traced back to your organization +- All data transmission uses TLS encryption +- No authentication tokens or credentials are collected +- Panic logs are sanitized to remove environment variables +- The cluster UUID is randomly generated and cannot be traced back to your organization ## Configuration @@ -220,16 +221,16 @@ One of the key features of the analytics system is **panic recovery** for backgr ncps uses `analytics.SafeGo()` to wrap all background goroutines with panic recovery. When a panic occurs: -1. **Panic is caught** - The goroutine doesn't crash the entire application -2. **Stack trace is captured** - Full stack trace for debugging -3. **Logged locally** - Panic is logged to application logs (always, regardless of analytics setting) -4. **Reported to analytics** - If analytics is enabled, panic is sent to maintainers +1. **Panic is caught** - The goroutine doesn't crash the entire application +1. **Stack trace is captured** - Full stack trace for debugging +1. **Logged locally** - Panic is logged to application logs (always, regardless of analytics setting) +1. **Reported to analytics** - If analytics is enabled, panic is sent to maintainers This ensures that: -* Your ncps instance stays running even if a background operation fails -* Bugs are reported to maintainers automatically (if analytics enabled) -* You have local logs for your own troubleshooting +- Your ncps instance stays running even if a background operation fails +- Bugs are reported to maintainers automatically (if analytics enabled) +- You have local logs for your own troubleshooting ### Example Panic Log @@ -246,15 +247,15 @@ This ensures that: **Analytics log (if enabled):** -Includes the same information plus resource attributes (service version, db\_type, etc.) to help maintainers identify patterns. +Includes the same information plus resource attributes (service version, db_type, etc.) to help maintainers identify patterns. ### SafeGo Usage When analytics is enabled, the following operations use `SafeGo()` for panic protection: -* **LRU cleanup** - Background cache eviction operations -* **Health checks** - Upstream cache health monitoring -* **Metrics collection** - Periodic statistics gathering +- **LRU cleanup** - Background cache eviction operations +- **Health checks** - Upstream cache health monitoring +- **Metrics collection** - Periodic statistics gathering ## Troubleshooting @@ -262,34 +263,37 @@ When analytics is enabled, the following operations use `SafeGo()` for panic pro If you expect analytics to be enabled but don't see the startup message: -1. **Check the flag value:** +1. **Check the flag value:** + + ``` + ncps serve --help | grep analytics + ``` + +1. **Verify environment variables:** + + ``` + echo $ANALYTICS_REPORTING_ENABLED + ``` - ``` - ncps serve --help | grep analytics - ``` -2. **Verify environment variables:** +1. **Check configuration file:** - ``` - echo $ANALYTICS_REPORTING_ENABLED - ``` -3. **Check configuration file:** + ``` + cat config.yaml | grep -A 3 analytics + ``` - ``` - cat config.yaml | grep -A 3 analytics - ``` -4. **Check for errors in logs:** +1. **Check for errors in logs:** - ``` - journalctl -u ncps | grep -i analytics - ``` + ``` + journalctl -u ncps | grep -i analytics + ``` ### Network Issues If analytics fails to connect to `otlp.ncps.dev:443`: -* **Firewall** - Ensure outbound HTTPS (port 443) is allowed -* **Proxy** - OpenTelemetry respects HTTP proxy environment variables -* **DNS** - Verify `otlp.ncps.dev` resolves correctly +- **Firewall** - Ensure outbound HTTPS (port 443) is allowed +- **Proxy** - OpenTelemetry respects HTTP proxy environment variables +- **DNS** - Verify `otlp.ncps.dev` resolves correctly Analytics failures are **non-fatal** - if the analytics endpoint is unreachable, ncps will log a warning but continue operating normally. @@ -345,10 +349,10 @@ See Observability for de Analytics is enabled by default because: -1. **Low overhead** - Minimal network usage (1 request per hour) -2. **Privacy-focused** - No sensitive data collection -3. **Helpful to maintainers** - Informs development priorities -4. **Easy opt-out** - Single flag to disable +1. **Low overhead** - Minimal network usage (1 request per hour) +1. **Privacy-focused** - No sensitive data collection +1. **Helpful to maintainers** - Informs development priorities +1. **Easy opt-out** - Single flag to disable This follows the model of other privacy-respecting open source projects like Homebrew, which collect anonymous statistics to understand usage patterns without compromising user privacy. @@ -358,17 +362,17 @@ This follows the model of other privacy-respecting open source projects like Hom No. Analytics has negligible performance impact: -* Metrics sent once per hour (not per request) -* Uses background goroutines (non-blocking) -* Compressed data (minimal bandwidth) +- Metrics sent once per hour (not per request) +- Uses background goroutines (non-blocking) +- Compressed data (minimal bandwidth) ### What if the analytics endpoint is down? If `otlp.ncps.dev` is unreachable: -* ncps logs a warning but continues operating -* No retries or queuing (to avoid memory buildup) -* Analytics automatically resumes when endpoint is available +- ncps logs a warning but continues operating +- No retries or queuing (to avoid memory buildup) +- Analytics automatically resumes when endpoint is available ### Can I host my own analytics collector? @@ -378,23 +382,23 @@ Not currently. The analytics endpoint is hardcoded to `otlp.ncps.dev:443`. If yo Unlike telemetry systems that collect invasive data, ncps analytics: -* **Is transparent** - This documentation explains exactly what's collected -* **Is minimal** - Only configuration metadata and aggregate statistics -* **Is optional** - Easy one-flag opt-out -* **Respects privacy** - No PII, IP addresses, or tracking -* **Has retention limits** - Data automatically deleted after 30-90 days -* **Is open source** - You can review the code in `pkg/analytics/` +- **Is transparent** - This documentation explains exactly what's collected +- **Is minimal** - Only configuration metadata and aggregate statistics +- **Is optional** - Easy one-flag opt-out +- **Respects privacy** - No PII, IP addresses, or tracking +- **Has retention limits** - Data automatically deleted after 30-90 days +- **Is open source** - You can review the code in `pkg/analytics/` ## Related Documentation -* Reference - All configuration options -* Observability - OpenTelemetry and Prometheus +- Reference - All configuration options +- Observability - OpenTelemetry and Prometheus ## Feedback Have questions or concerns about analytics? Please: -* Open an issue: [github.com/kalbasit/ncps/issues](https://github.com/kalbasit/ncps/issues) -* Start a discussion: [github.com/kalbasit/ncps/discussions](https://github.com/kalbasit/ncps/discussions) +- Open an issue: [github.com/kalbasit/ncps/issues](https://github.com/kalbasit/ncps/issues) +- Start a discussion: [github.com/kalbasit/ncps/discussions](https://github.com/kalbasit/ncps/discussions) -Your feedback helps us balance transparency, privacy, and useful data collection. \ No newline at end of file +Your feedback helps us balance transparency, privacy, and useful data collection. diff --git a/docs/docs/User Guide/Configuration/Database.md b/docs/docs/User Guide/Configuration/Database.md index 053a82a9..496231a0 100644 --- a/docs/docs/User Guide/Configuration/Database.md +++ b/docs/docs/User Guide/Configuration/Database.md @@ -1,4 +1,5 @@ -# Database +# Database + ## Database Configuration Configure ncps database backends: SQLite, PostgreSQL, or MySQL/MariaDB. @@ -7,9 +8,9 @@ Configure ncps database backends: SQLite, PostgreSQL, or MySQL/MariaDB. ncps supports three database backends for storing metadata (NarInfo, cache statistics, etc.): -* **SQLite**: Embedded database, no external dependencies -* **PostgreSQL**: Production-ready, concurrent access support -* **MySQL/MariaDB**: Production-ready, concurrent access support +- **SQLite**: Embedded database, no external dependencies +- **PostgreSQL**: Production-ready, concurrent access support +- **MySQL/MariaDB**: Production-ready, concurrent access support ## Quick Comparison @@ -24,13 +25,13 @@ ncps supports three database backends for storing metadata (NarInfo, cache stati ## Next Steps -1. [Storage Configuration](Storage.md) - Configure storage backend -2. [Configuration Reference](Reference.md) - All database options -3. High Availability - PostgreSQL/MySQL for HA -4. [Operations Guide](../Operations/Backup%20Restore.md) - Backup strategies +1. [Storage Configuration](Storage.md) - Configure storage backend +1. [Configuration Reference](Reference.md) - All database options +1. High Availability - PostgreSQL/MySQL for HA +1. [Operations Guide](../Operations/Backup%20Restore.md) - Backup strategies ## Related Documentation -* [Configuration Reference](Reference.md) - All configuration options -* [High Availability Guide](../Deployment/High%20Availability.md) - HA database setup -* [Backup and Restore Guide](../Operations/Backup%20Restore.md) - Backup strategies \ No newline at end of file +- [Configuration Reference](Reference.md) - All configuration options +- [High Availability Guide](../Deployment/High%20Availability.md) - HA database setup +- [Backup and Restore Guide](../Operations/Backup%20Restore.md) - Backup strategies diff --git a/docs/docs/User Guide/Configuration/Database/Migration Between Databases.md b/docs/docs/User Guide/Configuration/Database/Migration Between Databases.md index 35ac04a3..3619fe6d 100644 --- a/docs/docs/User Guide/Configuration/Database/Migration Between Databases.md +++ b/docs/docs/User Guide/Configuration/Database/Migration Between Databases.md @@ -1,4 +1,5 @@ -# Migration Between Databases +# Migration Between Databases + ### From SQLite to PostgreSQL ``` @@ -26,6 +27,6 @@ pgloader sqlite:///var/lib/ncps/db/db.sqlite \ Similar process using tools like: -* `sqlite3mysql` utility -* Manual export and conversion -* Custom migration scripts \ No newline at end of file +- `sqlite3mysql` utility +- Manual export and conversion +- Custom migration scripts diff --git a/docs/docs/User Guide/Configuration/Database/MySQLMariaDB Configuration.md b/docs/docs/User Guide/Configuration/Database/MySQLMariaDB Configuration.md index d5df5ed3..1647611f 100644 --- a/docs/docs/User Guide/Configuration/Database/MySQLMariaDB Configuration.md +++ b/docs/docs/User Guide/Configuration/Database/MySQLMariaDB Configuration.md @@ -1,15 +1,16 @@ -# MySQL/MariaDB Configuration +# MySQL/MariaDB Configuration + ### When to Use -* Same use cases as PostgreSQL -* Existing MySQL infrastructure -* Familiarity with MySQL ecosystem +- Same use cases as PostgreSQL +- Existing MySQL infrastructure +- Familiarity with MySQL ecosystem ### Prerequisites -* MySQL 8.0+ or MariaDB 10.3+ server -* Database and user created -* Network connectivity from ncps to MySQL +- MySQL 8.0+ or MariaDB 10.3+ server +- Database and user created +- Network connectivity from ncps to MySQL ### Setup MySQL @@ -48,9 +49,9 @@ mysql://[username]:[password]@[host]:[port]/[database]?[options] **Common options:** -* `socket` - Path to the Unix domain socket. -* `tls=true` - Enable TLS. -* `charset=utf8mb4` - Set character encoding. +- `socket` - Path to the Unix domain socket. +- `tls=true` - Enable TLS. +- `charset=utf8mb4` - Set character encoding. **Examples:** @@ -101,4 +102,4 @@ mysqldump -u ncps -p ncps > /backup/ncps.sql ``` mysql -u ncps -p ncps < /backup/ncps.sql -``` \ No newline at end of file +``` diff --git a/docs/docs/User Guide/Configuration/Database/PostgreSQL Configuration.md b/docs/docs/User Guide/Configuration/Database/PostgreSQL Configuration.md index 3753cf7b..1ee4d50a 100644 --- a/docs/docs/User Guide/Configuration/Database/PostgreSQL Configuration.md +++ b/docs/docs/User Guide/Configuration/Database/PostgreSQL Configuration.md @@ -1,16 +1,17 @@ -# PostgreSQL Configuration +# PostgreSQL Configuration + ### When to Use -* **High availability deployments**: Multiple ncps instances -* **Production environments**: Scalability and reliability required -* **Large teams**: High concurrent access -* **Cloud-native deployments** +- **High availability deployments**: Multiple ncps instances +- **Production environments**: Scalability and reliability required +- **Large teams**: High concurrent access +- **Cloud-native deployments** ### Prerequisites -* PostgreSQL 12+ server -* Database and user created -* Network connectivity from ncps to PostgreSQL +- PostgreSQL 12+ server +- Database and user created +- Network connectivity from ncps to PostgreSQL ### Setup PostgreSQL @@ -56,10 +57,10 @@ postgresql://[username]:[password]@[host]:[port]/[database]?[options] **Common options:** -* `host` - Hostname or path to the directory containing the Unix domain socket. -* `sslmode=require` - Require TLS encryption. -* `sslmode=disable` - Disable TLS (not recommended for production). -* `connect_timeout=10` - Connection timeout in seconds. +- `host` - Hostname or path to the directory containing the Unix domain socket. +- `sslmode=require` - Require TLS encryption. +- `sslmode=disable` - Disable TLS (not recommended for production). +- `connect_timeout=10` - Connection timeout in seconds. **Examples:** @@ -84,8 +85,8 @@ postgresql://ncps:password@localhost:5432/ncps?sslmode=require&connect_timeout=1 **Defaults for PostgreSQL:** -* Max open connections: 25 -* Max idle connections: 5 +- Max open connections: 25 +- Max idle connections: 5 **Custom settings:** @@ -143,4 +144,4 @@ pg_dump -h localhost -U ncps ncps > /backup/ncps.sql ``` psql -h localhost -U ncps ncps < /backup/ncps.sql -``` \ No newline at end of file +``` diff --git a/docs/docs/User Guide/Configuration/Database/SQLite Configuration.md b/docs/docs/User Guide/Configuration/Database/SQLite Configuration.md index c34d8a76..119659ed 100644 --- a/docs/docs/User Guide/Configuration/Database/SQLite Configuration.md +++ b/docs/docs/User Guide/Configuration/Database/SQLite Configuration.md @@ -1,10 +1,11 @@ -# SQLite Configuration +# SQLite Configuration + ### When to Use -* **Single-instance deployments**: One ncps server only -* **Simple setup**: No external database required -* **Development and testing** -* **Small to medium teams** (up to 100+ users) +- **Single-instance deployments**: One ncps server only +- **Simple setup**: No external database required +- **Development and testing** +- **Small to medium teams** (up to 100+ users) **Important:** SQLite does NOT support high-availability deployments with multiple instances. @@ -60,16 +61,16 @@ SQLite enforces a maximum of 1 open connection: **Pros:** -* Zero configuration -* Fast for single-instance -* No network overhead -* Automatic backups (file copy) +- Zero configuration +- Fast for single-instance +- No network overhead +- Automatic backups (file copy) **Cons:** -* Single writer at a time -* Not suitable for HA -* Limited scalability +- Single writer at a time +- Not suitable for HA +- Limited scalability ### Backup and Restore @@ -92,4 +93,4 @@ systemctl start ncps systemctl stop ncps cp /backup/db.sqlite.20240101 /var/lib/ncps/db/db.sqlite systemctl start ncps -``` \ No newline at end of file +``` diff --git a/docs/docs/User Guide/Configuration/Database/Troubleshooting.md b/docs/docs/User Guide/Configuration/Database/Troubleshooting.md index e65551fe..8af51aaf 100644 --- a/docs/docs/User Guide/Configuration/Database/Troubleshooting.md +++ b/docs/docs/User Guide/Configuration/Database/Troubleshooting.md @@ -1,11 +1,12 @@ -# Troubleshooting +# Troubleshooting + ### SQLite Issues **Database Locked:** -* Only one writer at a time -* Ensure no other processes are accessing the database -* Check for stale lock files +- Only one writer at a time +- Ensure no other processes are accessing the database +- Check for stale lock files **Corruption:** @@ -21,34 +22,34 @@ sqlite3 /var/lib/ncps/db/db.sqlite ".recover" | sqlite3 recovered.db **Connection Refused:** -* Check PostgreSQL is running: `systemctl status postgresql` -* Verify `pg_hba.conf` allows connections from ncps host -* Check firewall rules +- Check PostgreSQL is running: `systemctl status postgresql` +- Verify `pg_hba.conf` allows connections from ncps host +- Check firewall rules **Authentication Failed:** -* Verify username and password -* Check `pg_hba.conf` authentication method -* Ensure user has correct privileges +- Verify username and password +- Check `pg_hba.conf` authentication method +- Ensure user has correct privileges **Too Many Connections:** -* Reduce pool size in ncps -* Increase `max_connections` in PostgreSQL -* Check for connection leaks +- Reduce pool size in ncps +- Increase `max_connections` in PostgreSQL +- Check for connection leaks ### MySQL Issues **Connection Refused:** -* Check MySQL is running: `systemctl status mysql` -* Verify `bind-address` in my.cnf -* Check firewall rules +- Check MySQL is running: `systemctl status mysql` +- Verify `bind-address` in my.cnf +- Check firewall rules **Access Denied:** -* Verify username, password, and host in GRANT -* Check user privileges: `SHOW GRANTS FOR 'ncps'@'%';` -* Flush privileges after changes +- Verify username, password, and host in GRANT +- Check user privileges: `SHOW GRANTS FOR 'ncps'@'%';` +- Flush privileges after changes -See the [Troubleshooting Guide](../../Operations/Troubleshooting.md) for more help. \ No newline at end of file +See the [Troubleshooting Guide](../../Operations/Troubleshooting.md) for more help. diff --git a/docs/docs/User Guide/Configuration/Observability.md b/docs/docs/User Guide/Configuration/Observability.md index c6269006..95f0bc89 100644 --- a/docs/docs/User Guide/Configuration/Observability.md +++ b/docs/docs/User Guide/Configuration/Observability.md @@ -1,4 +1,5 @@ -# Observability +# Observability + ## Observability Configuration Configure monitoring, metrics, logging, and tracing for ncps. @@ -7,10 +8,10 @@ Configure monitoring, metrics, logging, and tracing for ncps. ncps provides comprehensive observability through: -* **Prometheus** - Metrics endpoint for monitoring your deployment -* **OpenTelemetry** - Distributed tracing and telemetry for your infrastructure -* **Structured Logging** - JSON-formatted logs with context -* **Analytics Reporting** - Anonymous usage statistics sent to project maintainers (separate from your monitoring) +- **Prometheus** - Metrics endpoint for monitoring your deployment +- **OpenTelemetry** - Distributed tracing and telemetry for your infrastructure +- **Structured Logging** - JSON-formatted logs with context +- **Analytics Reporting** - Anonymous usage statistics sent to project maintainers (separate from your monitoring) **Important:** This page covers observability for **your own deployment** (Prometheus, OpenTelemetry, logs). For information about anonymous usage statistics sent to project maintainers, see [Analytics Configuration](Analytics.md). @@ -50,49 +51,49 @@ http://your-ncps:8501/metrics **HTTP Metrics** (via otelchi middleware): -* `http_server_requests_total` - Total HTTP requests -* `http_server_request_duration_seconds` - Request duration histogram -* `http_server_active_requests` - Currently active requests +- `http_server_requests_total` - Total HTTP requests +- `http_server_request_duration_seconds` - Request duration histogram +- `http_server_active_requests` - Currently active requests **Cache Metrics:** -* `ncps_nar_served_total` - Total NAR files served -* `ncps_narinfo_served_total` - Total NarInfo files served +- `ncps_nar_served_total` - Total NAR files served +- `ncps_narinfo_served_total` - Total NarInfo files served **Upstream Health Metrics** (available when analytics reporting is enabled): -* `ncps_upstream_count_healthy` - Number of healthy upstream caches -* `ncps_upstream_count_total` - Total number of configured upstream caches +- `ncps_upstream_count_healthy` - Number of healthy upstream caches +- `ncps_upstream_count_total` - Total number of configured upstream caches Note: Upstream health metrics are collected as part of analytics reporting. See [Analytics Configuration](Analytics.md) for details. **Lock Metrics** (when using Redis for HA): -* `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisition attempts - * `type`: "download" or "lru" - * `result`: "success" or "failure" - * `mode`: "local" or "distributed" -* `ncps_lock_hold_duration_seconds{type,mode}` - Lock hold time histogram -* `ncps_lock_failures_total{type,reason,mode}` - Lock failures - * `reason`: "timeout", "redis\_error", "circuit\_breaker" -* `ncps_lock_retry_attempts_total{type}` - Retry attempts +- `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisition attempts + - `type`: "download" or "lru" + - `result`: "success" or "failure" + - `mode`: "local" or "distributed" +- `ncps_lock_hold_duration_seconds{type,mode}` - Lock hold time histogram +- `ncps_lock_failures_total{type,reason,mode}` - Lock failures + - `reason`: "timeout", "redis_error", "circuit_breaker" +- `ncps_lock_retry_attempts_total{type}` - Retry attempts **Migration Metrics** (during narinfo migration): -* `ncps_migration_narinfos_total{operation,result}` - NarInfo migration operations - * `operation`: "migrate" or "delete" - * `result`: "success", "failure", or "skipped" -* `ncps_migration_duration_seconds{operation}` - Migration operation duration histogram - * `operation`: "migrate" or "delete" -* `ncps_migration_batch_size` - Migration batch size histogram +- `ncps_migration_narinfos_total{operation,result}` - NarInfo migration operations + - `operation`: "migrate" or "delete" + - `result`: "success", "failure", or "skipped" +- `ncps_migration_duration_seconds{operation}` - Migration operation duration histogram + - `operation`: "migrate" or "delete" +- `ncps_migration_batch_size` - Migration batch size histogram **Background Migration Metrics** (during on-the-fly migration): -* `ncps_background_migration_narinfos_total{operation,result}` - Background NarInfo migration operations - * `operation`: "migrate" or "delete" - * `result`: "success" or "failure" -* `ncps_background_migration_duration_seconds{operation}` - Background migration operation duration histogram - * `operation`: "migrate" or "delete" +- `ncps_background_migration_narinfos_total{operation,result}` - Background NarInfo migration operations + - `operation`: "migrate" or "delete" + - `result`: "success" or "failure" +- `ncps_background_migration_duration_seconds{operation}` - Background migration operation duration histogram + - `operation`: "migrate" or "delete" See [NarInfo Migration Guide](../Operations/NarInfo%20Migration.md) for migration documentation. @@ -132,16 +133,16 @@ Create dashboards to visualize: **Cache Performance:** -* Cache hit rate -* NAR files served (rate) -* Request duration percentiles (p50, p95, p99) +- Cache hit rate +- NAR files served (rate) +- Request duration percentiles (p50, p95, p99) **HA Lock Performance:** -* Lock acquisition success/failure rate -* Lock hold duration -* Retry attempt rate -* Lock contention +- Lock acquisition success/failure rate +- Lock hold duration +- Retry attempt rate +- Lock contention See the [Monitoring Guide](../Operations/Monitoring.md) for dashboard examples. @@ -182,7 +183,7 @@ export OTEL_GRPC_URL=http://otel-collector:4317 When enabled, OpenTelemetry provides: -**1\. Logs** - Structured application logs **2\. Metrics** - Application and system metrics **3\. Traces** - Distributed request tracing +**1. Logs** - Structured application logs **2. Metrics** - Application and system metrics **3. Traces** - Distributed request tracing ### OpenTelemetry Collector Setup @@ -278,10 +279,10 @@ ncps serve --log-level=debug **Levels:** -* `debug` - Verbose logging, including debug information -* `info` - Standard informational messages (default) -* `warn` - Warning messages only -* `error` - Error messages only +- `debug` - Verbose logging, including debug information +- `info` - Standard informational messages (default) +- `warn` - Warning messages only +- `error` - Error messages only **Configuration file:** @@ -309,21 +310,21 @@ Logs are output in JSON format with structured fields: **Cache Operations:** -* `serving nar from cache` - NAR file served from cache -* `downloading nar from upstream` - Fetching from upstream -* `nar cached successfully` - Download and cache complete +- `serving nar from cache` - NAR file served from cache +- `downloading nar from upstream` - Fetching from upstream +- `nar cached successfully` - Download and cache complete **Lock Operations (HA):** -* `acquired download lock` - Download lock obtained -* `failed to acquire lock` - Lock acquisition failed after retries -* `another instance is running LRU` - LRU skipped (another instance running) -* `circuit breaker open: Redis is unavailable` - Redis connectivity issues +- `acquired download lock` - Download lock obtained +- `failed to acquire lock` - Lock acquisition failed after retries +- `another instance is running LRU` - LRU skipped (another instance running) +- `circuit breaker open: Redis is unavailable` - Redis connectivity issues **Server:** -* `server started` - ncps HTTP server started -* `server shutdown` - Graceful shutdown initiated +- `server started` - ncps HTTP server started +- `server shutdown` - Graceful shutdown initiated ### Log Aggregation @@ -392,12 +393,12 @@ Access Jaeger UI at `http://localhost:16686` to view traces. Traces include: -* Request ID -* Upstream cache calls -* Lock acquisitions (HA mode) -* Database queries -* S3 operations -* Download and cache operations +- Request ID +- Upstream cache calls +- Lock acquisitions (HA mode) +- Database queries +- S3 operations +- Download and cache operations ## Health Checks @@ -503,20 +504,20 @@ services: **Access:** -* ncps: `http://localhost:8501` -* Prometheus: `http://localhost:9090` -* Grafana: `http://localhost:3000` (admin/admin) -* Jaeger: `http://localhost:16686` +- ncps: `http://localhost:8501` +- Prometheus: `http://localhost:9090` +- Grafana: `http://localhost:3000` (admin/admin) +- Jaeger: `http://localhost:16686` ## Next Steps -1. Monitoring - Set up dashboards and alerts -2. Troubleshooting - Use logs and metrics to debug -3. Reference - All observability options +1. Monitoring - Set up dashboards and alerts +1. Troubleshooting - Use logs and metrics to debug +1. Reference - All observability options ## Related Documentation -* Analytics - Anonymous usage statistics reporting -* Monitoring - Detailed monitoring setup -* High Availability - HA observability -* Reference - All configuration options \ No newline at end of file +- Analytics - Anonymous usage statistics reporting +- Monitoring - Detailed monitoring setup +- High Availability - HA observability +- Reference - All configuration options diff --git a/docs/docs/User Guide/Configuration/Reference.md b/docs/docs/User Guide/Configuration/Reference.md index b641a836..a02b385f 100644 --- a/docs/docs/User Guide/Configuration/Reference.md +++ b/docs/docs/User Guide/Configuration/Reference.md @@ -1,4 +1,5 @@ -# Reference +# Reference + ## Configuration Reference Complete reference for all ncps configuration options. @@ -12,7 +13,7 @@ Options that apply to the entire ncps process. | `--config` | Path to configuration file (json, toml, yaml) | `NCPS_CONFIG_FILE` | `$XDG_CONFIG_HOME/ncps/config.yaml` | | `--log-level` | Log level: debug, info, warn, error | `LOG_LEVEL` | `info` | | `--otel-enabled` | Enable OpenTelemetry (logs, metrics, tracing) | `OTEL_ENABLED` | `false` | -| `--otel-grpc-url` | OpenTelemetry gRPC collector URL (omit for stdout) | `OTEL_GRPC_URL` | \- | +| `--otel-grpc-url` | OpenTelemetry gRPC collector URL (omit for stdout) | `OTEL_GRPC_URL` | - | | `--prometheus-enabled` | Enable Prometheus metrics endpoint at /metrics | `PROMETHEUS_ENABLED` | `false` | **Example:** @@ -83,13 +84,13 @@ Use these options for S3-compatible storage (AWS S3, MinIO, etc.). | Option | Description | Environment Variable | Required for S3 | Default | | --- | --- | --- | --- | --- | -| `--cache-storage-s3-bucket` | S3 bucket name | `CACHE_STORAGE_S3_BUCKET` | ✅ | \- | -| `--cache-storage-s3-endpoint` | S3 endpoint URL with scheme (e.g., [https://s3.amazonaws.com](https://s3.amazonaws.com) or [http://minio:9000](http://minio:9000)) | `CACHE_STORAGE_S3_ENDPOINT` | ✅ | \- | -| `--cache-storage-s3-access-key-id` | S3 access key ID | `CACHE_STORAGE_S3_ACCESS_KEY_ID` | ✅ | \- | -| `--cache-storage-s3-secret-access-key` | S3 secret access key | `CACHE_STORAGE_S3_SECRET_ACCESS_KEY` | ✅ | \- | -| `--cache-storage-s3-region` | S3 region (optional for some providers) | `CACHE_STORAGE_S3_REGION` | \- | \- | -| `--cache-storage-s3-force-path-style` | Use path-style URLs (required for MinIO) | `CACHE_STORAGE_S3_FORCE_PATH_STYLE` | \- | `false` | -| `--cache-storage-s3-use-ssl` | **DEPRECATED:** Specify scheme in endpoint instead | `CACHE_STORAGE_S3_USE_SSL` | \- | \- | +| `--cache-storage-s3-bucket` | S3 bucket name | `CACHE_STORAGE_S3_BUCKET` | ✅ | - | +| `--cache-storage-s3-endpoint` | S3 endpoint URL with scheme (e.g., [https://s3.amazonaws.com](https://s3.amazonaws.com) or [http://minio:9000](http://minio:9000)) | `CACHE_STORAGE_S3_ENDPOINT` | ✅ | - | +| `--cache-storage-s3-access-key-id` | S3 access key ID | `CACHE_STORAGE_S3_ACCESS_KEY_ID` | ✅ | - | +| `--cache-storage-s3-secret-access-key` | S3 secret access key | `CACHE_STORAGE_S3_SECRET_ACCESS_KEY` | ✅ | - | +| `--cache-storage-s3-region` | S3 region (optional for some providers) | `CACHE_STORAGE_S3_REGION` | - | - | +| `--cache-storage-s3-force-path-style` | Use path-style URLs (required for MinIO) | `CACHE_STORAGE_S3_FORCE_PATH_STYLE` | - | `false` | +| `--cache-storage-s3-use-ssl` | **DEPRECATED:** Specify scheme in endpoint instead | `CACHE_STORAGE_S3_USE_SSL` | - | - | **Note:** The endpoint must include the scheme (`https://` or `http://`). The `--cache-storage-s3-use-ssl` flag is deprecated in favor of specifying the scheme directly in the endpoint URL. @@ -127,7 +128,7 @@ See Storage for details. | `--cache-database-pool-max-open-conns` | Maximum open database connections | `CACHE_DATABASE_POOL_MAX_OPEN_CONNS` | 25 (PG/MySQL), 1 (SQLite) | | `--cache-database-pool-max-idle-conns` | Maximum idle database connections | `CACHE_DATABASE_POOL_MAX_IDLE_CONNS` | 5 (PG/MySQL), unset (SQLite) | | `--cache-max-size` | Maximum cache size (5K, 10G, etc.) | `CACHE_MAX_SIZE` | unlimited | -| `--cache-lru-schedule` | LRU cleanup cron schedule | `CACHE_LRU_SCHEDULE` | \- | +| `--cache-lru-schedule` | LRU cleanup cron schedule | `CACHE_LRU_SCHEDULE` | - | | `--cache-temp-path` | Temporary download directory | `CACHE_TEMP_PATH` | system temp | > [!IMPORTANT] @@ -135,18 +136,18 @@ See Storage for details. **Database URL Formats:** -* SQLite: `sqlite:/var/lib/ncps/db/db.sqlite` -* PostgreSQL: `postgresql://user:pass@host:5432/database?sslmode=require` -* PostgreSQL (Socket): `postgresql:///database?host=/var/run/postgresql` -* MySQL: `mysql://user:pass@host:3306/database` -* MySQL (Socket): `mysql://user:pass@/database?socket=/var/run/mysqld/mysqld.sock` +- SQLite: `sqlite:/var/lib/ncps/db/db.sqlite` +- PostgreSQL: `postgresql://user:pass@host:5432/database?sslmode=require` +- PostgreSQL (Socket): `postgresql:///database?host=/var/run/postgresql` +- MySQL: `mysql://user:pass@host:3306/database` +- MySQL (Socket): `mysql://user:pass@/database?socket=/var/run/mysqld/mysqld.sock` **Notes on Sockets:** For MySQL and PostgreSQL, you can use specialized schemes for Unix domain sockets: -* `mysql+unix:///path/to/socket.sock/database` -* `postgres+unix:///path/to/socket_dir/database` +- `mysql+unix:///path/to/socket.sock/database` +- `postgres+unix:///path/to/socket_dir/database` **Example:** @@ -189,9 +190,9 @@ Configure timeout values for upstream cache connections. Increase these if exper **Common timeout values:** -* `3s` - Default, works for most local/fast upstreams -* `10s` - Recommended for slow networks or distant upstreams -* `30s` - For very slow connections (satellite, slow VPN) +- `3s` - Default, works for most local/fast upstreams +- `10s` - Recommended for slow networks or distant upstreams +- `30s` - For very slow connections (satellite, slow VPN) **Example:** @@ -210,11 +211,11 @@ Redis configuration for distributed locking in high-availability deployments. | Option | Description | Environment Variable | Default | | --- | --- | --- | --- | | `--cache-redis-addrs` | Redis addresses (comma-separated for cluster) | `CACHE_REDIS_ADDRS` | (none - local mode) | -| `--cache-redis-username` | Redis ACL username | `CACHE_REDIS_USERNAME` | "" | -| `--cache-redis-password` | Redis password | `CACHE_REDIS_PASSWORD` | "" | -| `--cache-redis-db` | Redis database number (0-15) | `CACHE_REDIS_DB` | 0 | +| `--cache-redis-username` | Redis ACL username | `CACHE_REDIS_USERNAME` | "" | +| `--cache-redis-password` | Redis password | `CACHE_REDIS_PASSWORD` | "" | +| `--cache-redis-db` | Redis database number (0-15) | `CACHE_REDIS_DB` | 0 | | `--cache-redis-use-tls` | Enable TLS for Redis connections | `CACHE_REDIS_USE_TLS` | false | -| `--cache-redis-pool-size` | Connection pool size | `CACHE_REDIS_POOL_SIZE` | 10 | +| `--cache-redis-pool-size` | Connection pool size | `CACHE_REDIS_POOL_SIZE` | 10 | **Note:** If `--cache-redis-addrs` is not provided, ncps runs in single-instance mode using local locks. @@ -266,7 +267,7 @@ Lock timing and retry configuration for distributed locking. | Option | Description | Environment Variable | Default | | --- | --- | --- | --- | -| `--cache-lock-retry-max-attempts` | Maximum lock retry attempts | `CACHE_LOCK_RETRY_MAX_ATTEMPTS` | 3 | +| `--cache-lock-retry-max-attempts` | Maximum lock retry attempts | `CACHE_LOCK_RETRY_MAX_ATTEMPTS` | 3 | | `--cache-lock-retry-initial-delay` | Initial retry delay | `CACHE_LOCK_RETRY_INITIAL_DELAY` | `100ms` | | `--cache-lock-retry-max-delay` | Maximum retry delay (backoff cap) | `CACHE_LOCK_RETRY_MAX_DELAY` | `2s` | | `--cache-lock-retry-jitter` | Enable jitter in retry delays | `CACHE_LOCK_RETRY_JITTER` | `true` | @@ -294,27 +295,27 @@ Configure anonymous usage statistics reporting to help improve ncps. **What is collected:** -* **Resource attributes**: - * Database backend type: `sqlite`, `postgres`, or `mysql` - * Lock mechanism type: `local`, `redis`, or `postgres` - * Cluster UUID (randomly generated identifier) -* **Metrics** (hourly): Total cache size, upstream count, upstream health -* **Logs**: Startup events, panic/crash events with stack traces +- **Resource attributes**: + - Database backend type: `sqlite`, `postgres`, or `mysql` + - Lock mechanism type: `local`, `redis`, or `postgres` + - Cluster UUID (randomly generated identifier) +- **Metrics** (hourly): Total cache size, upstream count, upstream health +- **Logs**: Startup events, panic/crash events with stack traces **What is NOT collected:** -* No personal information (usernames, emails, PII) -* No network information (IP addresses, hostnames) -* No cache contents (store paths, packages) -* No configuration secrets (passwords, keys) -* No request logs (HTTP requests, clients) +- No personal information (usernames, emails, PII) +- No network information (IP addresses, hostnames) +- No cache contents (store paths, packages) +- No configuration secrets (passwords, keys) +- No request logs (HTTP requests, clients) **Privacy:** -* Fully anonymous and privacy-focused -* Data sent to `otlp.ncps.dev:443` via HTTPS -* Helps maintainers understand usage patterns and prioritize development -* Easy opt-out with `--analytics-reporting-enabled=false` +- Fully anonymous and privacy-focused +- Data sent to `otlp.ncps.dev:443` via HTTPS +- Helps maintainers understand usage patterns and prioritize development +- Easy opt-out with `--analytics-reporting-enabled=false` **Enable (default):** @@ -359,7 +360,7 @@ Metrics available at `http://your-ncps:8501/metrics`. | Option | Description | Environment Variable | Default | | --- | --- | --- | --- | | `--otel-enabled` | Enable OpenTelemetry (logs, metrics, tracing) | `OTEL_ENABLED` | `false` | -| `--otel-grpc-url` | gRPC collector endpoint (omit for stdout) | `OTEL_GRPC_URL` | \- | +| `--otel-grpc-url` | gRPC collector endpoint (omit for stdout) | `OTEL_GRPC_URL` | - | **Example:** @@ -445,15 +446,15 @@ otel: **Environment variable expansion:** -* Use `${VAR_NAME}` syntax in configuration files -* Variables are expanded when the config is loaded +- Use `${VAR_NAME}` syntax in configuration files +- Variables are expanded when the config is loaded See [config.example.yaml](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) for a complete example. ## Related Documentation -* Storage - Storage backend details -* Database - Database backend details -* Observability - Monitoring and logging -* High Availability - HA configuration -* Distributed Locking - Lock tuning \ No newline at end of file +- Storage - Storage backend details +- Database - Database backend details +- Observability - Monitoring and logging +- High Availability - HA configuration +- Distributed Locking - Lock tuning diff --git a/docs/docs/User Guide/Configuration/Storage.md b/docs/docs/User Guide/Configuration/Storage.md index 7dfff6f8..672087b9 100644 --- a/docs/docs/User Guide/Configuration/Storage.md +++ b/docs/docs/User Guide/Configuration/Storage.md @@ -1,4 +1,5 @@ -# Storage +# Storage + ## Storage Configuration Configure ncps storage backends: local filesystem or S3-compatible storage. @@ -7,20 +8,20 @@ Configure ncps storage backends: local filesystem or S3-compatible storage. ncps supports two storage backends for storing NAR files and other cache data: -* **Local Filesystem**: Traditional file-based storage -* **S3-Compatible**: AWS S3, MinIO, and other S3-compatible services +- **Local Filesystem**: Traditional file-based storage +- **S3-Compatible**: AWS S3, MinIO, and other S3-compatible services **Note:** You must choose exactly ONE storage backend. You cannot use both simultaneously. ## Next Steps -1. Database - Configure database backend -2. Reference - All storage options -3. High Availability - S3 for HA deployments -4. Operations - Monitoring and maintenance +1. Database - Configure database backend +1. Reference - All storage options +1. High Availability - S3 for HA deployments +1. Operations - Monitoring and maintenance ## Related Documentation -* Reference - All configuration options -* Installation - Installation-specific storage setup -* S3 Storage Implementation - S3 implementation details \ No newline at end of file +- Reference - All configuration options +- Installation - Installation-specific storage setup +- S3 Storage Implementation - S3 implementation details diff --git a/docs/docs/User Guide/Configuration/Storage/Local Filesystem Storage.md b/docs/docs/User Guide/Configuration/Storage/Local Filesystem Storage.md index c0fa2dd9..d19bddea 100644 --- a/docs/docs/User Guide/Configuration/Storage/Local Filesystem Storage.md +++ b/docs/docs/User Guide/Configuration/Storage/Local Filesystem Storage.md @@ -1,10 +1,11 @@ -# Local Filesystem Storage +# Local Filesystem Storage + ### When to Use -* **Single-instance deployments**: One ncps server -* **Simple setup**: No external dependencies -* **Low latency**: Direct disk I/O -* **Testing and development** +- **Single-instance deployments**: One ncps server +- **Simple setup**: No external dependencies +- **Low latency**: Direct disk I/O +- **Testing and development** ### Configuration @@ -41,9 +42,9 @@ Local storage creates the following structure: ### Requirements -* **Writable directory**: ncps user must have read/write access -* **Sufficient space**: Plan for cache growth (recommend 50GB-1TB) -* **Fast disk**: SSD recommended for better performance +- **Writable directory**: ncps user must have read/write access +- **Sufficient space**: Plan for cache growth (recommend 50GB-1TB) +- **Fast disk**: SSD recommended for better performance ### Permissions @@ -58,12 +59,12 @@ sudo chmod 0755 /var/lib/ncps **Pros:** -* Fast (local disk I/O) -* No network latency -* Simple to manage +- Fast (local disk I/O) +- No network latency +- Simple to manage **Cons:** -* Limited to single server's disk -* No built-in redundancy -* Not suitable for HA deployments \ No newline at end of file +- Limited to single server's disk +- No built-in redundancy +- Not suitable for HA deployments diff --git a/docs/docs/User Guide/Configuration/Storage/Migration Between Storage Back.md b/docs/docs/User Guide/Configuration/Storage/Migration Between Storage Back.md index f5a13270..3b5b54f9 100644 --- a/docs/docs/User Guide/Configuration/Storage/Migration Between Storage Back.md +++ b/docs/docs/User Guide/Configuration/Storage/Migration Between Storage Back.md @@ -1,4 +1,5 @@ -# Migration Between Storage Backends +# Migration Between Storage Backends + ### From Local to S3 ``` @@ -24,4 +25,4 @@ aws s3 sync s3://ncps-cache/config/ /var/lib/ncps/config/ # 2. Update ncps configuration to use local storage # 3. Restart ncps -``` \ No newline at end of file +``` diff --git a/docs/docs/User Guide/Configuration/Storage/S3-Compatible Storage.md b/docs/docs/User Guide/Configuration/Storage/S3-Compatible Storage.md index 3447ea51..83932c2f 100644 --- a/docs/docs/User Guide/Configuration/Storage/S3-Compatible Storage.md +++ b/docs/docs/User Guide/Configuration/Storage/S3-Compatible Storage.md @@ -1,18 +1,19 @@ -# S3-Compatible Storage +# S3-Compatible Storage + ### When to Use -* **High availability deployments**: Multiple ncps instances -* **Cloud-native setups**: Leveraging cloud infrastructure -* **Scalability**: Need storage independent of server resources -* **Redundancy**: Built-in durability and replication +- **High availability deployments**: Multiple ncps instances +- **Cloud-native setups**: Leveraging cloud infrastructure +- **Scalability**: Need storage independent of server resources +- **Redundancy**: Built-in durability and replication ### Supported Providers -* AWS S3 -* MinIO (self-hosted) -* DigitalOcean Spaces -* Backblaze B2 -* Any S3-compatible service +- AWS S3 +- MinIO (self-hosted) +- DigitalOcean Spaces +- Backblaze B2 +- Any S3-compatible service ### Configuration @@ -79,18 +80,18 @@ cache: | Option | Required | Description | Default | | --- | --- | --- | --- | -| `bucket` | Yes | S3 bucket name | \- | -| `endpoint` | Yes | S3 endpoint URL with scheme (e.g., `https://s3.amazonaws.com`) | \- | +| `bucket` | Yes | S3 bucket name | - | +| `endpoint` | Yes | S3 endpoint URL with scheme (e.g., `https://s3.amazonaws.com`) | - | | `region` | Yes | AWS region or any value for MinIO | `us-east-1` | -| `access-key-id` | Yes | S3 access key ID | \- | -| `secret-access-key` | Yes | S3 secret access key | \- | -| `force-path-style` | No | Use path-style URLs (required for MinIO) | `false` | +| `access-key-id` | Yes | S3 access key ID | - | +| `secret-access-key` | Yes | S3 secret access key | - | +| `force-path-style` | No | Use path-style URLs (required for MinIO) | `false` | **Endpoint Scheme Requirement:** -* The endpoint **must** include a scheme (`https://` or `http://`) -* Examples: `https://s3.amazonaws.com`, `http://minio:9000` -* The scheme determines whether SSL/TLS is used +- The endpoint **must** include a scheme (`https://` or `http://`) +- Examples: `https://s3.amazonaws.com`, `http://minio:9000` +- The scheme determines whether SSL/TLS is used ### S3 Bucket Setup @@ -162,17 +163,17 @@ s3://ncps-cache/ **Pros:** -* Scalable (independent of server resources) -* Durable (built-in redundancy) -* Multi-instance support (required for HA) -* Geographic replication options +- Scalable (independent of server resources) +- Durable (built-in redundancy) +- Multi-instance support (required for HA) +- Geographic replication options **Cons:** -* Network latency overhead -* Potential costs (AWS S3) -* Requires S3 service setup -* More complex configuration +- Network latency overhead +- Potential costs (AWS S3) +- Requires S3 service setup +- More complex configuration ### Security Best Practices @@ -201,11 +202,11 @@ s3://ncps-cache/ **Encryption:** -* Enable server-side encryption (SSE-S3 or SSE-KMS) -* Use TLS for data in transit (`--cache-storage-s3-use-ssl=true`) +- Enable server-side encryption (SSE-S3 or SSE-KMS) +- Use TLS for data in transit (`--cache-storage-s3-use-ssl=true`) **Access Control:** -* Use least-privilege IAM policies -* Enable bucket versioning for recovery -* Consider bucket lifecycle policies for cost optimization \ No newline at end of file +- Use least-privilege IAM policies +- Enable bucket versioning for recovery +- Consider bucket lifecycle policies for cost optimization diff --git a/docs/docs/User Guide/Configuration/Storage/Storage Comparison.md b/docs/docs/User Guide/Configuration/Storage/Storage Comparison.md index 7489324b..26a0bd6d 100644 --- a/docs/docs/User Guide/Configuration/Storage/Storage Comparison.md +++ b/docs/docs/User Guide/Configuration/Storage/Storage Comparison.md @@ -1,4 +1,5 @@ -# Storage Comparison +# Storage Comparison + | Feature | Local Storage | S3 Storage | | --- | --- | --- | | **Setup Complexity** | Simple | Moderate | @@ -8,4 +9,4 @@ | **High Availability** | ❌ Not supported | ✅ Required | | **Redundancy** | None (unless RAID/NFS) | Built-in | | **Cost** | Disk only | S3 storage + requests | -| **Best For** | Single-instance, dev/test | HA, production, cloud | \ No newline at end of file +| **Best For** | Single-instance, dev/test | HA, production, cloud | diff --git a/docs/docs/User Guide/Configuration/Storage/Troubleshooting.md b/docs/docs/User Guide/Configuration/Storage/Troubleshooting.md index 17a5a61c..0db45573 100644 --- a/docs/docs/User Guide/Configuration/Storage/Troubleshooting.md +++ b/docs/docs/User Guide/Configuration/Storage/Troubleshooting.md @@ -1,4 +1,5 @@ -# Troubleshooting +# Troubleshooting + ### Local Storage Issues **Permission Denied:** @@ -25,20 +26,20 @@ ncps serve --cache-max-size=50G --cache-lru-schedule="0 2 * * *" **Access Denied:** -* Verify credentials are correct -* Check IAM policy permissions -* Ensure bucket exists and is in correct region +- Verify credentials are correct +- Check IAM policy permissions +- Ensure bucket exists and is in correct region **Connection Timeout:** -* Check network connectivity to S3 endpoint -* Verify endpoint URL is correct -* Check firewall rules +- Check network connectivity to S3 endpoint +- Verify endpoint URL is correct +- Check firewall rules **Slow Performance:** -* Check network bandwidth -* Consider using S3 Transfer Acceleration (AWS) -* Verify region is geographically close +- Check network bandwidth +- Consider using S3 Transfer Acceleration (AWS) +- Verify region is geographically close -See the Troubleshooting for more help. \ No newline at end of file +See the Troubleshooting for more help. diff --git a/docs/docs/User Guide/Deployment.md b/docs/docs/User Guide/Deployment.md index 67216729..5fd95ce4 100644 --- a/docs/docs/User Guide/Deployment.md +++ b/docs/docs/User Guide/Deployment.md @@ -1,4 +1,5 @@ -# Deployment +# Deployment + ## Deployment Guide Choose the deployment strategy that best fits your requirements. @@ -13,18 +14,18 @@ One ncps server handling all cache requests. **Best for:** -* Development and testing -* Small to medium teams (1-100+ users) -* Single-location deployments -* Simpler operations +- Development and testing +- Small to medium teams (1-100+ users) +- Single-location deployments +- Simpler operations **Characteristics:** -* One server -* Local locks (no Redis) -* Local or S3 storage -* SQLite, PostgreSQL, or MySQL database -* Easier to set up and maintain +- One server +- Local locks (no Redis) +- Local or S3 storage +- SQLite, PostgreSQL, or MySQL database +- Easier to set up and maintain [Learn more →](Deployment/Single%20Instance.md) @@ -34,20 +35,20 @@ Multiple ncps instances for redundancy and scalability. **Best for:** -* Production environments -* Large teams (100+ users) -* Business-critical infrastructure -* Geographic distribution -* Zero-downtime requirements +- Production environments +- Large teams (100+ users) +- Business-critical infrastructure +- Geographic distribution +- Zero-downtime requirements **Characteristics:** -* 2+ servers -* Redis distributed locking -* S3 storage (required) -* PostgreSQL or MySQL database (required, NOT SQLite) -* Load balancer -* More complex setup +- 2+ servers +- Redis distributed locking +- S3 storage (required) +- PostgreSQL or MySQL database (required, NOT SQLite) +- Load balancer +- More complex setup [Learn more →](Deployment/High%20Availability.md) @@ -55,14 +56,14 @@ Multiple ncps instances for redundancy and scalability. | Aspect | Single-Instance | High Availability | | --- | --- | --- | -| **Servers** | 1 | 2+ | +| **Servers** | 1 | 2+ | | **Locking** | Local (in-process) | Redis distributed locks | | **Storage** | Local or S3 | S3 (required) | | **Database** | SQLite, PostgreSQL, or MySQL | PostgreSQL or MySQL (NOT SQLite) | | **Load Balancer** | Not needed | Required | | **Redundancy** | None | Full | | **Complexity** | Simple | Moderate | -| **Zero Downtime** | No | Yes | +| **Zero Downtime** | No | Yes | | **Scalability** | Limited to one server | Horizontal scaling | | **Cost** | Lower | Higher | @@ -81,9 +82,9 @@ Start ## Documentation -* [Single-Instance Deployment](Deployment/Single%20Instance.md) - Deploy one ncps server -* [High Availability Deployment](Deployment/High%20Availability.md) - Deploy multiple instances with HA -* Distributed Locking - Deep dive into Redis locking for HA +- [Single-Instance Deployment](Deployment/Single%20Instance.md) - Deploy one ncps server +- [High Availability Deployment](Deployment/High%20Availability.md) - Deploy multiple instances with HA +- Distributed Locking - Deep dive into Redis locking for HA ## Prerequisites by Mode @@ -91,45 +92,45 @@ Start **Minimum:** -* Server or VM (2+ CPU cores, 4GB+ RAM recommended) -* Storage (50GB-1TB depending on usage) -* Network connectivity to upstream caches +- Server or VM (2+ CPU cores, 4GB+ RAM recommended) +- Storage (50GB-1TB depending on usage) +- Network connectivity to upstream caches **Optional:** -* S3-compatible storage (for cloud-native or future HA) -* PostgreSQL/MySQL (for better performance than SQLite) +- S3-compatible storage (for cloud-native or future HA) +- PostgreSQL/MySQL (for better performance than SQLite) ### High Availability Prerequisites **Required:** -* 2+ servers (3+ recommended for better availability) -* Redis server (single instance or cluster) -* S3-compatible storage (AWS S3, MinIO, etc.) -* PostgreSQL or MySQL database -* Load balancer (nginx, HAProxy, cloud LB) +- 2+ servers (3+ recommended for better availability) +- Redis server (single instance or cluster) +- S3-compatible storage (AWS S3, MinIO, etc.) +- PostgreSQL or MySQL database +- Load balancer (nginx, HAProxy, cloud LB) **Optional:** -* Monitoring and alerting (Prometheus, Grafana) -* Centralized logging (ELK, Loki) +- Monitoring and alerting (Prometheus, Grafana) +- Centralized logging (ELK, Loki) ## Getting Started -1. **Choose deployment mode** based on your requirements -2. **Review prerequisites** for your chosen mode -3. **Follow installation guide**: - * Docker - * Docker Compose - * Kubernetes - * Helm Chart - * NixOS -4. **Configure** according to your mode: - * Single Instance - * High Availability -5. **Verify deployment** and test -6. **Set up monitoring** (recommended) +1. **Choose deployment mode** based on your requirements +1. **Review prerequisites** for your chosen mode +1. **Follow installation guide**: + - Docker + - Docker Compose + - Kubernetes + - Helm Chart + - NixOS +1. **Configure** according to your mode: + - Single Instance + - High Availability +1. **Verify deployment** and test +1. **Set up monitoring** (recommended) ## Migration Path @@ -137,10 +138,10 @@ Start Common migration path as your needs grow: -1. **Start**: Single instance with local storage and SQLite -2. **Scale up**: Move to PostgreSQL for better performance -3. **Cloud-ready**: Migrate to S3 storage -4. **High Availability**: Add Redis and additional instances +1. **Start**: Single instance with local storage and SQLite +1. **Scale up**: Move to PostgreSQL for better performance +1. **Cloud-ready**: Migrate to S3 storage +1. **High Availability**: Add Redis and additional instances Each step is incremental and can be done independently. @@ -189,13 +190,13 @@ Load Balancer ## Next Steps -1. [Choose and follow deployment guide](Deployment/Single%20Instance.md) -2. [Configure clients](Usage/Client%20Setup.md) to use your cache -3. [Set up monitoring](Operations/Monitoring.md) for production -4. [Review operations guides](Operations.md) for maintenance +1. [Choose and follow deployment guide](Deployment/Single%20Instance.md) +1. [Configure clients](Usage/Client%20Setup.md) to use your cache +1. [Set up monitoring](Operations/Monitoring.md) for production +1. [Review operations guides](Operations.md) for maintenance ## Related Documentation -* [Installation Guides](Installation.md) - Installation methods -* [Configuration Reference](Configuration/Reference.md) - All configuration options -* [Operations Guides](Operations.md) - Monitoring, troubleshooting, backups \ No newline at end of file +- [Installation Guides](Installation.md) - Installation methods +- [Configuration Reference](Configuration/Reference.md) - All configuration options +- [Operations Guides](Operations.md) - Monitoring, troubleshooting, backups diff --git a/docs/docs/User Guide/Deployment/Distributed Locking.md b/docs/docs/User Guide/Deployment/Distributed Locking.md index 1439a35a..84179052 100644 --- a/docs/docs/User Guide/Deployment/Distributed Locking.md +++ b/docs/docs/User Guide/Deployment/Distributed Locking.md @@ -1,25 +1,26 @@ -# Distributed Locking +# Distributed Locking + This document provides comprehensive guidance on using distributed locking in ncps for high-availability deployments. ## Overview ncps supports running multiple instances in a high-availability configuration using **Redis** or **PostgreSQL advisory locks** for distributed locking. This enables: -* **Zero-downtime deployments** - Update instances one at a time -* **Horizontal scaling** - Add instances to handle more traffic -* **Load distribution** - Spread requests across multiple servers -* **Geographic distribution** - Deploy instances closer to clients +- **Zero-downtime deployments** - Update instances one at a time +- **Horizontal scaling** - Add instances to handle more traffic +- **Load distribution** - Spread requests across multiple servers +- **Geographic distribution** - Deploy instances closer to clients ### Key Concepts -* **Download Deduplication**: When multiple instances request the same package, only one downloads it while others wait for the result -* **LRU Coordination**: Only one instance runs cache cleanup at a time to prevent conflicts -* **Retry with Backoff**: Failed lock acquisitions retry automatically with exponential backoff and jitter -* **Lock Expiry**: All locks have TTLs to prevent deadlocks from instance failures +- **Download Deduplication**: When multiple instances request the same package, only one downloads it while others wait for the result +- **LRU Coordination**: Only one instance runs cache cleanup at a time to prevent conflicts +- **Retry with Backoff**: Failed lock acquisitions retry automatically with exponential backoff and jitter +- **Lock Expiry**: All locks have TTLs to prevent deadlocks from instance failures -1. **Local Locks** (default) - In-memory locks using Go's `sync.Mutex`, suitable for single-instance deployments -2. **Redis** - Distributed locks using the Redlock algorithm, ideal for HA deployments with existing Redis infrastructure -3. **PostgreSQL Advisory Locks** - Distributed locks using PostgreSQL's native advisory lock feature +1. **Local Locks** (default) - In-memory locks using Go's `sync.Mutex`, suitable for single-instance deployments +1. **Redis** - Distributed locks using the Redlock algorithm, ideal for HA deployments with existing Redis infrastructure +1. **PostgreSQL Advisory Locks** - Distributed locks using PostgreSQL's native advisory lock feature ## Architecture @@ -39,9 +40,9 @@ ncps supports running multiple instances in a high-availability configuration us └─> SQLite Database ``` -* Uses Go's `sync.Mutex` and `sync.RWMutex` for coordination -* No external dependencies required -* Suitable for single-server deployments +- Uses Go's `sync.Mutex` and `sync.RWMutex` for coordination +- No external dependencies required +- Suitable for single-server deployments ### High-Availability Mode @@ -80,10 +81,10 @@ ncps supports running multiple instances in a high-availability configuration us └─────────┘ └───────────┘ ``` -* All instances share the same S3 storage and database -* Redis coordinates locks across instances -* Load balancer distributes traffic -* Instances can be added/removed dynamically +- All instances share the same S3 storage and database +- Redis coordinates locks across instances +- Load balancer distributes traffic +- Instances can be added/removed dynamically ### High-Availability Mode (Database Advisory Locks) @@ -121,11 +122,11 @@ ncps supports running multiple instances in a high-availability configuration us └─────────┘ ``` -* The shared database serves both as the metadata store AND the distributed lock coordinator -* Reduces infrastructure complexity (no Redis needed) -* Uses PostgreSQL's native advisory lock feature (`pg_advisory_lock`) -* All instances share the same S3 storage and database -* Load balancer distributes traffic +- The shared database serves both as the metadata store AND the distributed lock coordinator +- Reduces infrastructure complexity (no Redis needed) +- Uses PostgreSQL's native advisory lock feature (`pg_advisory_lock`) +- All instances share the same S3 storage and database +- Load balancer distributes traffic ## When to Use Distributed Locking @@ -133,41 +134,41 @@ ncps supports running multiple instances in a high-availability configuration us ✅ **Running Multiple Instances** -* Deploying behind a load balancer -* Need zero-downtime updates -* Require failover capability +- Deploying behind a load balancer +- Need zero-downtime updates +- Require failover capability ✅ **High Traffic Environments** -* Handling thousands of concurrent requests -* Need horizontal scaling -* Geographic distribution required +- Handling thousands of concurrent requests +- Need horizontal scaling +- Geographic distribution required ✅ **Production Deployments** -* Business-critical caching infrastructure -* SLA requirements for availability -* Need redundancy and fault tolerance +- Business-critical caching infrastructure +- SLA requirements for availability +- Need redundancy and fault tolerance ### Use Local Locking When: ✅ **Single Server Deployment** -* Running on a single machine -* No redundancy required -* Development/testing environments +- Running on a single machine +- No redundancy required +- Development/testing environments ✅ **Low Traffic Environments** -* Small teams or personal use -* Limited concurrent requests -* Resource-constrained environments +- Small teams or personal use +- Limited concurrent requests +- Resource-constrained environments ✅ **Simplified Operations** -* Want minimal infrastructure -* Distributed lock backend is not necessary -* Prefer embedded solutions (SQLite) +- Want minimal infrastructure +- Distributed lock backend is not necessary +- Prefer embedded solutions (SQLite) ## Configuration Guide @@ -175,16 +176,16 @@ ncps supports running multiple instances in a high-availability configuration us For high-availability mode, you need: -1. **Distributed Lock Backend** (one of the following): - * **Redis** (version 5.0 or later) - * **PostgreSQL** (version 9.1 or later) -2. **Shared Storage** (S3-compatible) - * AWS S3, MinIO, DigitalOcean Spaces, etc. - * All instances must access the same bucket -3. **Shared Database** (PostgreSQL or MySQL) - * PostgreSQL 12+ or MySQL 8.0+ recommended - * All instances must connect to the same database - * SQLite is NOT supported in HA mode +1. **Distributed Lock Backend** (one of the following): + - **Redis** (version 5.0 or later) + - **PostgreSQL** (version 9.1 or later) +1. **Shared Storage** (S3-compatible) + - AWS S3, MinIO, DigitalOcean Spaces, etc. + - All instances must access the same bucket +1. **Shared Database** (PostgreSQL or MySQL) + - PostgreSQL 12+ or MySQL 8.0+ recommended + - All instances must connect to the same database + - SQLite is NOT supported in HA mode ### Basic Configuration @@ -225,9 +226,9 @@ The `--cache-lock-backend` flag determines which mechanism ncps uses to coordina | --- | --- | --- | | `--cache-lock-backend` | Lock backend: `local`, `redis`, or `postgres` | `local` | -* **local**: Uses in-memory locks. Only suitable for single-instance deployments. -* **redis**: Uses Redis (Redlock algorithm). Best for high-traffic, multi-instance deployments. -* **postgres**: Uses PostgreSQL advisory locks. Good balance of simplicity and HA. +- **local**: Uses in-memory locks. Only suitable for single-instance deployments. +- **redis**: Uses Redis (Redlock algorithm). Best for high-traffic, multi-instance deployments. +- **postgres**: Uses PostgreSQL advisory locks. Good balance of simplicity and HA. ### Redis Configuration Options @@ -236,11 +237,11 @@ The `--cache-lock-backend` flag determines which mechanism ncps uses to coordina | Option | Description | Default | | --- | --- | --- | | `--cache-redis-addrs` | Comma-separated Redis addresses | (none - local mode) | -| `--cache-redis-username` | Username for Redis ACL | "" | -| `--cache-redis-password` | Password for authentication | "" | -| `--cache-redis-db` | Database number (0-15) | 0 | +| `--cache-redis-username` | Username for Redis ACL | "" | +| `--cache-redis-password` | Password for authentication | "" | +| `--cache-redis-db` | Database number (0-15) | 0 | | `--cache-redis-use-tls` | Enable TLS connections | false | -| `--cache-redis-pool-size` | Connection pool size | 10 | +| `--cache-redis-pool-size` | Connection pool size | 10 | #### Redis Lock Settings @@ -252,16 +253,16 @@ The `--cache-lock-backend` flag determines which mechanism ncps uses to coordina | Option | Description | Default | | --- | --- | --- | -| `--cache-lock-download-ttl` | Download lock timeout | 5m | +| `--cache-lock-download-ttl` | Download lock timeout | 5m | | `--cache-lock-lru-ttl` | LRU lock timeout | 30m | #### Retry Configuration | Option | Description | Default | | --- | --- | --- | -| `--cache-lock-retry-max-attempts` | Maximum retry attempts | 3 | +| `--cache-lock-retry-max-attempts` | Maximum retry attempts | 3 | | `--cache-lock-retry-initial-delay` | Initial retry delay | 100ms | -| `--cache-lock-retry-max-delay` | Maximum backoff delay | 2s | +| `--cache-lock-retry-max-delay` | Maximum backoff delay | 2s | | `--cache-lock-retry-jitter` | Enable jitter in retries | true | ### Advanced Configuration @@ -294,23 +295,23 @@ The `--cache-lock-backend` flag determines which mechanism ncps uses to coordina Advisory locks provide a distributed locking alternative for deployments that: -* Already use PostgreSQL as the primary database -* Want to minimize infrastructure dependencies (no Redis needed) -* Prefer a single database for both data and coordination +- Already use PostgreSQL as the primary database +- Want to minimize infrastructure dependencies (no Redis needed) +- Prefer a single database for both data and coordination #### Advisory Lock Prerequisites > [!IMPORTANT] > Database advisory locks require PostgreSQL 9.1+. SQLite and MySQL do not support advisory locks in ncps. If you use MySQL as your database, you must use Redis for distributed locking. -1. **Shared Database** (PostgreSQL) - * Version 9.1 or later (12+ recommended) - * Uses native advisory lock functions - * Must be shared across all ncps instances - * Requires no special configuration or extensions -2. **Shared Storage** (S3-compatible) - * Same requirement as Redis mode - * All instances must access the same bucket +1. **Shared Database** (PostgreSQL) + - Version 9.1 or later (12+ recommended) + - Uses native advisory lock functions + - Must be shared across all ncps instances + - Requires no special configuration or extensions +1. **Shared Storage** (S3-compatible) + - Same requirement as Redis mode + - All instances must access the same bucket #### Advisory Lock Configuration (CLI) @@ -359,11 +360,11 @@ These settings apply to both Redis and PostgreSQL backends: | Option | Description | Default | | --- | --- | --- | -| `--cache-lock-download-ttl` | TTL for download locks | 5m | +| `--cache-lock-download-ttl` | TTL for download locks | 5m | | `--cache-lock-lru-ttl` | TTL for LRU cleanup lock | 30m | -| `--cache-lock-retry-max-attempts` | Maximum retry attempts | 3 | +| `--cache-lock-retry-max-attempts` | Maximum retry attempts | 3 | | `--cache-lock-retry-initial-delay` | Initial retry delay | 100ms | -| `--cache-lock-retry-max-delay` | Maximum retry delay (exponential backoff cap) | 2s | +| `--cache-lock-retry-max-delay` | Maximum retry delay (exponential backoff cap) | 2s | | `--cache-lock-retry-jitter` | Enable random jitter in retries | `true` | #### How Advisory Locks Work @@ -386,10 +387,10 @@ SELECT pg_advisory_unlock_shared(key_hash); -- Release shared (read) lock **Key Features:** -* Locks are identified by 64-bit integers (ncps hashes string keys to int64) -* Automatically released when connection closes (prevents deadlocks) -* Native database feature - no configuration or extensions needed -* Same connection must be used for lock() and unlock() +- Locks are identified by 64-bit integers (ncps hashes string keys to int64) +- Automatically released when connection closes (prevents deadlocks) +- Native database feature - no configuration or extensions needed +- Same connection must be used for lock() and unlock() #### Connection Management & Scalability @@ -398,26 +399,26 @@ SELECT pg_advisory_unlock_shared(key_hash); -- Release shared (read) lock PostgreSQL advisory lock implementations in ncps use a **dedicated connection model**: -1. When `Lock(key)` is called, a dedicated connection is pulled from the pool (or created). -2. The lock is acquired on that connection. -3. The connection is **held open** and removed from the pool until `Unlock(key)` is called. +1. When `Lock(key)` is called, a dedicated connection is pulled from the pool (or created). +1. The lock is acquired on that connection. +1. The connection is **held open** and removed from the pool until `Unlock(key)` is called. **Implication:** If your database has `max_connections = 100` and you try to acquire 101 concurrent locks across your cluster, the 101st attempt will fail (and eventually trigger the circuit breaker). **Recommendation:** -* Carefully monitor `pg_stat_activity` or equivalent. -* Ensure your database's `max_connections` is comfortably higher than `(num_instances * max_concurrent_downloads) + (num_instances * pool_size)`. -* If you need thousands of concurrent locks, **use Redis**. +- Carefully monitor `pg_stat_activity` or equivalent. +- Ensure your database's `max_connections` is comfortably higher than `(num_instances * max_concurrent_downloads) + (num_instances * pool_size)`. +- If you need thousands of concurrent locks, **use Redis**. > [!CAUTION] > **Risk of Deadlock with Low Connection Pool Limits** > > When using PostgreSQL advisory locks, a single request that requires a download can consume up to **3 concurrent database connections**: > -> 1. One connection to hold the **shared cache lock** for the duration of the request. -> 2. One connection to hold the **exclusive download lock** while the asset is being pulled. -> 3. One connection for the **database transaction** to store the metadata once the download completes. +> 1. One connection to hold the **shared cache lock** for the duration of the request. +> 1. One connection to hold the **exclusive download lock** while the asset is being pulled. +> 1. One connection for the **database transaction** to store the metadata once the download completes. > > If your connection pool (`--cache-database-pool-max-open-conns`) is too small (e.g., 10), as few as 4-5 concurrent requests can completely exhaust the pool, causing a deadlock where all requests are waiting for a connection to start a transaction while holding locks on other connections. @@ -435,56 +436,56 @@ PostgreSQL advisory lock implementations in ncps use a **dedicated connection mo **Use Redis when:** -* ✅ You already have Redis infrastructure -* ✅ Need the highest performance (Redis is optimized for in-memory operations) -* ✅ Need true read-write lock semantics with high read concurrency -* ✅ Want to use Redis for other purposes (caching, pub/sub) -* ✅ High-traffic deployments with thousands of concurrent requests +- ✅ You already have Redis infrastructure +- ✅ Need the highest performance (Redis is optimized for in-memory operations) +- ✅ Need true read-write lock semantics with high read concurrency +- ✅ Want to use Redis for other purposes (caching, pub/sub) +- ✅ High-traffic deployments with thousands of concurrent requests **Use PostgreSQL Advisory Locks when:** -* ✅ You already use PostgreSQL as the database -* ✅ Want to minimize infrastructure (one less service to manage) -* ✅ Prefer keeping everything in the database -* ✅ Need true shared read locks for concurrent cache access -* ✅ Lock contention is moderate (database locks are fast but not as fast as Redis) -* ✅ Want automatic cleanup when instances crash (connection closes) +- ✅ You already use PostgreSQL as the database +- ✅ Want to minimize infrastructure (one less service to manage) +- ✅ Prefer keeping everything in the database +- ✅ Need true shared read locks for concurrent cache access +- ✅ Lock contention is moderate (database locks are fast but not as fast as Redis) +- ✅ Want automatic cleanup when instances crash (connection closes) **Use Local Locks when:** -* ✅ Running single instance only -* ✅ Development/testing environment -* ✅ No HA requirements +- ✅ Running single instance only +- ✅ Development/testing environment +- ✅ No HA requirements #### Performance Considerations PostgreSQL advisory locks are fast, but not as fast as Redis: -* **Redis** Lock acquisition: ~0.5-2ms -* **PostgreSQL** Lock acquisition: ~1-5ms (depends on database load) +- **Redis** Lock acquisition: ~0.5-2ms +- **PostgreSQL** Lock acquisition: ~1-5ms (depends on database load) For most deployments, PostgreSQL advisory locks provide excellent performance. Redis may be preferred for: -* Very high lock contention (hundreds of locks/second) -* Extremely latency-sensitive workloads -* Geographic distribution with distant database +- Very high lock contention (hundreds of locks/second) +- Extremely latency-sensitive workloads +- Geographic distribution with distant database ### Recommended Stack For best performance, reliability, and scalability in production: -1. **Distributed Locking:** **Redis** - * Why: Decouples locking load from your primary database. Handles thousands of concurrent locks with minimal connection overhead. -2. **Metadata Database:** **PostgreSQL** - * Why: Robust, transactional reliability for cache metadata. -3. **Storage:** **S3 (AWS or MinIO)** - * Why: Infinite scalability for binary artifacts. +1. **Distributed Locking:** **Redis** + - Why: Decouples locking load from your primary database. Handles thousands of concurrent locks with minimal connection overhead. +1. **Metadata Database:** **PostgreSQL** + - Why: Robust, transactional reliability for cache metadata. +1. **Storage:** **S3 (AWS or MinIO)** + - Why: Infinite scalability for binary artifacts. **Use Database Advisory Locks only if:** -* You cannot maintain a functional Redis setup. -* Your concurrency is low (< 100 concurrent downloads cluster-wide). -* You want strict "single dependency" simplicity over scalability. +- You cannot maintain a functional Redis setup. +- Your concurrency is low (< 100 concurrent downloads cluster-wide). +- You want strict "single dependency" simplicity over scalability. ## How It Works @@ -492,7 +493,7 @@ For best performance, reliability, and scalability in production: ncps uses two types of distributed locks: -#### 1\. Download Locks (Exclusive) +#### 1. Download Locks (Exclusive) **Purpose:** Prevent duplicate downloads of the same package @@ -503,14 +504,14 @@ ncps uses two types of distributed locks: **Behavior:** -* When instance A starts downloading a package, it acquires the lock -* Instance B requesting the same package will retry acquiring the lock -* Once instance A completes the download, it releases the lock -* Instance B then reads the package from shared storage (no download needed) +- When instance A starts downloading a package, it acquires the lock +- Instance B requesting the same package will retry acquiring the lock +- Once instance A completes the download, it releases the lock +- Instance B then reads the package from shared storage (no download needed) **TTL:** 5 minutes (configurable via `--cache-lock-download-ttl`) -#### 2\. LRU Lock (Exclusive) +#### 2. LRU Lock (Exclusive) **Purpose:** Coordinate cache cleanup across instances @@ -518,10 +519,10 @@ ncps uses two types of distributed locks: **Behavior:** -* Uses `TryLock()` - non-blocking acquisition -* If locked, the instance skips LRU and tries again next cycle -* Only one instance runs LRU cleanup at a time -* Prevents concurrent deletions that could corrupt the cache +- Uses `TryLock()` - non-blocking acquisition +- If locked, the instance skips LRU and tries again next cycle +- Only one instance runs LRU cleanup at a time +- Prevents concurrent deletions that could corrupt the cache **TTL:** 30 minutes (configurable via `--cache-lock-lru-ttl`) @@ -529,9 +530,9 @@ ncps uses two types of distributed locks: ncps uses the [Redlock algorithm](https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/) via [go-redsync](https://github.com/go-redsync/redsync): -1. **Acquire**: Try to SET with NX (only if not exists) and PX (expiry time) -2. **Release**: Delete the key when operation completes -3. **Expire**: Lock auto-expires after TTL if instance crashes (important for long-running downloads) +1. **Acquire**: Try to SET with NX (only if not exists) and PX (expiry time) +1. **Release**: Delete the key when operation completes +1. **Expire**: Lock auto-expires after TTL if instance crashes (important for long-running downloads) **Note**: Lock extension is not currently implemented. The TTL should be set long enough to accommodate the longest expected download operation. @@ -555,9 +556,9 @@ actual_delay = delay + random(0, delay * jitter_factor) **Why Jitter?** -* Prevents thundering herd when lock is released -* Distributes retry attempts across time -* Improves fairness in lock acquisition +- Prevents thundering herd when lock is released +- Distributes retry attempts across time +- Improves fairness in lock acquisition ### Cache Access Protection @@ -591,19 +592,19 @@ Read operations (GetNar, GetNarInfo) acquire read locks to prevent the LRU from The following OpenTelemetry metrics will be available for monitoring lock operations: -* `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisition attempts - * `type`: "download" or "lru" - * `result`: "success" or "failure" - * `mode`: "local" or "distributed" -* `ncps_lock_hold_duration_seconds{type,mode}` - Time locks are held - * Histogram of lock hold times - * Helps identify slow operations -* `ncps_lock_failures_total{type,reason,mode}` - Lock failures - * `reason`: "timeout", "redis\_error", "circuit\_breaker" - * Indicates infrastructure issues -* `ncps_lock_retry_attempts_total{type}` - Retry attempts before success/failure - * Shows lock contention levels - * High values indicate scaling needs +- `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisition attempts + - `type`: "download" or "lru" + - `result`: "success" or "failure" + - `mode`: "local" or "distributed" +- `ncps_lock_hold_duration_seconds{type,mode}` - Time locks are held + - Histogram of lock hold times + - Helps identify slow operations +- `ncps_lock_failures_total{type,reason,mode}` - Lock failures + - `reason`: "timeout", "redis_error", "circuit_breaker" + - Indicates infrastructure issues +- `ncps_lock_retry_attempts_total{type}` - Retry attempts before success/failure + - Shows lock contention levels + - High values indicate scaling needs ### Logging @@ -622,10 +623,10 @@ ncps logs lock operations with structured fields: **Important log messages:** -* `acquired download lock` - Successfully acquired lock for download -* `failed to acquire lock` - Lock acquisition failed after retries -* `another instance is running LRU` - LRU skipped (another instance running) -* `circuit breaker open: Redis is unavailable` - Redis connectivity issues +- `acquired download lock` - Successfully acquired lock for download +- `failed to acquire lock` - Lock acquisition failed after retries +- `another instance is running LRU` - LRU skipped (another instance running) +- `circuit breaker open: Redis is unavailable` - Redis connectivity issues ### Health Checks @@ -667,10 +668,10 @@ grep "acquired download lock" /var/log/ncps.log | wc -l **Common Causes:** -1. **Redis not configured** - Verify `--cache-redis-addrs` is set -2. **Network issues** - Check firewall rules, DNS resolution -3. **Redis authentication** - Verify username/password if ACL is enabled -4. **Different key prefixes** - Ensure all instances use the same `--cache-lock-redis-key-prefix` +1. **Redis not configured** - Verify `--cache-redis-addrs` is set +1. **Network issues** - Check firewall rules, DNS resolution +1. **Redis authentication** - Verify username/password if ACL is enabled +1. **Different key prefixes** - Ensure all instances use the same `--cache-lock-redis-key-prefix` **Solution:** @@ -702,18 +703,20 @@ redis-cli --scan --pattern "ncps:lock:download:*" | wc -l **Solutions:** -1. **Increase retry settings:** +1. **Increase retry settings:** + + ``` + --cache-lock-retry-max-attempts=5 \ + --cache-lock-retry-max-delay=5s + ``` + +1. **Scale down instances** (if too many instances competing) - ``` - --cache-lock-retry-max-attempts=5 \ - --cache-lock-retry-max-delay=5s - ``` -2. **Scale down instances** (if too many instances competing) -3. **Increase lock TTL** for long-running operations: +1. **Increase lock TTL** for long-running operations: - ``` - --cache-lock-download-ttl=10m - ``` + ``` + --cache-lock-download-ttl=10m + ``` ### LRU Not Running @@ -734,8 +737,8 @@ redis-cli GET "ncps:lock:lru" **Common Causes:** -1. **LRU lock stuck** - Lock held by crashed instance -2. **All instances skipping** - Each thinks another is running +1. **LRU lock stuck** - Lock held by crashed instance +1. **All instances skipping** - Each thinks another is running **Solution:** @@ -766,21 +769,23 @@ nc -zv redis-host 6379 **Solutions:** -1. **Verify Redis is running:** +1. **Verify Redis is running:** - ``` - systemctl start redis - ``` -2. **Check firewall rules:** + ``` + systemctl start redis + ``` - ``` - sudo iptables -L | grep 6379 - ``` -3. **Verify TLS configuration** if using `--cache-redis-use-tls`: +1. **Check firewall rules:** - ``` - openssl s_client -connect redis-host:6380 - ``` + ``` + sudo iptables -L | grep 6379 + ``` + +1. **Verify TLS configuration** if using `--cache-redis-use-tls`: + + ``` + openssl s_client -connect redis-host:6380 + ``` ## Performance Tuning @@ -788,43 +793,43 @@ nc -zv redis-host 6379 **Download Lock TTL** (`--cache-lock-download-ttl`): -* **Default:** 5 minutes -* **Increase if:** Large packages take longer to download -* **Decrease if:** Most downloads complete quickly (reduces stuck lock impact) +- **Default:** 5 minutes +- **Increase if:** Large packages take longer to download +- **Decrease if:** Most downloads complete quickly (reduces stuck lock impact) **LRU Lock TTL** (`--cache-lock-lru-ttl`): -* **Default:** 30 minutes -* **Increase if:** LRU cleanup takes longer (very large caches) -* **Decrease if:** Want faster failover if instance crashes during LRU +- **Default:** 30 minutes +- **Increase if:** LRU cleanup takes longer (very large caches) +- **Decrease if:** Want faster failover if instance crashes during LRU ### Retry Configuration **Max Attempts** (`--cache-lock-retry-max-attempts`): -* **Default:** 3 -* **Increase if:** High lock contention (many instances) -* **Decrease if:** Want faster failure feedback +- **Default:** 3 +- **Increase if:** High lock contention (many instances) +- **Decrease if:** Want faster failure feedback **Initial Delay** (`--cache-lock-retry-initial-delay`): -* **Default:** 100ms -* **Increase if:** Redis is slow or distant -* **Decrease if:** Redis is fast and local +- **Default:** 100ms +- **Increase if:** Redis is slow or distant +- **Decrease if:** Redis is fast and local **Max Delay** (`--cache-lock-retry-max-delay`): -* **Default:** 2s -* **Increase if:** Locks are held for long periods -* **Decrease if:** Want faster failure +- **Default:** 2s +- **Increase if:** Locks are held for long periods +- **Decrease if:** Want faster failure ### Redis Pool Size **Pool Size** (`--cache-redis-pool-size`): -* **Default:** 10 connections per instance -* **Increase if:** High concurrent download requests -* **Decrease if:** Running many instances (to reduce Redis load) +- **Default:** 10 connections per instance +- **Increase if:** High concurrent download requests +- **Decrease if:** Running many instances (to reduce Redis load) **Formula:** `total_connections = instances * pool_size` @@ -834,56 +839,56 @@ nc -zv redis-host 6379 ### Deployment -1. **Start Redis First** - * Ensure Redis is healthy before starting ncps instances - * Use health checks in orchestration (Kubernetes, Docker Compose) -2. **Gradual Rollout** - * Update instances one at a time - * Verify each instance is healthy before updating the next - * Monitor lock metrics during rollout -3. **Load Balancer Configuration** - * Use health check endpoint: `GET /pubkey` - * Configure session affinity if needed (not required) - * Set reasonable timeouts (downloads can be large) -4. **Shared Storage** - * Ensure all instances have identical S3 configuration - * Use IAM roles or credentials with proper permissions - * Enable S3 server-side encryption for security -5. **Database** - * Use connection pooling in PostgreSQL - * Configure appropriate timeouts - * Monitor connection counts +1. **Start Redis First** + - Ensure Redis is healthy before starting ncps instances + - Use health checks in orchestration (Kubernetes, Docker Compose) +1. **Gradual Rollout** + - Update instances one at a time + - Verify each instance is healthy before updating the next + - Monitor lock metrics during rollout +1. **Load Balancer Configuration** + - Use health check endpoint: `GET /pubkey` + - Configure session affinity if needed (not required) + - Set reasonable timeouts (downloads can be large) +1. **Shared Storage** + - Ensure all instances have identical S3 configuration + - Use IAM roles or credentials with proper permissions + - Enable S3 server-side encryption for security +1. **Database** + - Use connection pooling in PostgreSQL + - Configure appropriate timeouts + - Monitor connection counts ### Monitoring -1. **Key Metrics to Watch** - * Lock acquisition latency - * Retry attempt rates - * Redis connectivity - * Cache hit rates -2. **Alerting** - * Alert on high lock failures - * Alert on Redis unavailability - * Alert on excessive retry attempts -3. **Logging** - * Centralize logs (ELK, Loki, CloudWatch) - * Include structured fields for filtering - * Set appropriate log levels +1. **Key Metrics to Watch** + - Lock acquisition latency + - Retry attempt rates + - Redis connectivity + - Cache hit rates +1. **Alerting** + - Alert on high lock failures + - Alert on Redis unavailability + - Alert on excessive retry attempts +1. **Logging** + - Centralize logs (ELK, Loki, CloudWatch) + - Include structured fields for filtering + - Set appropriate log levels ### Operations -1. **Backup Strategy** - * Redis: Optional (locks are ephemeral) - * Database: Regular backups (contains metadata) - * S3: Enable versioning for disaster recovery -2. **Scaling** - * Add instances during high traffic - * Remove instances during maintenance - * Monitor for lock contention when scaling -3. **Maintenance** - * Update one instance at a time - * Redis can be restarted (locks will regenerate) - * Database migrations should be backward-compatible +1. **Backup Strategy** + - Redis: Optional (locks are ephemeral) + - Database: Regular backups (contains metadata) + - S3: Enable versioning for disaster recovery +1. **Scaling** + - Add instances during high traffic + - Remove instances during maintenance + - Monitor for lock contention when scaling +1. **Maintenance** + - Update one instance at a time + - Redis can be restarted (locks will regenerate) + - Database migrations should be backward-compatible ## Migration Guide @@ -891,59 +896,65 @@ nc -zv redis-host 6379 **Prerequisites:** -1. ✅ Set up PostgreSQL database -2. ✅ Migrate from SQLite (if applicable) -3. ✅ Set up S3-compatible storage -4. ✅ Deploy Redis server +1. ✅ Set up PostgreSQL database +1. ✅ Migrate from SQLite (if applicable) +1. ✅ Set up S3-compatible storage +1. ✅ Deploy Redis server **Migration Steps:** -1. **Migrate to S3 Storage:** +1. **Migrate to S3 Storage:** + + ``` + # Sync local storage to S3 + aws s3 sync /var/lib/ncps/storage s3://ncps-cache/ + ``` - ``` - # Sync local storage to S3 - aws s3 sync /var/lib/ncps/storage s3://ncps-cache/ - ``` -2. **Migrate Database:** +1. **Migrate Database:** - ``` - # Export SQLite data - sqlite3 ncps.db .dump > backup.sql + ``` + # Export SQLite data + sqlite3 ncps.db .dump > backup.sql - # Import to PostgreSQL (after schema conversion) - psql ncps < converted.sql - ``` -3. **Configure First Instance:** + # Import to PostgreSQL (after schema conversion) + psql ncps < converted.sql + ``` - ``` - ncps serve \ - --cache-database-url=postgresql://... \ - --cache-storage-s3-bucket=ncps-cache \ - --cache-redis-addrs=redis:6379 - ``` -4. **Verify Functionality:** +1. **Configure First Instance:** - * Test package downloads - * Check Redis for lock keys - * Verify cache hits -5. **Add Additional Instances:** + ``` + ncps serve \ + --cache-database-url=postgresql://... \ + --cache-storage-s3-bucket=ncps-cache \ + --cache-redis-addrs=redis:6379 + ``` - * Use identical configuration - * Point to same Redis, S3, and database - * Add to load balancer +1. **Verify Functionality:** + + - Test package downloads + - Check Redis for lock keys + - Verify cache hits + +1. **Add Additional Instances:** + + - Use identical configuration + - Point to same Redis, S3, and database + - Add to load balancer ### Rollback Plan If issues occur: -1. **Stop new instances** (keep first instance) -2. **Continue using first instance** with Redis -3. **Or temporarily disable Redis:** +1. **Stop new instances** (keep first instance) + +1. **Continue using first instance** with Redis + +1. **Or temporarily disable Redis:** - ``` - # Remove --cache-redis-addrs flag - # Falls back to local locks - ``` + ``` + # Remove --cache-redis-addrs flag + # Falls back to local locks + ``` **Note:** Rollback from S3 to local storage requires data sync: @@ -951,20 +962,20 @@ If issues occur: aws s3 sync s3://ncps-cache/ /var/lib/ncps/storage ``` ---- +______________________________________________________________________ ## Additional Resources -* **Redis Official Documentation:** [https://redis.io/docs/](https://redis.io/docs/) -* **Redlock Algorithm:** [https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/](https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/) -* **go-redsync Library:** [https://github.com/go-redsync/redsync](https://github.com/go-redsync/redsync) -* **ncps Configuration Reference:** See [`config.example.yaml`](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) -* **High Availability Best Practices:** AWS Well-Architected Framework +- **Redis Official Documentation:** [https://redis.io/docs/](https://redis.io/docs/) +- **Redlock Algorithm:** [https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/](https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/) +- **go-redsync Library:** [https://github.com/go-redsync/redsync](https://github.com/go-redsync/redsync) +- **ncps Configuration Reference:** See [`config.example.yaml`](https://github.com/kalbasit/ncps/blob/main/config.example.yaml) +- **High Availability Best Practices:** AWS Well-Architected Framework ## Support For issues or questions: -* **GitHub Issues:** [https://github.com/kalbasit/ncps/issues](https://github.com/kalbasit/ncps/issues) -* **Discussions:** [https://github.com/kalbasit/ncps/discussions](https://github.com/kalbasit/ncps/discussions) -* **CONTRIBUTING.md:** Development and testing guide \ No newline at end of file +- **GitHub Issues:** [https://github.com/kalbasit/ncps/issues](https://github.com/kalbasit/ncps/issues) +- **Discussions:** [https://github.com/kalbasit/ncps/discussions](https://github.com/kalbasit/ncps/discussions) +- **CONTRIBUTING.md:** Development and testing guide diff --git a/docs/docs/User Guide/Deployment/High Availability.md b/docs/docs/User Guide/Deployment/High Availability.md index 477c84c5..80700613 100644 --- a/docs/docs/User Guide/Deployment/High Availability.md +++ b/docs/docs/User Guide/Deployment/High Availability.md @@ -1,4 +1,5 @@ -# High Availability +# High Availability + ## High Availability Deployment Deploy multiple ncps instances for zero-downtime operation, load distribution, and redundancy. @@ -7,11 +8,11 @@ Deploy multiple ncps instances for zero-downtime operation, load distribution, a Running multiple ncps instances provides: -* ✅ **Zero Downtime** - Instance failures don't interrupt service -* ✅ **Load Distribution** - Requests spread across multiple servers -* ✅ **Horizontal Scaling** - Add instances to handle more traffic -* ✅ **Geographic Distribution** - Deploy instances closer to clients -* ✅ **Rolling Updates** - Update instances one at a time without downtime +- ✅ **Zero Downtime** - Instance failures don't interrupt service +- ✅ **Load Distribution** - Requests spread across multiple servers +- ✅ **Horizontal Scaling** - Add instances to handle more traffic +- ✅ **Geographic Distribution** - Deploy instances closer to clients +- ✅ **Rolling Updates** - Update instances one at a time without downtime ## Architecture @@ -46,26 +47,26 @@ Running multiple ncps instances provides: ### Required Components -1. **Multiple ncps instances** (2+, recommended 3+) -2. **Distributed locking backend** - * **Redis server** (version 5.0+) - * **PostgreSQL advisory locks** (version 9.1+) -3. **S3-compatible storage** (shared across all instances) - * AWS S3, MinIO, DigitalOcean Spaces, etc. -4. **PostgreSQL or MySQL database** (shared across all instances) - * PostgreSQL 12+ or MySQL 8.0+ - * **SQLite is NOT supported for HA** - * **NOTE: MySQL is only supported for data storage, NOT for distributed locking. If using MySQL, you must use Redis for locking.** -5. **Load balancer** to distribute requests - * nginx, HAProxy, cloud load balancer, etc. +1. **Multiple ncps instances** (2+, recommended 3+) +1. **Distributed locking backend** + - **Redis server** (version 5.0+) + - **PostgreSQL advisory locks** (version 9.1+) +1. **S3-compatible storage** (shared across all instances) + - AWS S3, MinIO, DigitalOcean Spaces, etc. +1. **PostgreSQL or MySQL database** (shared across all instances) + - PostgreSQL 12+ or MySQL 8.0+ + - **SQLite is NOT supported for HA** + - **NOTE: MySQL is only supported for data storage, NOT for distributed locking. If using MySQL, you must use Redis for locking.** +1. **Load balancer** to distribute requests + - nginx, HAProxy, cloud load balancer, etc. ### Network Requirements -* All instances must reach Redis -* All instances must reach S3 storage -* All instances must reach shared database -* Load balancer must reach all instances -* Clients reach load balancer +- All instances must reach Redis +- All instances must reach S3 storage +- All instances must reach shared database +- Load balancer must reach all instances +- Clients reach load balancer ## Quick Start @@ -318,29 +319,29 @@ ncps uses Redis to coordinate multiple instances: When multiple instances request the same package: -1. Instance A acquires download lock for hash `abc123` -2. Instance B tries to download same package -3. Instance B cannot acquire lock (Instance A holds it) -4. Instance B retries with exponential backoff -5. Instance A completes download and releases lock -6. Instance B acquires lock, finds package in S3, serves it -7. Result: Only one download from upstream +1. Instance A acquires download lock for hash `abc123` +1. Instance B tries to download same package +1. Instance B cannot acquire lock (Instance A holds it) +1. Instance B retries with exponential backoff +1. Instance A completes download and releases lock +1. Instance B acquires lock, finds package in S3, serves it +1. Result: Only one download from upstream ### LRU Coordination Only one instance runs cache cleanup at a time: -1. Instances try to acquire global LRU lock -2. First instance to acquire lock runs LRU -3. Other instances skip LRU (lock held) -4. After cleanup, lock is released -5. Next scheduled LRU cycle, another instance may acquire lock +1. Instances try to acquire global LRU lock +1. First instance to acquire lock runs LRU +1. Other instances skip LRU (lock held) +1. After cleanup, lock is released +1. Next scheduled LRU cycle, another instance may acquire lock **Benefits:** -* Prevents concurrent deletions -* Avoids cache corruption -* Distributes LRU load +- Prevents concurrent deletions +- Avoids cache corruption +- Distributes LRU load See Distributed Locking for technical details and database advisory lock configuration (PostgreSQL). @@ -414,11 +415,11 @@ spec: ### Key Metrics -* **Instance health**: Up/down status -* **Lock acquisition rate**: Download and LRU locks -* **Lock contention**: Retry attempts -* **Redis connectivity**: Connection status -* **Cache hit rate**: Per-instance and aggregate +- **Instance health**: Up/down status +- **Lock acquisition rate**: Download and LRU locks +- **Lock contention**: Retry attempts +- **Redis connectivity**: Connection status +- **Cache hit rate**: Per-instance and aggregate ### Example Prometheus Queries @@ -461,9 +462,9 @@ grep "acquired download lock" /var/log/ncps.log **Solutions:** -1. Increase retry settings -2. Increase lock TTLs for long operations -3. Scale down instances if too many +1. Increase retry settings +1. Increase lock TTLs for long operations +1. Scale down instances if too many See Distributed Locking for detailed troubleshooting. @@ -471,21 +472,21 @@ See Distributed Locki ### Prerequisites -1. ✅ Set up PostgreSQL or MySQL database -2. ✅ Migrate from SQLite (if applicable) -3. ✅ Set up S3-compatible storage -4. ✅ Deploy Redis server +1. ✅ Set up PostgreSQL or MySQL database +1. ✅ Migrate from SQLite (if applicable) +1. ✅ Set up S3-compatible storage +1. ✅ Deploy Redis server ### Migration Steps -**1\. Migrate to S3 Storage:** +**1. Migrate to S3 Storage:** ``` # Sync local storage to S3 aws s3 sync /var/lib/ncps s3://ncps-cache/ ``` -**2\. Migrate Database:** +**2. Migrate Database:** ``` # Export SQLite data @@ -496,45 +497,45 @@ pgloader sqlite:///var/lib/ncps/db/db.sqlite \ postgresql://ncps:password@localhost:5432/ncps ``` -**3\. Configure First Instance:** +**3. Configure First Instance:** ```yaml # Update config.yaml to use S3 and PostgreSQL # Add Redis configuration ``` -**4\. Verify Functionality:** +**4. Verify Functionality:** -* Test package downloads -* Check Redis for lock keys -* Verify cache hits +- Test package downloads +- Check Redis for lock keys +- Verify cache hits -**5\. Add Additional Instances:** +**5. Add Additional Instances:** -* Use identical configuration -* Point to same Redis, S3, and database -* Add to load balancer +- Use identical configuration +- Point to same Redis, S3, and database +- Add to load balancer ## Best Practices -1. **Start Redis First** - Ensure Redis is healthy before starting ncps instances -2. **Use Health Checks** - Configure load balancer health checks -3. **Monitor Lock Metrics** - Watch for contention and failures -4. **Plan Capacity** - 3+ instances recommended for true HA -5. **Test Failover** - Regularly test instance failures -6. **Centralize Logs** - Use log aggregation for troubleshooting -7. **Set Up Alerts** - Alert on high lock failures, Redis unavailability +1. **Start Redis First** - Ensure Redis is healthy before starting ncps instances +1. **Use Health Checks** - Configure load balancer health checks +1. **Monitor Lock Metrics** - Watch for contention and failures +1. **Plan Capacity** - 3+ instances recommended for true HA +1. **Test Failover** - Regularly test instance failures +1. **Centralize Logs** - Use log aggregation for troubleshooting +1. **Set Up Alerts** - Alert on high lock failures, Redis unavailability ## Next Steps -1. Client Setup - Set up Nix clients -2. Distributed Locking - Understand locking in depth -3. Monitoring - Configure observability -4. Operations - Learn about backups, upgrades +1. Client Setup - Set up Nix clients +1. Distributed Locking - Understand locking in depth +1. Monitoring - Configure observability +1. Operations - Learn about backups, upgrades ## Related Documentation -* Distributed Locking - Deep dive into Redis locking -* Helm Chart - Simplified HA deployment -* Reference - All HA options -* Monitoring - HA-specific monitoring \ No newline at end of file +- Distributed Locking - Deep dive into Redis locking +- Helm Chart - Simplified HA deployment +- Reference - All HA options +- Monitoring - HA-specific monitoring diff --git a/docs/docs/User Guide/Deployment/Single Instance.md b/docs/docs/User Guide/Deployment/Single Instance.md index edaf7755..ee90875d 100644 --- a/docs/docs/User Guide/Deployment/Single Instance.md +++ b/docs/docs/User Guide/Deployment/Single Instance.md @@ -1,4 +1,5 @@ -# Single Instance +# Single Instance + ## Single-Instance Deployment Deploy ncps as a single server for simplified operations and maintenance. @@ -7,11 +8,11 @@ Deploy ncps as a single server for simplified operations and maintenance. Single-instance deployment is ideal for: -* **Development and testing environments** -* **Small to medium teams** (1-100+ users) -* **Single-location deployments** -* **Simpler operational requirements** -* **Cost-conscious deployments** +- **Development and testing environments** +- **Small to medium teams** (1-100+ users) +- **Single-location deployments** +- **Simpler operational requirements** +- **Cost-conscious deployments** ## Architecture @@ -41,15 +42,15 @@ Single-instance deployment is ideal for: **Pros:** -* Simple setup -* Fast (local I/O) -* No external dependencies +- Simple setup +- Fast (local I/O) +- No external dependencies **Cons:** -* Limited to server disk size -* No redundancy -* Cannot scale to HA +- Limited to server disk size +- No redundancy +- Cannot scale to HA **Configuration:** @@ -65,15 +66,15 @@ cache: **Pros:** -* Scalable storage -* Easy migration to HA later -* Built-in redundancy +- Scalable storage +- Easy migration to HA later +- Built-in redundancy **Cons:** -* Requires S3 service -* Slight latency overhead -* Additional cost (if using cloud S3) +- Requires S3 service +- Slight latency overhead +- Additional cost (if using cloud S3) **Configuration:** @@ -97,14 +98,14 @@ cache: **Pros:** -* No external service required -* Zero configuration -* Perfect for single instance +- No external service required +- Zero configuration +- Perfect for single instance **Cons:** -* Cannot be used for HA -* Single connection limit +- Cannot be used for HA +- Single connection limit **Configuration:** @@ -117,14 +118,14 @@ cache: **Pros:** -* Better performance under load -* Easier migration to HA later -* Better concurrent access +- Better performance under load +- Easier migration to HA later +- Better concurrent access **Cons:** -* Requires PostgreSQL service -* More complex setup +- Requires PostgreSQL service +- More complex setup **Configuration:** @@ -204,27 +205,27 @@ prometheus: ### Minimum -* **CPU**: 2 cores -* **RAM**: 4GB -* **Disk**: 50GB (for local storage) -* **Network**: 100Mbps +- **CPU**: 2 cores +- **RAM**: 4GB +- **Disk**: 50GB (for local storage) +- **Network**: 100Mbps ### Recommended -* **CPU**: 4+ cores -* **RAM**: 8GB+ -* **Disk**: 200GB-1TB (for local storage) -* **Network**: 1Gbps +- **CPU**: 4+ cores +- **RAM**: 8GB+ +- **Disk**: 200GB-1TB (for local storage) +- **Network**: 1Gbps ## Installation Methods Choose your preferred installation method: -* Docker - Quickest setup -* Docker Compose - Automated deployment -* Nixos - Native NixOS integration -* Kubernetes - For K8s environments -* Helm - Simplified K8s deployment +- Docker - Quickest setup +- Docker Compose - Automated deployment +- Nixos - Native NixOS integration +- Kubernetes - For K8s environments +- Helm - Simplified K8s deployment ## Deployment Checklist @@ -269,10 +270,10 @@ See Monitoring Single-instance deployments have these limitations: -* **No redundancy**: Server downtime = cache downtime -* **No load distribution**: One server handles all requests -* **No zero-downtime updates**: Updates require service restart -* **Limited scalability**: Cannot add more instances +- **No redundancy**: Server downtime = cache downtime +- **No load distribution**: One server handles all requests +- **No zero-downtime updates**: Updates require service restart +- **Limited scalability**: Cannot add more instances **When you outgrow single-instance:** See High Availability for migration. @@ -318,15 +319,15 @@ See the Troub ## Next Steps -1. Client Setup - Set up Nix clients -2. Monitoring - Set up observability -3. Operations - Learn about backups, upgrades, etc. -4. **Consider** High Availability - When you need to scale +1. Client Setup - Set up Nix clients +1. Monitoring - Set up observability +1. Operations - Learn about backups, upgrades, etc. +1. **Consider** High Availability - When you need to scale ## Related Documentation -* Installation - Installation methods -* Reference - All configuration options -* Storage - Storage backend details -* Database - Database backend details -* High Availability - Migrate to HA when needed \ No newline at end of file +- Installation - Installation methods +- Reference - All configuration options +- Storage - Storage backend details +- Database - Database backend details +- High Availability - Migrate to HA when needed diff --git a/docs/docs/User Guide/Getting Started.md b/docs/docs/User Guide/Getting Started.md index 105d9970..ccb01d4e 100644 --- a/docs/docs/User Guide/Getting Started.md +++ b/docs/docs/User Guide/Getting Started.md @@ -1,12 +1,13 @@ -# Getting Started +# Getting Started + ## Getting Started with ncps This section will help you get up and running with ncps quickly and understand the core concepts. ## Quick Links -* Quick Start - Get ncps running in minutes with Docker -* Concepts - Understand how ncps works and why to use it +- Quick Start - Get ncps running in minutes with Docker +- Concepts - Understand how ncps works and why to use it ## What You'll Learn @@ -14,46 +15,46 @@ This section will help you get up and running with ncps quickly and understand t Learn how to: -* Install ncps with Docker in minutes -* Run with local storage (simplest setup) -* Run with S3 storage (scalable setup) -* Verify your installation works -* Get the public key for client configuration +- Install ncps with Docker in minutes +- Run with local storage (simplest setup) +- Run with S3 storage (scalable setup) +- Verify your installation works +- Get the public key for client configuration ### Core Concepts Understand: -* What ncps is and the problems it solves -* How the request flow works -* Storage architecture (local vs S3) -* Database options (SQLite, PostgreSQL, MySQL) -* When to use single-instance vs high-availability mode +- What ncps is and the problems it solves +- How the request flow works +- Storage architecture (local vs S3) +- Database options (SQLite, PostgreSQL, MySQL) +- When to use single-instance vs high-availability mode ## Next Steps After completing the getting started guides: -1. **Installation** - Choose your [installation method](Installation.md) -2. **Configuration** - Review the [configuration options](Configuration/Reference.md) -3. **Client Setup** - Configure your [Nix clients](Usage/Client%20Setup.md) -4. **Deployment** - Plan your [deployment strategy](Deployment.md) +1. **Installation** - Choose your [installation method](Installation.md) +1. **Configuration** - Review the [configuration options](Configuration/Reference.md) +1. **Client Setup** - Configure your [Nix clients](Usage/Client%20Setup.md) +1. **Deployment** - Plan your [deployment strategy](Deployment.md) ## Common Questions **Do I need Redis?** -* No, not for single-instance deployments -* Yes, for high-availability with multiple instances +- No, not for single-instance deployments +- Yes, for high-availability with multiple instances **Should I use S3 or local storage?** -* Local storage: Simple, single-instance deployments -* S3 storage: Multi-instance HA deployments or cloud-native setups +- Local storage: Simple, single-instance deployments +- S3 storage: Multi-instance HA deployments or cloud-native setups **Which database should I use?** -* SQLite: Simple, single-instance deployments -* PostgreSQL/MySQL: Multi-instance HA deployments +- SQLite: Simple, single-instance deployments +- PostgreSQL/MySQL: Multi-instance HA deployments -See Concepts for detailed explanations. \ No newline at end of file +See Concepts for detailed explanations. diff --git a/docs/docs/User Guide/Getting Started/Concepts.md b/docs/docs/User Guide/Getting Started/Concepts.md index 31d78a08..bc3fbece 100644 --- a/docs/docs/User Guide/Getting Started/Concepts.md +++ b/docs/docs/User Guide/Getting Started/Concepts.md @@ -1,4 +1,5 @@ -# Concepts +# Concepts + ## Core Concepts This guide explains what ncps is, the problems it solves, and how it works under the hood. @@ -11,28 +12,28 @@ ncps (Nix Cache Proxy Server) is a high-performance proxy server that acts as a When multiple machines running NixOS or Nix pull packages, they often download the same dependencies from remote caches, leading to: -* **Redundant downloads** - Each machine downloads identical files -* **High bandwidth usage** - Significant network traffic for large projects -* **Slower build times** - Network latency impacts development velocity -* **Internet dependency** - Every build requires external connectivity +- **Redundant downloads** - Each machine downloads identical files +- **High bandwidth usage** - Significant network traffic for large projects +- **Slower build times** - Network latency impacts development velocity +- **Internet dependency** - Every build requires external connectivity ### Real-World Example Imagine a team of 10 developers all working on the same Nix-based project: -* A large dependency (500MB) gets updated -* Without ncps: 10 machines × 500MB = 5GB of internet bandwidth used -* With ncps: 500MB downloaded once from internet, then served locally 9 times +- A large dependency (500MB) gets updated +- Without ncps: 10 machines × 500MB = 5GB of internet bandwidth used +- With ncps: 500MB downloaded once from internet, then served locally 9 times ## The Solution ncps solves these issues by acting as a **centralized cache** on your local network: -1. **Single Download**: Package downloaded once from upstream -2. **Local Distribution**: Served to all local machines from cache -3. **Bandwidth Savings**: Dramatic reduction in internet usage -4. **Faster Builds**: Local network speeds vs internet speeds -5. **Offline Capability**: Cached packages available without internet +1. **Single Download**: Package downloaded once from upstream +1. **Local Distribution**: Served to all local machines from cache +1. **Bandwidth Savings**: Dramatic reduction in internet usage +1. **Faster Builds**: Local network speeds vs internet speeds +1. **Offline Capability**: Cached packages available without internet ## How It Works @@ -65,15 +66,15 @@ ncps solves these issues by acting as a **centralized cache** on your local netw **Step-by-step:** -1. **Request** - Nix client requests a store path (e.g., `/nix/store/abc123-package`) -2. **Cache Check** - ncps checks if NarInfo metadata exists in database -3. **Cache Hit** - If cached, serve directly from storage -4. **Cache Miss** - If not cached: - * Fetch NarInfo and NAR from upstream cache - * Store NAR file in storage backend - * Store NarInfo metadata in database - * Sign NarInfo with ncps private key -5. **Serve** - Deliver the path to the requesting client +1. **Request** - Nix client requests a store path (e.g., `/nix/store/abc123-package`) +1. **Cache Check** - ncps checks if NarInfo metadata exists in database +1. **Cache Hit** - If cached, serve directly from storage +1. **Cache Miss** - If not cached: + - Fetch NarInfo and NAR from upstream cache + - Store NAR file in storage backend + - Store NarInfo metadata in database + - Sign NarInfo with ncps private key +1. **Serve** - Deliver the path to the requesting client ### Storage Architecture @@ -98,16 +99,16 @@ ncps uses a flexible storage architecture with separate components for different Stores metadata about cached packages: -* **SQLite** (default): Embedded, no external dependencies, single-instance only -* **PostgreSQL**: Production-ready, supports concurrent access, required for HA -* **MySQL/MariaDB**: Production-ready, supports concurrent access, works for HA +- **SQLite** (default): Embedded, no external dependencies, single-instance only +- **PostgreSQL**: Production-ready, supports concurrent access, required for HA +- **MySQL/MariaDB**: Production-ready, supports concurrent access, works for HA #### Storage Backend (Binary Data) Stores actual package files: -* **Local Filesystem**: Traditional file storage, simple setup, single-instance -* **S3-Compatible**: AWS S3, MinIO, etc., required for HA, scalable +- **Local Filesystem**: Traditional file storage, simple setup, single-instance +- **S3-Compatible**: AWS S3, MinIO, etc., required for HA, scalable ### Key Concepts @@ -115,38 +116,38 @@ Stores actual package files: A NAR is an archive format containing the actual package files. When you install a package, Nix downloads the NAR and unpacks it into `/nix/store`. -* Binary package data -* Typically compressed (xz, zstd) -* Can be very large (500MB+ for some packages) -* Stored in the storage backend +- Binary package data +- Typically compressed (xz, zstd) +- Can be very large (500MB+ for some packages) +- Stored in the storage backend #### NarInfo NarInfo is metadata about a NAR file: -* Hash and size of the NAR -* Compression type -* References to other store paths -* Digital signature -* Stored in the database +- Hash and size of the NAR +- Compression type +- References to other store paths +- Digital signature +- Stored in the database #### Signing ncps signs all cached NarInfo files with its own private key: -* Clients trust ncps by adding its public key to their configuration -* Ensures integrity and authenticity of cached packages -* Private key generated automatically on first run -* Public key available at `http://your-ncps/pubkey` +- Clients trust ncps by adding its public key to their configuration +- Ensures integrity and authenticity of cached packages +- Private key generated automatically on first run +- Public key available at `http://your-ncps/pubkey` #### Upstream Caches ncps fetches packages from configured upstream caches: -* Primary: `cache.nixos.org` (official Nix cache) -* Secondary: Custom caches, Cachix, etc. -* Failover support: tries next upstream if one fails -* Respects upstream public keys for verification +- Primary: `cache.nixos.org` (official Nix cache) +- Secondary: Custom caches, Cachix, etc. +- Failover support: tries next upstream if one fails +- Respects upstream public keys for verification ### Deployment Modes @@ -177,18 +178,18 @@ ncps fetches packages from configured upstream caches: **Characteristics:** -* Single ncps server -* Local locks (no Redis needed) -* Simple to set up and manage -* Perfect for teams up to 100+ users -* Can use any storage and database option +- Single ncps server +- Local locks (no Redis needed) +- Simple to set up and manage +- Perfect for teams up to 100+ users +- Can use any storage and database option **When to Use:** -* Development teams -* Single location deployments -* Simpler operations preferred -* No need for zero-downtime updates +- Development teams +- Single location deployments +- Simpler operations preferred +- No need for zero-downtime updates #### High Availability Mode @@ -218,26 +219,26 @@ ncps fetches packages from configured upstream caches: **Characteristics:** -* Multiple ncps instances (2+) -* Redis for distributed locking -* Shared S3 storage (required) -* Shared PostgreSQL/MySQL (required, SQLite NOT supported) -* Load balancer distributes requests +- Multiple ncps instances (2+) +- Redis for distributed locking +- Shared S3 storage (required) +- Shared PostgreSQL/MySQL (required, SQLite NOT supported) +- Load balancer distributes requests **When to Use:** -* Production deployments -* Need zero-downtime updates -* Geographic distribution -* Very high traffic (1000+ users) -* SLA requirements +- Production deployments +- Need zero-downtime updates +- Geographic distribution +- Very high traffic (1000+ users) +- SLA requirements **Key Features:** -* **Download Deduplication**: Only one instance downloads each package -* **LRU Coordination**: Only one instance runs cache cleanup at a time -* **Automatic Failover**: Instance failures don't interrupt service -* **Horizontal Scaling**: Add instances to handle more load +- **Download Deduplication**: Only one instance downloads each package +- **LRU Coordination**: Only one instance runs cache cleanup at a time +- **Automatic Failover**: Instance failures don't interrupt service +- **Horizontal Scaling**: Add instances to handle more load See the High Availability for detailed setup instructions. @@ -247,39 +248,39 @@ See the H Typical cache hit rates depend on usage patterns: -* Stable environments: 80-95% hit rate -* Active development: 50-80% hit rate -* Fresh installations: 0-20% hit rate (builds up over time) +- Stable environments: 80-95% hit rate +- Active development: 50-80% hit rate +- Fresh installations: 0-20% hit rate (builds up over time) ### Speed Improvements Typical speed improvements with ncps: -* **Local network**: 10-100× faster than internet download -* **Example**: 1Gbps LAN vs 100Mbps internet = 10× faster -* **Latency**: Sub-millisecond vs 10-100ms to upstream +- **Local network**: 10-100× faster than internet download +- **Example**: 1Gbps LAN vs 100Mbps internet = 10× faster +- **Latency**: Sub-millisecond vs 10-100ms to upstream ### Storage Requirements Plan storage based on usage: -* **Small team (5-10 users)**: 20-50GB -* **Medium team (10-50 users)**: 50-200GB -* **Large team (50+ users)**: 200GB-1TB+ -* **LRU cleanup**: Automatically manages size with `--cache-max-size` +- **Small team (5-10 users)**: 20-50GB +- **Medium team (10-50 users)**: 50-200GB +- **Large team (50+ users)**: 200GB-1TB+ +- **LRU cleanup**: Automatically manages size with `--cache-max-size` ## Next Steps Now that you understand how ncps works: -1. Installation - Docker, Kubernetes, NixOS, etc. -2. Storage - Local vs S3 -3. Database - SQLite vs PostgreSQL/MySQL -4. Deployment - Single-instance vs High Availability -5. Client Setup - Configure Nix to use your cache +1. Installation - Docker, Kubernetes, NixOS, etc. +1. Storage - Local vs S3 +1. Database - SQLite vs PostgreSQL/MySQL +1. Deployment - Single-instance vs High Availability +1. Client Setup - Configure Nix to use your cache ## Related Documentation -* Quick Start - Get ncps running quickly -* [Deep dive into internals](../../Developer%20Guide/Architecture.md) - Deep dive into internals -* Reference - All configuration options \ No newline at end of file +- Quick Start - Get ncps running quickly +- [Deep dive into internals](../../Developer%20Guide/Architecture.md) - Deep dive into internals +- Reference - All configuration options diff --git a/docs/docs/User Guide/Getting Started/Quick Start.md b/docs/docs/User Guide/Getting Started/Quick Start.md index 97a296d0..693d0ba2 100644 --- a/docs/docs/User Guide/Getting Started/Quick Start.md +++ b/docs/docs/User Guide/Getting Started/Quick Start.md @@ -1,13 +1,14 @@ -# Quick Start +# Quick Start + ## Quick Start Guide Get ncps up and running in minutes. This guide shows you the fastest path from zero to a working ncps instance. ## Prerequisites -* Docker installed and running -* Basic understanding of Nix package manager -* Network access to upstream caches (cache.nixos.org) +- Docker installed and running +- Basic understanding of Nix package manager +- Network access to upstream caches (cache.nixos.org) ## Option 1: Local Storage (Recommended for Getting Started) @@ -118,9 +119,9 @@ docker run -d \ **Replace:** -* `my-ncps-cache` with your S3 bucket name -* `YOUR_ACCESS_KEY` and `YOUR_SECRET_KEY` with your S3 credentials -* Adjust `endpoint` and `region` for your S3 provider +- `my-ncps-cache` with your S3 bucket name +- `YOUR_ACCESS_KEY` and `YOUR_SECRET_KEY` with your S3 credentials +- Adjust `endpoint` and `region` for your S3 provider ### Step 5: Verify Installation @@ -137,41 +138,41 @@ curl http://localhost:8501/pubkey Your ncps instance is now: -* Listening on port 8501 -* Caching packages from cache.nixos.org -* Storing data in Docker volume (local) or S3 bucket -* Signing cached paths with its own private key -* Ready to serve Nix clients +- Listening on port 8501 +- Caching packages from cache.nixos.org +- Storing data in Docker volume (local) or S3 bucket +- Signing cached paths with its own private key +- Ready to serve Nix clients ## Next Steps -1. Client Setup - Set up your Nix clients to use ncps -2. Concepts - Learn how ncps works under the hood -3. Installation - Pick the best installation method for your needs -4. Reference - Explore more configuration options +1. Client Setup - Set up your Nix clients to use ncps +1. Concepts - Learn how ncps works under the hood +1. Installation - Pick the best installation method for your needs +1. Reference - Explore more configuration options ## Quick Troubleshooting **Container exits immediately:** -* Check you provided all required flags: `--cache-hostname`, storage, database, upstream -* Check logs: `docker logs ncps` +- Check you provided all required flags: `--cache-hostname`, storage, database, upstream +- Check logs: `docker logs ncps` **Can't access** [**http://localhost:8501**](http://localhost:8501)**:** -* Verify container is running: `docker ps | grep ncps` -* Check port mapping: `-p 8501:8501` -* Try from inside container: `docker exec ncps wget -O- http://localhost:8501/nix-cache-info` +- Verify container is running: `docker ps | grep ncps` +- Check port mapping: `-p 8501:8501` +- Try from inside container: `docker exec ncps wget -O- http://localhost:8501/nix-cache-info` **Database errors:** -* Ensure you ran the database migration step -* Verify database path matches between migration and serve commands +- Ensure you ran the database migration step +- Verify database path matches between migration and serve commands See the Troubleshooting for more help. ## Related Documentation -* Docker - Detailed Docker setup -* Docker Compose - Automated setup -* Reference - All configuration options \ No newline at end of file +- Docker - Detailed Docker setup +- Docker Compose - Automated setup +- Reference - All configuration options diff --git a/docs/docs/User Guide/Installation.md b/docs/docs/User Guide/Installation.md index 8e4e6c98..1cbc51b0 100644 --- a/docs/docs/User Guide/Installation.md +++ b/docs/docs/User Guide/Installation.md @@ -1,4 +1,5 @@ -# Installation +# Installation + ## Installation Guide Choose the installation method that best fits your environment and requirements. @@ -19,86 +20,88 @@ Choose the installation method that best fits your environment and requirements. **Use** Docker -* Fastest setup (5 minutes) -* No infrastructure required -* Perfect for trying ncps +- Fastest setup (5 minutes) +- No infrastructure required +- Perfect for trying ncps ### For Small Teams (1-10 users) **Use** Docker Compose or NixOS -* Automated setup and management -* Easy to maintain -* Good for single-server deployments +- Automated setup and management +- Easy to maintain +- Good for single-server deployments ### For Production (Single Instance) **Use** Kubernetes or Helm Chart -* Better resource management -* Built-in health checks and restarts -* Integration with existing infrastructure +- Better resource management +- Built-in health checks and restarts +- Integration with existing infrastructure ### For Production (High Availability) **Use** Helm Chart -* Simplified multi-instance deployment -* Built-in HA configuration -* Handles Redis, load balancing, and more +- Simplified multi-instance deployment +- Built-in HA configuration +- Handles Redis, load balancing, and more ## Prerequisites by Method ### Docker -* Docker installed (version 20.10+) -* 2GB+ available disk space -* Network access to a container registry (GHCR or Docker Hub) +- Docker installed (version 20.10+) +- 2GB+ available disk space +- Network access to a container registry (GHCR or Docker Hub) ### Docker Compose -* Docker and Docker Compose installed -* 2GB+ available disk space +- Docker and Docker Compose installed +- 2GB+ available disk space ### Kubernetes -* Kubernetes cluster (version 1.20+) -* kubectl configured -* PersistentVolume provisioner -* 2GB+ available storage +- Kubernetes cluster (version 1.20+) +- kubectl configured +- PersistentVolume provisioner +- 2GB+ available storage ### Helm -* Kubernetes cluster (version 1.20+) -* Helm installed (version 3.0+) -* kubectl configured +- Kubernetes cluster (version 1.20+) +- Helm installed (version 3.0+) +- kubectl configured ### NixOS -* NixOS 25.05 or later -* Sufficient disk space for cache +- NixOS 25.05 or later +- Sufficient disk space for cache ## Common Post-Installation Steps After installing ncps with any method: -1. **Verify Installation** +1. **Verify Installation** + + ``` + # Test cache info endpoint + curl http://your-ncps-hostname:8501/nix-cache-info + + # Get public key + curl http://your-ncps-hostname:8501/pubkey + ``` - ``` - # Test cache info endpoint - curl http://your-ncps-hostname:8501/nix-cache-info +1. Client Setup - # Get public key - curl http://your-ncps-hostname:8501/pubkey - ``` -2. Client Setup + - Add ncps as a substituter + - Add public key to trusted keys - * Add ncps as a substituter - * Add public key to trusted keys -3. Monitoring (Optional but recommended) +1. Monitoring (Optional but recommended) - * Enable Prometheus metrics - * Set up alerts + - Enable Prometheus metrics + - Set up alerts ## Comparison: Local vs S3 Storage @@ -106,29 +109,29 @@ After installing ncps with any method: **Pros:** -* Simple setup, no external dependencies -* Lower latency for single-instance -* No S3 costs +- Simple setup, no external dependencies +- Lower latency for single-instance +- No S3 costs **Cons:** -* Not suitable for HA deployments -* Limited to single server's disk -* No built-in redundancy +- Not suitable for HA deployments +- Limited to single server's disk +- No built-in redundancy ### S3 Storage **Pros:** -* Required for HA deployments -* Scalable and redundant -* Works with AWS S3, MinIO, and others +- Required for HA deployments +- Scalable and redundant +- Works with AWS S3, MinIO, and others **Cons:** -* Requires S3 service setup -* Potential costs (AWS S3) -* Slight latency overhead +- Requires S3 service setup +- Potential costs (AWS S3) +- Slight latency overhead See Storage for details. @@ -138,42 +141,42 @@ See Storage for **Pros:** -* Embedded, no external service -* Zero configuration -* Perfect for single-instance +- Embedded, no external service +- Zero configuration +- Perfect for single-instance **Cons:** -* NOT supported for HA -* Single connection limit -* File-based limitations +- NOT supported for HA +- Single connection limit +- File-based limitations ### PostgreSQL/MySQL **Pros:** -* Required for HA deployments -* Handles concurrent connections -* Production-ready scaling +- Required for HA deployments +- Handles concurrent connections +- Production-ready scaling **Cons:** -* Requires database service -* More complex setup -* Additional maintenance +- Requires database service +- More complex setup +- Additional maintenance See Database for details. ## Need Help? -* Troubleshooting -* [Configuration Reference](Configuration/Reference.md) -* [GitHub Discussions](https://github.com/kalbasit/ncps/discussions) +- Troubleshooting +- [Configuration Reference](Configuration/Reference.md) +- [GitHub Discussions](https://github.com/kalbasit/ncps/discussions) ## Next Steps After installation: -1. [Configure ncps](Configuration/Reference.md) -2. [Set up Nix clients](Usage/Client%20Setup.md) -3. [Monitor your cache](Operations/Monitoring.md) \ No newline at end of file +1. [Configure ncps](Configuration/Reference.md) +1. [Set up Nix clients](Usage/Client%20Setup.md) +1. [Monitor your cache](Operations/Monitoring.md) diff --git a/docs/docs/User Guide/Installation/Docker Compose.md b/docs/docs/User Guide/Installation/Docker Compose.md index fe6b6a78..43ae6377 100644 --- a/docs/docs/User Guide/Installation/Docker Compose.md +++ b/docs/docs/User Guide/Installation/Docker Compose.md @@ -1,13 +1,14 @@ -# Docker Compose +# Docker Compose + ## Docker Compose Installation Install ncps using Docker Compose for automated, reproducible deployments. This method is ideal for production single-instance deployments and development environments. ## Prerequisites -* Docker and Docker Compose installed -* Basic familiarity with Docker Compose -* 2GB+ available disk space +- Docker and Docker Compose installed +- Basic familiarity with Docker Compose +- 2GB+ available disk space ## Basic Setup (Local Storage) @@ -77,9 +78,9 @@ docker compose up -d This will: -1. Create directories with correct permissions -2. Run database migrations -3. Start ncps server +1. Create directories with correct permissions +1. Run database migrations +1. Start ncps server ### Step 3: Verify Installation @@ -229,16 +230,16 @@ volumes: **This setup includes:** -* PostgreSQL for shared database -* Redis for distributed locking -* MinIO for S3-compatible storage -* Two ncps instances for high availability +- PostgreSQL for shared database +- Redis for distributed locking +- MinIO for S3-compatible storage +- Two ncps instances for high availability **Access points:** -* ncps instance 1: [http://localhost:8501](http://localhost:8501) -* ncps instance 2: [http://localhost:8502](http://localhost:8502) -* MinIO console: [http://localhost:9001](http://localhost:9001) +- ncps instance 1: [http://localhost:8501](http://localhost:8501) +- ncps instance 2: [http://localhost:8502](http://localhost:8502) +- MinIO console: [http://localhost:9001](http://localhost:9001) ## Using Configuration File @@ -404,14 +405,14 @@ See the Troub ## Next Steps -1. Client Setup - Set up Nix clients to use your cache -2. Monitoring - Set up Prometheus and Grafana -3. Reference - Explore more options -4. Deployment - Consider deployment strategies +1. Client Setup - Set up Nix clients to use your cache +1. Monitoring - Set up Prometheus and Grafana +1. Reference - Explore more options +1. Deployment - Consider deployment strategies ## Related Documentation -* Docker - Manual Docker setup -* Kubernetes - For K8s environments -* High Availability - HA setup guide -* Reference - All configuration options \ No newline at end of file +- Docker - Manual Docker setup +- Kubernetes - For K8s environments +- High Availability - HA setup guide +- Reference - All configuration options diff --git a/docs/docs/User Guide/Installation/Docker.md b/docs/docs/User Guide/Installation/Docker.md index 198e9e21..b98ce6f0 100644 --- a/docs/docs/User Guide/Installation/Docker.md +++ b/docs/docs/User Guide/Installation/Docker.md @@ -1,14 +1,15 @@ -# Docker +# Docker + ## Docker Installation Install and run ncps using Docker. This is the simplest installation method, perfect for testing and single-instance deployments. ## Prerequisites -* Docker installed (version 20.10 or later) -* Basic familiarity with Docker commands -* 2GB+ available disk space -* Network access to upstream caches +- Docker installed (version 20.10 or later) +- Basic familiarity with Docker commands +- 2GB+ available disk space +- Network access to upstream caches ## Step 1: Pull the Image @@ -21,9 +22,9 @@ docker pull ghcr.io/kalbasit/ncps **Available tags:** -* `latest` - Latest stable release -* `vX.Y.Z` - Specific version (recommended for production) -* See [Docker Hub](https://hub.docker.com/r/kalbasit/ncps) or [GitHub packages](https://github.com/kalbasit/ncps/pkgs/container/ncps) for all tags +- `latest` - Latest stable release +- `vX.Y.Z` - Specific version (recommended for production) +- See [Docker Hub](https://hub.docker.com/r/kalbasit/ncps) or [GitHub packages](https://github.com/kalbasit/ncps/pkgs/container/ncps) for all tags ### Step 2: Initialize Storage and Database @@ -46,10 +47,10 @@ docker run --rm -v ncps-storage:/storage ghcr.io/kalbasit/ncps \ **What this does:** -* Creates a Docker volume for persistent storage -* Sets up the directory structure -* **Sets ownership to UID 1000** (ncps user in the container) -* Runs database migrations to create required tables +- Creates a Docker volume for persistent storage +- Sets up the directory structure +- **Sets ownership to UID 1000** (ncps user in the container) +- Runs database migrations to create required tables **Important:** The ncps Docker container runs as a non-root user (`ncps`, UID 1000, GID 1000) for security. All storage directories must be owned by UID 1000 for the container to access them. @@ -76,11 +77,11 @@ docker run -d \ **Flags explained:** -* `-d` - Run in detached mode (background) -* `--name ncps` - Container name for easy reference -* `-p 8501:8501` - Expose port 8501 -* `-v ncps-storage:/storage` - Mount persistent volume -* `--restart unless-stopped` - Auto-restart on failures +- `-d` - Run in detached mode (background) +- `--name ncps` - Container name for easy reference +- `-p 8501:8501` - Expose port 8501 +- `-v ncps-storage:/storage` - Mount persistent volume +- `--restart unless-stopped` - Auto-restart on failures ### Step 4: Verify Installation @@ -100,9 +101,9 @@ curl http://localhost:8501/pubkey **Expected output:** -* Container status: "Up" -* Cache info: JSON with StoreDir, Priority, etc. -* Public key: `your-ncps-hostname:base64encodedkey` +- Container status: "Up" +- Cache info: JSON with StoreDir, Priority, etc. +- Public key: `your-ncps-hostname:base64encodedkey` ## Using S3 Storage @@ -240,9 +241,9 @@ docker logs ncps **Common causes:** -* Missing required flags (--cache-hostname, storage, database, upstream) -* Database not initialized (missing migration step) -* Invalid configuration +- Missing required flags (--cache-hostname, storage, database, upstream) +- Database not initialized (missing migration step) +- Invalid configuration ### Can't Access [http://localhost:8501](http://localhost:8501) @@ -289,14 +290,14 @@ See the Troub ## Next Steps -1. Client Setup - Set up Nix clients to use your cache -2. Monitoring - Enable Prometheus metrics -3. Reference - Explore more options -4. **Consider** Docker Compose - For easier management +1. Client Setup - Set up Nix clients to use your cache +1. Monitoring - Enable Prometheus metrics +1. Reference - Explore more options +1. **Consider** Docker Compose - For easier management ## Related Documentation -* Docker Compose - Automated Docker setup -* Reference - All configuration options -* Storage - Local vs S3 storage -* Operations - Monitoring, backup, and maintenance \ No newline at end of file +- Docker Compose - Automated Docker setup +- Reference - All configuration options +- Storage - Local vs S3 storage +- Operations - Monitoring, backup, and maintenance diff --git a/docs/docs/User Guide/Installation/Helm Chart.md b/docs/docs/User Guide/Installation/Helm Chart.md index 721b1ec0..2b5c601c 100644 --- a/docs/docs/User Guide/Installation/Helm Chart.md +++ b/docs/docs/User Guide/Installation/Helm Chart.md @@ -1,12 +1,13 @@ -# Helm Chart +# Helm Chart + Install ncps on Kubernetes using Helm for simplified configuration and management. This is the recommended method for production Kubernetes deployments. ## Prerequisites -* Kubernetes 1.19+ -* Helm 3.8+ -* kubectl configured and connected to your cluster -* PV provisioner support in the underlying infrastructure (for local storage with persistence) +- Kubernetes 1.19+ +- Helm 3.8+ +- kubectl configured and connected to your cluster +- PV provisioner support in the underlying infrastructure (for local storage with persistence) ## Quick Start @@ -33,10 +34,10 @@ helm install ncps . -f values.yaml --namespace ncps This installs ncps with: -* Single replica (StatefulSet mode) -* Local storage (PersistentVolumeClaim, 20Gi) -* SQLite database -* Default upstream: cache.nixos.org +- Single replica (StatefulSet mode) +- Local storage (PersistentVolumeClaim, 20Gi) +- SQLite database +- Default upstream: cache.nixos.org ### Verify Installation @@ -60,9 +61,9 @@ The chart supports two deployment modes: Best for: -* Single instance deployments -* Local persistent storage -* SQLite database +- Single instance deployments +- Local persistent storage +- SQLite database ```yaml mode: statefulset @@ -82,9 +83,9 @@ config: Best for: -* High availability (multiple replicas) -* S3 storage -* PostgreSQL/MySQL database +- High availability (multiple replicas) +- S3 storage +- PostgreSQL/MySQL database ```yaml mode: deployment @@ -598,10 +599,10 @@ ingress: ### From Single Instance to HA -1. Migrate from SQLite to PostgreSQL/MySQL -2. Switch from local storage to S3 -3. Enable Redis -4. Increase replica count +1. Migrate from SQLite to PostgreSQL/MySQL +1. Switch from local storage to S3 +1. Enable Redis +1. Increase replica count ``` # Step 1: Backup SQLite database @@ -649,20 +650,20 @@ kubectl -n ncps logs job/ncps-migration **Pod fails to start with "database file not found":** -* For SQLite + S3 deployments, ensure `storage.local.persistence.enabled: true` is set -* SQLite requires persistent storage even when using S3 for NAR files +- For SQLite + S3 deployments, ensure `storage.local.persistence.enabled: true` is set +- SQLite requires persistent storage even when using S3 for NAR files **Migration job fails:** -* Check migration job logs: `kubectl -n ncps logs job/ncps-migration` -* Verify database credentials are correct -* Ensure database is accessible from the cluster +- Check migration job logs: `kubectl -n ncps logs job/ncps-migration` +- Verify database credentials are correct +- Ensure database is accessible from the cluster **S3 connection errors:** -* Verify S3 credentials and endpoint -* For MinIO, ensure `config.storage.s3.forcePathStyle: true` is set -* Check endpoint includes proper scheme (http:// or https://) +- Verify S3 credentials and endpoint +- For MinIO, ensure `config.storage.s3.forcePathStyle: true` is set +- Check endpoint includes proper scheme (http:// or https://) ## Complete Values Reference @@ -670,6 +671,6 @@ See the Char ## Next Steps -* Client Setup -* Monitoring -* High Availability \ No newline at end of file +- Client Setup +- Monitoring +- High Availability diff --git a/docs/docs/User Guide/Installation/Helm Chart/Chart Reference.md b/docs/docs/User Guide/Installation/Helm Chart/Chart Reference.md index c9f44b15..9dc62c74 100644 --- a/docs/docs/User Guide/Installation/Helm Chart/Chart Reference.md +++ b/docs/docs/User Guide/Installation/Helm Chart/Chart Reference.md @@ -1,4 +1,5 @@ -# Chart Reference +# Chart Reference + ## Introduction This chart bootstraps a ncps deployment on a Kubernetes cluster using the Helm package manager. ncps is a local binary cache proxy for Nix that fetches store paths from upstream caches and caches them locally, reducing download times and bandwidth usage. @@ -8,9 +9,9 @@ This chart bootstraps a ncps deployment on a Kubernetes cluster using the Helm p ## Prerequisites -* Kubernetes 1.19+ -* Helm 3.8+ -* PV provisioner support in the underlying infrastructure (for local storage with persistence) +- Kubernetes 1.19+ +- Helm 3.8+ +- PV provisioner support in the underlying infrastructure (for local storage with persistence) ## Installation @@ -570,9 +571,9 @@ helm test ncps When using `helm template` (manually or via tools like nixidy), Helm hook annotations are ignored and the test pod gets rendered as a regular resource, causing issues: -* The pod runs once and completes -* It appears as degraded/failed in your cluster -* Updates to the pod fail (can't update completed pods) +- The pod runs once and completes +- It appears as degraded/failed in your cluster +- Updates to the pod fail (can't update completed pods) ```yaml # values.yaml when using helm template @@ -582,8 +583,8 @@ tests: **Note for ArgoCD/Flux users**: These tools may use `helm template` internally. Check your configuration: -* ArgoCD: Depends on your Application's source configuration -* Flux: HelmRelease with `spec.install.disableHooks: true` has this issue +- ArgoCD: Depends on your Application's source configuration +- Flux: HelmRelease with `spec.install.disableHooks: true` has this issue To test your deployment when using templating, use the readiness/liveness probes or manually verify: @@ -601,16 +602,16 @@ The chart includes validation to prevent incompatible configurations: **Error: "High availability mode requires Redis"** -* Enable Redis when using multiple replicas: `config.redis.enabled=true` +- Enable Redis when using multiple replicas: `config.redis.enabled=true` **Error: "High availability mode is not compatible with SQLite"** -* Use PostgreSQL or MySQL: `config.database.type=postgresql` +- Use PostgreSQL or MySQL: `config.database.type=postgresql` **Error: "High availability mode with Deployment requires S3 storage"** -* Either use S3: `config.storage.type=s3` -* Or switch to StatefulSet with NFS: `mode=statefulset` +- Either use S3: `config.storage.type=s3` +- Or switch to StatefulSet with NFS: `mode=statefulset` ### Pods Not Starting @@ -671,8 +672,8 @@ kubectl get secret -ncps -o jsonpath='{.data.redis-password}' | ba ## Further Information -* User Guide -* Installation -* Helm Chart -* [ncps GitHub Repository](https://github.com/kalbasit/ncps) -* [Helm Documentation](https://helm.sh/docs/) \ No newline at end of file +- User Guide +- Installation +- Helm Chart +- [ncps GitHub Repository](https://github.com/kalbasit/ncps) +- [Helm Documentation](https://helm.sh/docs/) diff --git a/docs/docs/User Guide/Installation/Kubernetes.md b/docs/docs/User Guide/Installation/Kubernetes.md index 649911d2..99596023 100644 --- a/docs/docs/User Guide/Installation/Kubernetes.md +++ b/docs/docs/User Guide/Installation/Kubernetes.md @@ -1,14 +1,15 @@ -# Kubernetes +# Kubernetes + ## Kubernetes Installation Deploy ncps on Kubernetes for production-ready, scalable deployments with manual control over resources. ## Prerequisites -* Kubernetes cluster (version 1.20+) -* kubectl configured and connected to your cluster -* PersistentVolume provisioner available -* 2GB+ available storage +- Kubernetes cluster (version 1.20+) +- kubectl configured and connected to your cluster +- PersistentVolume provisioner available +- 2GB+ available storage ## Quick Start @@ -393,9 +394,9 @@ For HA with multiple replicas: ### Prerequisites -* Redis deployed in cluster -* S3 storage configured -* PostgreSQL or MySQL database +- Redis deployed in cluster +- S3 storage configured +- PostgreSQL or MySQL database ### Create Deployment with Multiple Replicas @@ -487,14 +488,14 @@ See the Troub ## Next Steps -1. Client Setup - Set up Nix clients -2. Monitoring - Set up observability -3. Reference - Explore more options -4. **Consider** Helm - For simplified management +1. Client Setup - Set up Nix clients +1. Monitoring - Set up observability +1. Reference - Explore more options +1. **Consider** Helm - For simplified management ## Related Documentation -* Helm - Simplified Kubernetes deployment -* Docker Compose - For non-K8s environments -* High Availability - HA setup guide -* Reference - All configuration options \ No newline at end of file +- Helm - Simplified Kubernetes deployment +- Docker Compose - For non-K8s environments +- High Availability - HA setup guide +- Reference - All configuration options diff --git a/docs/docs/User Guide/Installation/NixOS.md b/docs/docs/User Guide/Installation/NixOS.md index 200ee98b..3c038075 100644 --- a/docs/docs/User Guide/Installation/NixOS.md +++ b/docs/docs/User Guide/Installation/NixOS.md @@ -1,13 +1,14 @@ -# NixOS +# NixOS + ## NixOS Installation Install ncps on NixOS using the built-in service module for native integration and simplified management. ## Prerequisites -* NixOS 25.05 or later (earlier versions don't include the ncps module) -* Sufficient disk space for cache storage -* Basic familiarity with NixOS configuration +- NixOS 25.05 or later (earlier versions don't include the ncps module) +- Sufficient disk space for cache storage +- Basic familiarity with NixOS configuration ## Quick Start @@ -42,10 +43,10 @@ sudo nixos-rebuild switch The service will: -* Create the ncps user and group automatically -* Set up directories with correct permissions -* Initialize the database -* Start the ncps service +- Create the ncps user and group automatically +- Set up directories with correct permissions +- Initialize the database +- Start the ncps service ### Verify Installation @@ -174,8 +175,8 @@ curl http://localhost:8501/pubkey To use S3 storage with NixOS today: -* Install ncps via Docker/Podman on NixOS -* Use the Docker +- Install ncps via Docker/Podman on NixOS +- Use the Docker ## Observability Configuration @@ -379,14 +380,14 @@ sudo nixos-rebuild switch ## Next Steps -1. Client Setup - Set up your Nix clients to use the cache -2. Reference - Explore more configuration options -3. Monitoring - Configure observability -4. High Availability - Consider high availability (use Docker/K8s) +1. Client Setup - Set up your Nix clients to use the cache +1. Reference - Explore more configuration options +1. Monitoring - Configure observability +1. High Availability - Consider high availability (use Docker/K8s) ## Related Documentation -* NixOS Options Search - All module options -* Docker - For S3 storage on NixOS -* Reference - All configuration options -* Client Setup - Configure Nix clients \ No newline at end of file +- NixOS Options Search - All module options +- Docker - For S3 storage on NixOS +- Reference - All configuration options +- Client Setup - Configure Nix clients diff --git a/docs/docs/User Guide/Operations.md b/docs/docs/User Guide/Operations.md index 419b7f3f..fdd89f3f 100644 --- a/docs/docs/User Guide/Operations.md +++ b/docs/docs/User Guide/Operations.md @@ -1,51 +1,52 @@ -# Operations +# Operations + ## Operations Guide Operational guides for running ncps in production. ## Guides -* Monitoring - Set up metrics, dashboards, and alerts -* Troubleshooting - Solve common issues -* [Backup & Restore](Operations/Backup%20Restore.md) - Backup strategies and recovery -* Upgrading - Upgrade procedures and migration -* NarInfo Migration - Migrate narinfo metadata to database +- Monitoring - Set up metrics, dashboards, and alerts +- Troubleshooting - Solve common issues +- [Backup & Restore](Operations/Backup%20Restore.md) - Backup strategies and recovery +- Upgrading - Upgrade procedures and migration +- NarInfo Migration - Migrate narinfo metadata to database ## Quick Links ### Monitoring -* [Prometheus Setup](Operations/Monitoring.md) -* [Grafana Dashboards](Operations/Monitoring.md) -* [Alert Manager](Operations/Monitoring.md) +- [Prometheus Setup](Operations/Monitoring.md) +- [Grafana Dashboards](Operations/Monitoring.md) +- [Alert Manager](Operations/Monitoring.md) ### Troubleshooting -* [Common Errors](Operations/Troubleshooting.md) -* [Logs & Debugging](Operations/Troubleshooting.md) -* [Network Connectivity](Operations/Troubleshooting.md) +- [Common Errors](Operations/Troubleshooting.md) +- [Logs & Debugging](Operations/Troubleshooting.md) +- [Network Connectivity](Operations/Troubleshooting.md) ### Backups -* [Database Backups](Operations/Backup%20Restore.md) -* [S3 Object Retention](Operations/Backup%20Restore.md) -* [Disaster Recovery](Operations/Backup%20Restore.md) +- [Database Backups](Operations/Backup%20Restore.md) +- [S3 Object Retention](Operations/Backup%20Restore.md) +- [Disaster Recovery](Operations/Backup%20Restore.md) ### Upgrades -* [Release Notes](Operations/Upgrading.md) -* [Database Migrations](Operations/Upgrading.md) -* [Rollback Procedures](Operations/Upgrading.md) +- [Release Notes](Operations/Upgrading.md) +- [Database Migrations](Operations/Upgrading.md) +- [Rollback Procedures](Operations/Upgrading.md) ### NarInfo Migration -* [Migration Strategies](Operations/NarInfo%20Migration.md) -* [CLI Migration Guide](Operations/NarInfo%20Migration.md) -* [Progress Monitoring](Operations/NarInfo%20Migration.md) -* [Troubleshooting Migration](Operations/NarInfo%20Migration.md) +- [Migration Strategies](Operations/NarInfo%20Migration.md) +- [CLI Migration Guide](Operations/NarInfo%20Migration.md) +- [Progress Monitoring](Operations/NarInfo%20Migration.md) +- [Troubleshooting Migration](Operations/NarInfo%20Migration.md) ## Related Documentation -* [Configuration Reference](Configuration/Reference.md) - All configuration options -* [Deployment Guides](Deployment.md) - Deployment strategies -* [Usage Guides](Usage.md) - Client setup and usage \ No newline at end of file +- [Configuration Reference](Configuration/Reference.md) - All configuration options +- [Deployment Guides](Deployment.md) - Deployment strategies +- [Usage Guides](Usage.md) - Client setup and usage diff --git a/docs/docs/User Guide/Operations/Backup Restore.md b/docs/docs/User Guide/Operations/Backup Restore.md index 3b4b4c92..ceb6abeb 100644 --- a/docs/docs/User Guide/Operations/Backup Restore.md +++ b/docs/docs/User Guide/Operations/Backup Restore.md @@ -1,4 +1,5 @@ -# Backup Restore +# Backup Restore + ## Backup & Restore Guide Backup strategies and recovery procedures. @@ -86,29 +87,29 @@ aws s3api put-bucket-versioning \ ### Development -* Database: Daily backups -* Storage: Optional (can rebuild) +- Database: Daily backups +- Storage: Optional (can rebuild) ### Production Single-Instance -* Database: Daily automated backups -* Storage: Weekly backups or S3 with versioning +- Database: Daily automated backups +- Storage: Weekly backups or S3 with versioning ### Production HA -* Database: Automated backups with replication -* Storage: S3 with versioning (built-in) -* Redis: Optional (ephemeral locks) +- Database: Automated backups with replication +- Storage: S3 with versioning (built-in) +- Redis: Optional (ephemeral locks) ## Disaster Recovery -1. Stop ncps instances -2. Restore database from backup -3. Restore storage from backup (if local) -4. Start ncps instances -5. Verify functionality +1. Stop ncps instances +1. Restore database from backup +1. Restore storage from backup (if local) +1. Start ncps instances +1. Verify functionality ## Related Documentation -* Database - Database setup -* Storage - Storage setup \ No newline at end of file +- Database - Database setup +- Storage - Storage setup diff --git a/docs/docs/User Guide/Operations/Monitoring.md b/docs/docs/User Guide/Operations/Monitoring.md index da2f06ba..7d3b2ef3 100644 --- a/docs/docs/User Guide/Operations/Monitoring.md +++ b/docs/docs/User Guide/Operations/Monitoring.md @@ -1,4 +1,5 @@ -# Monitoring +# Monitoring + ## Monitoring Guide Set up monitoring, metrics, and alerting for ncps. @@ -18,35 +19,35 @@ Access metrics at: `http://your-ncps:8501/metrics` (for `serve`) or via stdout/O **HTTP Metrics:** -* `http_server_requests_total` - Total HTTP requests -* `http_server_request_duration_seconds` - Request duration -* `http_server_active_requests` - Active requests +- `http_server_requests_total` - Total HTTP requests +- `http_server_request_duration_seconds` - Request duration +- `http_server_active_requests` - Active requests **Cache Metrics:** -* `ncps_nar_served_total` - NAR files served -* `ncps_narinfo_served_total` - NarInfo files served +- `ncps_nar_served_total` - NAR files served +- `ncps_narinfo_served_total` - NarInfo files served **Lock Metrics (HA):** -* `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisitions -* `ncps_lock_hold_duration_seconds{type,mode}` - Lock hold time -* `ncps_lock_failures_total{type,reason,mode}` - Lock failures +- `ncps_lock_acquisitions_total{type,result,mode}` - Lock acquisitions +- `ncps_lock_hold_duration_seconds{type,mode}` - Lock hold time +- `ncps_lock_failures_total{type,reason,mode}` - Lock failures **Migration Metrics:** -* `ncps_migration_narinfos_total{operation,result}` - NarInfos migrated - * Labels: `operation` (migrate/delete), `result` (success/failure/skipped) -* `ncps_migration_duration_seconds{operation}` - Migration operation duration - * Label: `operation` (migrate/delete) -* `ncps_migration_batch_size` - Migration batch sizes +- `ncps_migration_narinfos_total{operation,result}` - NarInfos migrated + - Labels: `operation` (migrate/delete), `result` (success/failure/skipped) +- `ncps_migration_duration_seconds{operation}` - Migration operation duration + - Label: `operation` (migrate/delete) +- `ncps_migration_batch_size` - Migration batch sizes **Background Migration Metrics:** -* `ncps_background_migration_narinfos_total{operation,result}` - Background NarInfos migrated - * Labels: `operation` (migrate/delete), `result` (success/failure) -* `ncps_background_migration_duration_seconds{operation}` - Background migration operation duration - * Label: `operation` (migrate/delete) +- `ncps_background_migration_narinfos_total{operation,result}` - Background NarInfos migrated + - Labels: `operation` (migrate/delete), `result` (success/failure) +- `ncps_background_migration_duration_seconds{operation}` - Background migration operation duration + - Label: `operation` (migrate/delete) ## Prometheus Configuration @@ -66,15 +67,15 @@ scrape_configs: **Cache Performance:** -* Cache hit rate -* NAR served rate -* Request duration (p50, p95, p99) +- Cache hit rate +- NAR served rate +- Request duration (p50, p95, p99) **HA Lock Performance:** -* Lock acquisition success rate -* Lock retry attempts -* Lock hold duration +- Lock acquisition success rate +- Lock retry attempts +- Lock hold duration ### Example PromQL Queries @@ -149,5 +150,5 @@ curl -f http://localhost:8501/nix-cache-info || exit 1 ## Related Documentation -* Observability - Configure metrics -* Troubleshooting - Debug issues \ No newline at end of file +- Observability - Configure metrics +- Troubleshooting - Debug issues diff --git a/docs/docs/User Guide/Operations/NarInfo Migration.md b/docs/docs/User Guide/Operations/NarInfo Migration.md index b00e312d..7b852640 100644 --- a/docs/docs/User Guide/Operations/NarInfo Migration.md +++ b/docs/docs/User Guide/Operations/NarInfo Migration.md @@ -1,4 +1,5 @@ -# NarInfo Migration +# NarInfo Migration + ## Overview NarInfo migration moves NarInfo metadata from storage (filesystem or S3) into the database. This provides faster lookups, better querying capabilities, and prepares for advanced features. @@ -7,16 +8,16 @@ NarInfo migration moves NarInfo metadata from storage (filesystem or S3) into th **Benefits:** -* **Faster lookups** - Database queries vs. file I/O -* **Better scalability** - Indexed queries on millions of entries -* **Advanced features** - Enables future features requiring relational data -* **Reduced storage I/O** - Less filesystem/S3 traffic +- **Faster lookups** - Database queries vs. file I/O +- **Better scalability** - Indexed queries on millions of entries +- **Advanced features** - Enables future features requiring relational data +- **Reduced storage I/O** - Less filesystem/S3 traffic **When to migrate:** -* Upgrading from pre-database versions -* Moving to high-availability deployments -* Experiencing performance issues with large caches +- Upgrading from pre-database versions +- Moving to high-availability deployments +- Experiencing performance issues with large caches ## Migration Strategies @@ -26,24 +27,24 @@ NarInfo metadata is automatically migrated during normal operation when accessed **Advantages:** -* Zero downtime -* No manual intervention -* Gradual migration over time -* Works alongside normal cache operation +- Zero downtime +- No manual intervention +- Gradual migration over time +- Works alongside normal cache operation **How it works:** -1. Client requests a package -2. NCPS checks database first -3. If not in database, reads from storage -4. Migrates to database transparently -5. Subsequent requests use database +1. Client requests a package +1. NCPS checks database first +1. If not in database, reads from storage +1. Migrates to database transparently +1. Subsequent requests use database **Best for:** -* Production systems -* Caches with moderate traffic -* When downtime is unacceptable +- Production systems +- Caches with moderate traffic +- When downtime is unacceptable ### Explicit CLI Migration @@ -51,22 +52,22 @@ Bulk migration using the CLI command for faster results. **Advantages:** -* Faster completion -* Predictable timeline -* Progress monitoring -* Deletes from storage after migration +- Faster completion +- Predictable timeline +- Progress monitoring +- Deletes from storage after migration **Disadvantages:** -* Requires downtime (if deleting) -* More manual process +- Requires downtime (if deleting) +- More manual process **Best for:** -* Large caches (millions of narinfos) -* Maintenance windows -* When migration speed is important -* Storage space constraints (migration deletes files) +- Large caches (millions of narinfos) +- Maintenance windows +- When migration speed is important +- Storage space constraints (migration deletes files) ## CLI Migration Guide @@ -97,29 +98,29 @@ ncps migrate-narinfo \ **With Redis locking:** -* Migration can run safely while ncps is serving requests -* Multiple migration workers coordinate to avoid duplicate work -* Uses distributed locks to prevent race conditions -* Same Redis configuration as your running ncps instances +- Migration can run safely while ncps is serving requests +- Multiple migration workers coordinate to avoid duplicate work +- Uses distributed locks to prevent race conditions +- Same Redis configuration as your running ncps instances **Without Redis locking:** -* Uses in-memory locking (no coordination with other instances) -* Should only run when ncps instances are stopped -* Still safe for single-instance deployments +- Uses in-memory locking (no coordination with other instances) +- Should only run when ncps instances are stopped +- Still safe for single-instance deployments **Redis flags:** -* `--cache-redis-addrs` - Comma-separated Redis server addresses (enables distributed locking) -* `--cache-redis-username` - Redis username (optional) -* `--cache-redis-password` - Redis password (optional) -* `--cache-redis-db` - Redis database number (default: 0) -* `--cache-redis-use-tls` - Use TLS for Redis connections (optional) -* `--cache-redis-pool-size` - Redis connection pool size (default: 10) -* `--cache-lock-backend` - Lock backend to use: 'local', 'redis', or 'postgres' (default: 'local') -* `--cache-lock-redis-key-prefix` - Prefix for Redis lock keys (default: 'ncps:lock:') -* `--cache-lock-allow-degraded-mode` - Fallback to local locks if Redis is down -* `--cache-lock-retry-max-attempts` - Max lock retry attempts (default: 3) +- `--cache-redis-addrs` - Comma-separated Redis server addresses (enables distributed locking) +- `--cache-redis-username` - Redis username (optional) +- `--cache-redis-password` - Redis password (optional) +- `--cache-redis-db` - Redis database number (default: 0) +- `--cache-redis-use-tls` - Use TLS for Redis connections (optional) +- `--cache-redis-pool-size` - Redis connection pool size (default: 10) +- `--cache-lock-backend` - Lock backend to use: 'local', 'redis', or 'postgres' (default: 'local') +- `--cache-lock-redis-key-prefix` - Prefix for Redis lock keys (default: 'ncps:lock:') +- `--cache-lock-allow-degraded-mode` - Fallback to local locks if Redis is down +- `--cache-lock-retry-max-attempts` - Max lock retry attempts (default: 3) ### Dry Run @@ -181,10 +182,10 @@ Adjust worker count based on your database capacity: **Guidelines:** -* **SQLite**: 5-10 workers (single-writer limitation) -* **PostgreSQL**: 20-100 workers (depends on connection pool) -* **MySQL/MariaDB**: 20-100 workers (depends on connection pool) -* **S3 Storage**: Higher concurrency OK (parallel uploads) +- **SQLite**: 5-10 workers (single-writer limitation) +- **PostgreSQL**: 20-100 workers (depends on connection pool) +- **MySQL/MariaDB**: 20-100 workers (depends on connection pool) +- **S3 Storage**: Higher concurrency OK (parallel uploads) ## Progress Monitoring @@ -201,11 +202,11 @@ INFO migration completed found=10000 processed=10000 succeeded=9987 failed=13 du **Metrics explained:** -* **found**: Total narinfos discovered -* **processed**: Entered worker pool -* **succeeded**: Successfully migrated -* **failed**: Errors during migration -* **rate**: Narinfos processed per second +- **found**: Total narinfos discovered +- **processed**: Entered worker pool +- **succeeded**: Successfully migrated +- **failed**: Errors during migration +- **rate**: Narinfos processed per second ### OpenTelemetry @@ -220,7 +221,7 @@ ncps migrate-narinfo \ If OpenTelemetry is enabled, monitor via metrics: -**ncps\_migration\_narinfos\_total** +**ncps_migration_narinfos_total** ``` # Total migrations @@ -231,7 +232,7 @@ sum(rate(ncps_migration_narinfos_total{result="success"}[5m])) / sum(rate(ncps_migration_narinfos_total[5m])) ``` -**ncps\_migration\_duration\_seconds** +**ncps_migration_duration_seconds** ``` # Average migration time @@ -241,7 +242,7 @@ histogram_quantile(0.5, ncps_migration_duration_seconds) histogram_quantile(0.99, ncps_migration_duration_seconds) ``` -**ncps\_migration\_batch\_size** +**ncps_migration_batch_size** ``` # Batch sizes @@ -289,19 +290,23 @@ WHERE hash = 'n5glp21rsz314qssw9fbvfswgy3kc68f'; **Solutions:** -1. **Increase worker count** (if database can handle it) +1. **Increase worker count** (if database can handle it) + + ```sh + --concurrency=50 + ``` + +1. **Check database connection pool** + + ```sh + --cache-database-pool-max-open-conns=100 + ``` + +1. **Verify network latency** to database - ```sh - --concurrency=50 - ``` -2. **Check database connection pool** +1. **Run during low-traffic period** - ```sh - --cache-database-pool-max-open-conns=100 - ``` -3. **Verify network latency** to database -4. **Run during low-traffic period** -5. **For SQLite**: Consider PostgreSQL/MySQL for better concurrency +1. **For SQLite**: Consider PostgreSQL/MySQL for better concurrency ### Duplicate Key Errors in Logs @@ -325,9 +330,9 @@ ncps migrate-narinfo \ **How it works:** -* Migration is idempotent -* Already-migrated narinfos are deleted from storage -* Database migration step is skipped +- Migration is idempotent +- Already-migrated narinfos are deleted from storage +- Database migration step is skipped ### Transaction Deadlocks @@ -335,12 +340,13 @@ ncps migrate-narinfo \ **Solutions:** -1. **Reduce worker count** +1. **Reduce worker count** - ```sh - --concurrency=5 - ``` -2. **Use PostgreSQL/MySQL** instead of SQLite (better concurrent writes) + ```sh + --concurrency=5 + ``` + +1. **Use PostgreSQL/MySQL** instead of SQLite (better concurrent writes) ### Out of Memory @@ -348,51 +354,55 @@ ncps migrate-narinfo \ **Solutions:** -1. **Migration loads all migrated hashes** into memory by default +1. **Migration loads all migrated hashes** into memory by default + + - For very large caches (millions of narinfos), this can use significant RAM + - Solution: Ensure adequate memory or use background migration instead - * For very large caches (millions of narinfos), this can use significant RAM - * Solution: Ensure adequate memory or use background migration instead -2. **Reduce worker count** to lower memory pressure +1. **Reduce worker count** to lower memory pressure - ```sh - --concurrency=10 - ``` + ```sh + --concurrency=10 + ``` ## Best Practices ### Before Migration -1. **Backup database** before starting +1. **Backup database** before starting + + ```sh + # SQLite + cp /var/lib/ncps/db.sqlite /var/lib/ncps/db.sqlite.backup + + # PostgreSQL + pg_dump ncps > ncps_backup.sql + ``` + +1. **Test with dry run** - ```sh - # SQLite - cp /var/lib/ncps/db.sqlite /var/lib/ncps/db.sqlite.backup + ``` + ncps migrate-narinfo --dry-run ... + ``` - # PostgreSQL - pg_dump ncps > ncps_backup.sql - ``` -2. **Test with dry run** +1. **Check available disk space** as the database will grow. - ``` - ncps migrate-narinfo --dry-run ... - ``` -3. **Check available disk space** as the database will grow. -4. **Plan for a maintenance window** since this is a destructive operation. +1. **Plan for a maintenance window** since this is a destructive operation. ### During Migration -1. **Monitor progress** via console or OpenTelemetry -2. **Watch error count** - some failures OK, many failures = investigate -3. **Check database performance** - watch for resource constraints -4. **Keep backups available** for quick rollback if needed +1. **Monitor progress** via console or OpenTelemetry +1. **Watch error count** - some failures OK, many failures = investigate +1. **Check database performance** - watch for resource constraints +1. **Keep backups available** for quick rollback if needed ### After Migration -1. **Verify migration count** matches expected -2. **Spot check** several narinfos for data integrity -3. **Test cache operation** - fetch a few packages -4. **Keep storage files** for a few days before deleting (safety) -5. **Monitor cache performance** - should improve after migration +1. **Verify migration count** matches expected +1. **Spot check** several narinfos for data integrity +1. **Test cache operation** - fetch a few packages +1. **Keep storage files** for a few days before deleting (safety) +1. **Monitor cache performance** - should improve after migration ## Common Workflows @@ -433,10 +443,10 @@ ncps migrate-narinfo \ **Benefits:** -* No downtime required -* Migration coordinates with running instances via distributed locks -* Safe to run multiple migration processes simultaneously -* Each narinfo is migrated exactly once (lock prevents duplicates) +- No downtime required +- Migration coordinates with running instances via distributed locks +- Safe to run multiple migration processes simultaneously +- Each narinfo is migrated exactly once (lock prevents duplicates) **Option 2: Maintenance window (without Redis)** @@ -456,8 +466,8 @@ systemctl start ncps@* **When to use each approach:** -* **With Redis**: Production systems where downtime is unacceptable, or when you want to parallelize migration across multiple machines -* **Without Redis**: Maintenance windows, single-instance deployments, or when Redis is not available +- **With Redis**: Production systems where downtime is unacceptable, or when you want to parallelize migration across multiple machines +- **Without Redis**: Maintenance windows, single-instance deployments, or when Redis is not available ### Emergency Rollback @@ -478,12 +488,12 @@ Storage files are still available (unless you used `--delete`). ## Next Steps -* Monitoring - Track migration metrics -* Upgrading - Upgrade procedures -* Database - Database configuration +- Monitoring - Track migration metrics +- Upgrading - Upgrade procedures +- Database - Database configuration ## Related Documentation -* Storage - Storage backends -* Database - Database setup -* Troubleshooting - Common issues \ No newline at end of file +- Storage - Storage backends +- Database - Database setup +- Troubleshooting - Common issues diff --git a/docs/docs/User Guide/Operations/Troubleshooting.md b/docs/docs/User Guide/Operations/Troubleshooting.md index bedb2382..c68b1430 100644 --- a/docs/docs/User Guide/Operations/Troubleshooting.md +++ b/docs/docs/User Guide/Operations/Troubleshooting.md @@ -1,4 +1,5 @@ -# Troubleshooting +# Troubleshooting + ## Troubleshooting Guide Common issues and solutions. @@ -19,10 +20,10 @@ journalctl -u ncps -f **Common causes:** -* Missing required flags -* Database not initialized -* Permission errors -* Port already in use +- Missing required flags +- Database not initialized +- Permission errors +- Port already in use ### Can't Access Cache @@ -34,10 +35,10 @@ curl http://your-ncps:8501/nix-cache-info **Check:** -* Service is running -* Port 8501 is open -* Firewall rules -* Network connectivity +- Service is running +- Port 8501 is open +- Firewall rules +- Network connectivity ## Database Issues @@ -45,9 +46,9 @@ curl http://your-ncps:8501/nix-cache-info SQLite only allows one writer: -* Check no other processes are accessing the database -* Restart ncps -* Use PostgreSQL/MySQL for concurrent access +- Check no other processes are accessing the database +- Restart ncps +- Use PostgreSQL/MySQL for concurrent access ### Migration Errors @@ -82,17 +83,17 @@ sudo chown -R ncps:ncps /var/lib/ncps **Check:** -* Redis is configured and reachable -* All instances use same Redis -* Check logs for lock messages +- Redis is configured and reachable +- All instances use same Redis +- Check logs for lock messages ### High Lock Contention **Solutions:** -* Increase retry settings -* Increase lock TTLs -* Scale down instances if too many +- Increase retry settings +- Increase lock TTLs +- Scale down instances if too many See Distributed Locking. @@ -114,5 +115,5 @@ ncps serve --log-level=debug ## Related Documentation -* Monitoring - Set up monitoring -* Operations - All operational guides \ No newline at end of file +- Monitoring - Set up monitoring +- Operations - All operational guides diff --git a/docs/docs/User Guide/Operations/Upgrading.md b/docs/docs/User Guide/Operations/Upgrading.md index b4552b54..6f4faba2 100644 --- a/docs/docs/User Guide/Operations/Upgrading.md +++ b/docs/docs/User Guide/Operations/Upgrading.md @@ -1,4 +1,5 @@ -# Upgrading +# Upgrading + ## Upgrading Guide Upgrade ncps to newer versions. @@ -72,9 +73,9 @@ spec: Database schema migrations run automatically on startup. Ensure: -1. Backup database before upgrading -2. Migrations complete successfully (check logs) -3. All instances use same database schema version +1. Backup database before upgrading +1. Migrations complete successfully (check logs) +1. All instances use same database schema version ### NarInfo Migration @@ -82,18 +83,18 @@ When upgrading from versions before database-backed narinfo metadata, you have t **Option 1: Background Migration (Recommended)** -* Continue normal operation -* NarInfo migrated automatically on access -* Zero downtime -* Gradual migration over time -* No manual intervention required +- Continue normal operation +- NarInfo migrated automatically on access +- Zero downtime +- Gradual migration over time +- No manual intervention required **Option 2: Explicit CLI Migration** -* Faster bulk migration -* Use during maintenance window -* Deletion from storage (saves space) -* Progress monitoring and metrics with OpenTelemetry +- Faster bulk migration +- Use during maintenance window +- Deletion from storage (saves space) +- Progress monitoring and metrics with OpenTelemetry **Example CLI migration:** @@ -143,5 +144,5 @@ helm rollback ncps -n ncps ## Related Documentation -* Installation - Installation methods -* Deployment - Deployment strategies \ No newline at end of file +- Installation - Installation methods +- Deployment - Deployment strategies diff --git a/docs/docs/User Guide/Usage.md b/docs/docs/User Guide/Usage.md index aa9d210f..3d2e95c1 100644 --- a/docs/docs/User Guide/Usage.md +++ b/docs/docs/User Guide/Usage.md @@ -1,27 +1,28 @@ -# Usage +# Usage + ## Usage Guide Learn how to use ncps effectively. ## Guides -* Client Setup - Configure Nix clients to use your cache -* Cache Management - Manage cache size and cleanup +- Client Setup - Configure Nix clients to use your cache +- Cache Management - Manage cache size and cleanup ## Quick Links ### Setting Up Clients -1. [NixOS Configuration](Usage/Client%20Setup.md) -2. [Non-NixOS Linux](Usage/Client%20Setup.md) -3. [macOS Setup](Usage/Client%20Setup.md) -4. [CI/CD Integration](Usage/Client%20Setup.md) +1. [NixOS Configuration](Usage/Client%20Setup.md) +1. [Non-NixOS Linux](Usage/Client%20Setup.md) +1. [macOS Setup](Usage/Client%20Setup.md) +1. [CI/CD Integration](Usage/Client%20Setup.md) ### Managing Your Cache -1. [Automatic GC](Usage/Cache%20Management.md) -2. [Manual Cleanup](Usage/Cache%20Management.md) -3. [Size Monitoring](Usage/Cache%20Management.md) +1. [Automatic GC](Usage/Cache%20Management.md) +1. [Manual Cleanup](Usage/Cache%20Management.md) +1. [Size Monitoring](Usage/Cache%20Management.md) ## Common Tasks @@ -38,6 +39,6 @@ nix-build --option substituters "http://your-ncps:8501" ... ## Related Documentation -* Configuration Reference - Configuration options -* [Monitoring Guide](Operations/Monitoring.md) - Monitor cache performance -* [Troubleshooting Guide](Operations/Troubleshooting.md) - Solve common issues \ No newline at end of file +- Configuration Reference - Configuration options +- [Monitoring Guide](Operations/Monitoring.md) - Monitor cache performance +- [Troubleshooting Guide](Operations/Troubleshooting.md) - Solve common issues diff --git a/docs/docs/User Guide/Usage/Cache Management.md b/docs/docs/User Guide/Usage/Cache Management.md index 6614b60e..19d29dc7 100644 --- a/docs/docs/User Guide/Usage/Cache Management.md +++ b/docs/docs/User Guide/Usage/Cache Management.md @@ -1,4 +1,5 @@ -# Cache Management +# Cache Management + ## Cache Management Guide Manage cache size, cleanup, and optimization. @@ -22,10 +23,10 @@ cache: **Size formats:** -* `10K` - 10 kilobytes -* `100M` - 100 megabytes -* `50G` - 50 gigabytes -* `1T` - 1 terabyte +- `10K` - 10 kilobytes +- `100M` - 100 megabytes +- `50G` - 50 gigabytes +- `1T` - 1 terabyte ### Check Current Size @@ -58,9 +59,9 @@ cache: **Cron schedule examples:** -* `0 2 * * *` - Daily at 2 AM -* `0 */6 * * *` - Every 6 hours -* `0 3 * * 0` - Weekly on Sunday at 3 AM +- `0 2 * * *` - Daily at 2 AM +- `0 */6 * * *` - Every 6 hours +- `0 3 * * 0` - Weekly on Sunday at 3 AM ### Manual Cleanup @@ -86,12 +87,12 @@ If Prometheus is enabled: **Cache size:** -* Custom script to export size metrics +- Custom script to export size metrics **Cache hits/misses:** -* `ncps_nar_served_total` - Total NARs served -* `ncps_narinfo_served_total` - Total NarInfo served +- `ncps_nar_served_total` - Total NARs served +- `ncps_narinfo_served_total` - Total NarInfo served **Query cache hit rate:** @@ -143,10 +144,10 @@ NarInfo metadata is automatically migrated during normal operation when accessed **How it works:** -* Client requests a package -* NCPS checks database first -* If not found, reads from storage and migrates -* Subsequent requests use faster database lookups +- Client requests a package +- NCPS checks database first +- If not found, reads from storage and migrates +- Subsequent requests use faster database lookups ### Explicit Migration (CLI) @@ -184,9 +185,9 @@ ncps migrate-narinfo --dry-run \ Monitor migration progress through: -* **Console logs** - Progress updates every 5 seconds -* **OpenTelemetry** - Export traces and metrics (enable with `--otel-enabled`) -* **Final summary** - Completion report with statistics +- **Console logs** - Progress updates every 5 seconds +- **OpenTelemetry** - Export traces and metrics (enable with `--otel-enabled`) +- **Final summary** - Completion report with statistics **Example output:** @@ -200,35 +201,35 @@ INFO migration completed found=10000 processed=10000 succeeded=9987 failed=13 du **Use background migration when:** -* Running in production with uptime requirements -* Cache has moderate traffic -* No rush to complete migration +- Running in production with uptime requirements +- Cache has moderate traffic +- No rush to complete migration **Use CLI migration when:** -* Large cache (millions of narinfos) -* Need faster completion -* Storage space is limited (migration deletes narinfos) -* Upgrading from pre-database versions +- Large cache (millions of narinfos) +- Need faster completion +- Storage space is limited (migration deletes narinfos) +- Upgrading from pre-database versions See [NarInfo Migration Guide](../Operations/NarInfo%20Migration.md) for comprehensive documentation. ## Best Practices -1. **Set reasonable max-size** - Based on available disk space -2. **Enable LRU cleanup** - Automatic management -3. **Monitor cache usage** - Watch for growth trends -4. **Plan for growth** - Cache size increases over time -5. **Use S3 for large caches** - Better for 1TB+ caches -6. **Migrate narinfo to database** - Improves lookup performance +1. **Set reasonable max-size** - Based on available disk space +1. **Enable LRU cleanup** - Automatic management +1. **Monitor cache usage** - Watch for growth trends +1. **Plan for growth** - Cache size increases over time +1. **Use S3 for large caches** - Better for 1TB+ caches +1. **Migrate narinfo to database** - Improves lookup performance ## Next Steps -* Monitoring - Track cache performance -* Reference - All cache options +- Monitoring - Track cache performance +- Reference - All cache options ## Related Documentation -* Storage - Storage backends -* Monitoring - Monitor cache metrics -* Troubleshooting - Solve issues \ No newline at end of file +- Storage - Storage backends +- Monitoring - Monitor cache metrics +- Troubleshooting - Solve issues diff --git a/docs/docs/User Guide/Usage/Client Setup.md b/docs/docs/User Guide/Usage/Client Setup.md index 249dbaf2..ceac0276 100644 --- a/docs/docs/User Guide/Usage/Client Setup.md +++ b/docs/docs/User Guide/Usage/Client Setup.md @@ -1,4 +1,5 @@ -# Client Setup +# Client Setup + ## Client Setup Guide Configure your Nix clients to use your ncps cache. @@ -117,8 +118,8 @@ nix-build '' -A hello Look for log messages like: -* `serving nar from cache` - Cache hit! -* `downloading nar from upstream` - Cache miss, fetching from upstream +- `serving nar from cache` - Cache hit! +- `downloading nar from upstream` - Cache miss, fetching from upstream ## Priority and Order @@ -216,9 +217,9 @@ nix.settings.trusted-users = [ "root" "youruser" ]; **Possible causes:** -1. ncps doesn't have the package cached yet (first download) -2. ncps cache listed after official cache (order matters) -3. Public key not trusted +1. ncps doesn't have the package cached yet (first download) +1. ncps cache listed after official cache (order matters) +1. Public key not trusted **Check ncps logs** to see if requests are reaching it. @@ -226,12 +227,12 @@ See the Troub ## Next Steps -1. Monitoring - Set up monitoring -2. Cache Management - Configure LRU cleanup -3. Reference - Explore more options +1. Monitoring - Set up monitoring +1. Cache Management - Configure LRU cleanup +1. Reference - Explore more options ## Related Documentation -* Reference - All configuration options -* Monitoring - Monitor cache hits/misses -* Troubleshooting - Solve issues \ No newline at end of file +- Reference - All configuration options +- Monitoring - Monitor cache hits/misses +- Troubleshooting - Solve issues