Nix binary cache proxy service -- with local caching and signing.
Find a file
Wael Nasreddine 757e6c7e36
feat: Add readiness probes to process-compose services (#377)
# Add readiness probes to process-compose services

This PR adds readiness probes to the Minio, PostgreSQL, and MariaDB initialization services in the process-compose configuration. Each service now:

1. Removes any stale marker files from previous runs at startup
2. Creates a marker file when initialization is complete
3. Uses a readiness probe that checks for the existence of these marker files

The readiness probes are configured with:
- An initial delay of 3 seconds
- A check period of 1 second
- An exec command that tests for the appropriate marker file

This change improves the reliability of service dependencies by ensuring services are fully initialized before dependent services attempt to use them.
2025-12-29 23:42:13 -08:00
.claude feat: Add PostgreSQL database support (#373) 2025-12-29 22:37:41 -08:00
.github/workflows ci: Restrict vendor hash workflow to only run on PRs targeting main branch (#380) 2025-12-29 22:56:22 -08:00
cmd fix: Deprecated --upstream-cache should work (#368) 2025-12-29 15:00:59 -08:00
db feat: Add MySQL/MariaDB database backend support (#374) 2025-12-29 23:31:44 -08:00
dev-scripts refactor: Rename upstream flags to use --cache-upstream-* prefix (#367) 2025-12-29 13:45:14 -08:00
nix feat: Add readiness probes to process-compose services (#377) 2025-12-29 23:42:13 -08:00
pkg feat: Add MySQL/MariaDB database backend support (#374) 2025-12-29 23:31:44 -08:00
testdata fix: Fix all lint issues (#260) 2025-08-22 22:42:48 +00:00
testhelper feat: Add MySQL/MariaDB database backend support (#374) 2025-12-29 23:31:44 -08:00
.env sqlc: define the schema/queries and make use of generated models (#71) 2024-12-11 00:49:37 +00:00
.envrc Direnv: watch the entire nix/ directory. (#93) 2024-12-12 16:48:08 +00:00
.gitignore Direnv: use flake instead of devbox (#89) 2024-12-12 15:54:53 +00:00
.golangci.yml chore(flake): Update nixpkgs to release 25.11 (#341) 2025-11-27 07:17:19 +00:00
.sqlfluff feat: Add PostgreSQL database support (#373) 2025-12-29 22:37:41 -08:00
CLAUDE.md feat: Add MySQL/MariaDB database backend support (#374) 2025-12-29 23:31:44 -08:00
config.example.yaml feat: Add MySQL/MariaDB database backend support (#374) 2025-12-29 23:31:44 -08:00
flake.lock chore: Update dependencies and vendorHash (#360) 2025-12-27 06:26:23 +00:00
flake.nix feat: Add MinIO integration with process-compose (#351) 2025-12-26 02:50:43 -08:00
go.mod feat: Add MySQL/MariaDB database backend support (#374) 2025-12-29 23:31:44 -08:00
go.sum feat: Add MySQL/MariaDB database backend support (#374) 2025-12-29 23:31:44 -08:00
LICENSE Initial commit 2024-11-27 22:11:23 -08:00
main.go refactor: Handle errors gracefully instead of panicking (#326) 2025-09-24 23:19:26 -07:00
README.md feat: Add MySQL/MariaDB database backend support (#374) 2025-12-29 23:31:44 -08:00
renovate.json chore: Configure Renovate (#95) 2024-12-12 23:48:25 +00:00
sqlc.yml feat: Add MySQL/MariaDB database backend support (#374) 2025-12-29 23:31:44 -08:00

🚀 ncps: Nix Cache Proxy Server

A high-performance proxy server that accelerates Nix dependency retrieval across your local network by caching and serving packages locally.

Go Report Card License: MIT

📋 Table of Contents

🎯 Overview

ncps acts as a local binary cache for Nix, fetching store paths from upstream caches (like cache.nixos.org) and storing them locally. This reduces download times and bandwidth usage, especially beneficial when multiple machines share the same dependencies.

🔍 Problem & Solution

The Problem

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

The Solution

ncps solves these issues by acting as a centralized cache on your local network, dramatically reducing redundant downloads and improving build performance.

Key Features

Feature Description
🚀 Easy Setup Simple configuration and deployment
🔄 Multi-Upstream Support for multiple upstream caches with failover
💾 Smart Caching LRU cache management with configurable size limits
☁️ Flexible Storage NEW in v0.5.0: Choose between local filesystem or S3-compatible storage (AWS S3, MinIO, etc.)
🔐 Secure Signing Signs cached paths with private keys for integrity
📊 Monitoring OpenTelemetry support for centralized logging
🗜️ Compression Harmonia's transparent zstd compression support
🗄️ Database Support SQLite (embedded), PostgreSQL, or MySQL/MariaDB for metadata storage

⚙️ How It Works

Request Flow

sequenceDiagram
    participant Client as Nix Client
    participant NCPS as ncps Server
    participant Cache as Cache Storage
    participant Upstream as Upstream Cache

    Client->>NCPS: Request store path
    NCPS->>Cache: Check cache

    alt Path exists in cache
        Cache-->>NCPS: Return cached path
        NCPS-->>Client: Serve cached path
    else Path not cached
        NCPS->>Upstream: Fetch from upstream
        Upstream-->>NCPS: Return store path
        NCPS->>Cache: Cache and sign path
        NCPS-->>Client: Serve downloaded path
    end
  1. Request - Nix client requests a store path from ncps
  2. Cache Check - ncps checks if the path exists in cache storage
  3. Upstream Fetch - If not cached, fetches from configured upstream caches
  4. Cache & Sign - Stores and signs the path with ncps private key
  5. Serve - Delivers the path to the requesting client

Storage Architecture

NEW in v0.5.0: ncps now supports flexible storage backends!

graph TB
    NCPS[ncps Server]

    subgraph Database["Database Backends (Choose One)"]
        SQLite[(SQLite<br/>--cache-database-url sqlite:...)]
        Postgres[(PostgreSQL<br/>--cache-database-url postgresql:...)]
        MySQL[(MySQL/MariaDB<br/>--cache-database-url mysql:...)]
    end

    subgraph Storage["Storage Backends (Choose One)"]
        Local[Local Filesystem<br/>--cache-storage-local]
        S3[S3-Compatible Storage<br/>--cache-storage-s3-*]
    end

    subgraph S3Detail["S3-Compatible Options"]
        AWS[AWS S3]
        MinIO[MinIO]
        Other[Other S3-Compatible]
    end

    NCPS -.->|Option 1| SQLite
    NCPS -.->|Option 2| Postgres
    NCPS -.->|Option 3| MySQL
    NCPS -.->|Option A| Local
    NCPS -.->|Option B| S3
    S3 --> S3Detail

    style Database fill:#ffe1f5
    style Storage fill:#e1f5ff
    style S3Detail fill:#fff4e1
    style NCPS fill:#d4edda

Database Options:

  • SQLite (default) - Embedded database for single-server deployments, no external dependencies
  • PostgreSQL - Scalable relational database for production deployments
  • MySQL/MariaDB - Popular open-source relational database for production deployments

Storage Options:

  • Local Filesystem - Traditional file-based storage for single-server deployments
  • S3-Compatible Storage - Scalable cloud storage supporting AWS S3, MinIO, and other S3-compatible services

🚀 Quick Start

Get ncps running quickly with Docker:

Using Local Storage
# Pull the images
docker pull alpine
docker pull kalbasit/ncps

# Create the storage volume
docker volume create ncps-storage
docker run --rm -v ncps-storage:/storage alpine /bin/sh -c \
  "mkdir -m 0755 -p /storage/var && mkdir -m 0700 -p /storage/var/ncps && mkdir -m 0700 -p /storage/var/ncps/db"

# Initialize database
docker run --rm -v ncps-storage:/storage kalbasit/ncps /bin/dbmate --url=sqlite:/storage/var/ncps/db/db.sqlite migrate up

# Start the server
docker run -d --name ncps -p 8501:8501 -v ncps-storage:/storage kalbasit/ncps \
  /bin/ncps serve \
  --cache-hostname=your-ncps-hostname \
  --cache-storage-local=/storage \
  --cache-database-url=sqlite:/storage/var/ncps/db/db.sqlite \
  --cache-upstream-url=https://cache.nixos.org \
  --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
Using S3 Storage (NEW in v0.5.0)
# Pull the image
docker pull kalbasit/ncps

# Create volume for database only (cache data goes to S3)
docker volume create ncps-db
docker run --rm -v ncps-db:/db alpine mkdir -m 0700 -p /db

# Initialize database
docker run --rm -v ncps-db:/db kalbasit/ncps /bin/dbmate --url=sqlite:/db/db.sqlite migrate up

# Start the server with S3 storage
docker run -d --name ncps -p 8501:8501 -v ncps-db:/db kalbasit/ncps \
  /bin/ncps serve \
  --cache-hostname=your-ncps-hostname \
  --cache-storage-s3-bucket=my-ncps-cache \
  --cache-storage-s3-endpoint=s3.amazonaws.com \
  --cache-storage-s3-region=us-east-1 \
  --cache-storage-s3-access-key-id=YOUR_ACCESS_KEY \
  --cache-storage-s3-secret-access-key=YOUR_SECRET_KEY \
  --cache-database-url=sqlite:/db/db.sqlite \
  --cache-upstream-url=https://cache.nixos.org \
  --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=

Benefits of S3 storage:

  • Scales independently of server resources
  • Shared storage across multiple ncps instances
  • Built-in durability and redundancy
  • Works with AWS S3, MinIO, and other S3-compatible services

Your cache will be available at http://localhost:8501 and the public key at http://localhost:8501/pubkey.

📦 Installation

🐳 Docker

Docker Setup

Step 1: Pull the image

docker pull kalbasit/ncps

Step 2: Initialize storage and database

docker volume create ncps-storage

docker run --rm -v ncps-storage:/storage alpine /bin/sh -c \
  "mkdir -m 0755 -p /storage/var && mkdir -m 0700 -p /storage/var/ncps && mkdir -m 0700 -p /storage/var/ncps/db"

docker run --rm -v ncps-storage:/storage kalbasit/ncps /bin/dbmate --url=sqlite:/storage/var/ncps/db/db.sqlite migrate up

Step 3: Start the server

docker run -d \
  --name ncps \
  -p 8501:8501 \
  -v ncps-storage:/storage \
  kalbasit/ncps \
  /bin/ncps serve \
  --cache-hostname=your-ncps-hostname \
  --cache-storage-local=/storage \
  --cache-database-url=sqlite:/storage/var/ncps/db/db.sqlite \
  --cache-upstream-url=https://cache.nixos.org \
  --cache-upstream-url=https://nix-community.cachix.org \
  --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= \
  --cache-upstream-public-key=nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
🐳 Docker Compose

Create a docker-compose.yml file:

services:
  create-directories:
    image: alpine:latest
    volumes:
      - ncps-storage:/storage
    command: >
      /bin/sh -c "
        mkdir -m 0755 -p /storage/var &&
        mkdir -m 0700 -p /storage/var/ncps &&
        mkdir -m 0700 -p /storage/var/ncps/db
      "
    restart: "no"

  migrate-database:
    image: kalbasit/ncps:latest
    depends_on:
      create-directories:
        condition: service_completed_successfully
    volumes:
      - ncps-storage:/storage
    command: >
      /bin/dbmate --url=sqlite:/storage/var/ncps/db/db.sqlite migrate up
    restart: "no"

  ncps:
    image: kalbasit/ncps:latest
    depends_on:
      migrate-database:
        condition: service_completed_successfully
    ports:
      - "8501:8501"
    volumes:
      - ncps-storage:/storage
    command: >
      /bin/ncps serve
      --cache-hostname=your-ncps-hostname
      --cache-storage-local=/storage
      --cache-database-url=sqlite:/storage/var/ncps/db/db.sqlite
      --cache-upstream-url=https://cache.nixos.org
      --cache-upstream-url=https://nix-community.cachix.org
      --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
      --cache-upstream-public-key=nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
    restart: unless-stopped

volumes:
  ncps-storage:

Then run:

docker compose up -d
☸️ Kubernetes
PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ncps
  labels:
    app: ncps
    tier: proxy
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: ncps
  labels:
    app: ncps
    tier: proxy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ncps
      tier: proxy
  template:
    metadata:
      labels:
        app: ncps
        tier: proxy
    spec:
      initContainers:
        - image: alpine:latest
          name: create-directories
          args:
            - /bin/sh
            - -c
            - "mkdir -m 0755 -p /storage/var && mkdir -m 0700 -p /storage/var/ncps && mkdir -m 0700 -p /storage/var/ncps/db"
          volumeMounts:
            - name: ncps-persistent-storage
              mountPath: /storage
        - image: kalbasit/ncps:latest # NOTE: It's recommended to use a tag here!
          name: migrate-database
          args:
            - /bin/dbmate
            - --url=sqlite:/storage/var/ncps/db/db.sqlite
            - migrate
            - up
          volumeMounts:
            - name: ncps-persistent-storage
              mountPath: /storage
      containers:
        - image: kalbasit/ncps:latest # NOTE: It's recommended to use a tag here!
          name: ncps
          args:
            - /bin/ncps
            - serve
            - --cache-hostname=ncps.yournetwork.local # TODO: Replace with your own hostname
            - --cache-storage-local=/storage
            - --cache-temp-path=/nar-temp-dir
            - --cache-database-url=sqlite:/storage/var/ncps/db/db.sqlite
            - --cache-upstream-url=https://cache.nixos.org
            - --cache-upstream-url=https://nix-community.cachix.org
            - --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
            - --cache-upstream-public-key=nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
          ports:
            - containerPort: 8501
              name: http-web
          volumeMounts:
            - name: ncps-persistent-storage
              mountPath: /storage
            - name: nar-temp-dir
              mountPath: /nar-temp-dir
      volumes:
        - name: ncps-persistent-storage
          persistentVolumeClaim:
            claimName: ncps
        - name: nar-temp-dir
          emptyDir:
            sizeLimit: 5Gi
Service
apiVersion: v1
kind: Service
metadata:
  name: ncps
  labels:
    app: ncps
    tier: proxy
spec:
  type: ClusterIP
  ports:
    - name: http-web
      port: 8501
  selector:
    app: ncps
    tier: proxy
🐧 NixOS

NixOS Service Module

ncps is available as a built-in NixOS service module (available in NixOS 25.05+). No additional installation needed!

Basic Configuration:

{
  services.ncps = {
    enable = true;
    cache.hostName = "your-ncps-hostname";
    upstream = {
      caches = [
        "https://cache.nixos.org"
        "https://nix-community.cachix.org"
      ];
      publicKeys = [
        "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
        "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
      ];
    };
  };
}

Advanced Configuration:

{
  services.ncps = {
    enable = true;
    cache = {
      hostName = "your-ncps-hostname";
      dataPath = "/path/to/ncps/data";
      tempPath = "/path/to/ncps/tmp"; # Introduced in NixOS 25.09
      databaseURL = "sqlite:/path/to/ncps/db/db.sqlite";
      maxSize = "50G";
      lru.schedule = "0 2 * * *"; # Clean up daily at 2 AM
      allowPutVerb = true;
      allowDeleteVerb = true;
    };
    server.addr = "0.0.0.0:8501";
    upstream = {
      caches = [
        "https://cache.nixos.org"
        "https://nix-community.cachix.org"
      ];
      publicKeys = [
        "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
        "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
      ];
    };
  };
}

S3 Storage Support:

S3 storage configuration in the NixOS module will be available in a future release. For now, use the Docker or standalone installation methods for S3 storage.

Complete Options Reference: NixOS Options Search

The NixOS module automatically handles:

  • Database initialization and migrations
  • Systemd service configuration
  • User and group creation
  • Directory permissions
  • Service dependencies

📝 Note: After enabling the service, configure your clients to use the cache (see Client Setup section).

🔧 Go Install & Source

Install with Go

go install github.com/kalbasit/ncps@latest

Build from Source

git clone https://github.com/kalbasit/ncps.git
cd ncps
go build .

Note: You'll need to handle database setup and service management manually with these methods.

⚙️ Configuration

All the flags can be set using the configuration file. See config.example.yaml for a complete reference including S3 storage configuration examples.

Global Options

Option Description Environment Variable Default
--config Path to the configuration file (json, toml, yaml) NCPS_CONFIG_FILE $XDG_CONFIG_HOME/ncps/config.yaml
--otel-enabled Enable OpenTelemetry logs, metrics, and tracing OTEL_ENABLED false
--prometheus-enabled Enable Prometheus metrics endpoint at /metrics PROMETHEUS_ENABLED false
--log-level Set log level: debug, info, warn, error LOG_LEVEL info
--otel-grpc-url OpenTelemetry gRPC URL (omit for stdout) OTEL_GRPC_URL -

Server Configuration

🔧 Essential Options

Option Description Environment Variable Required
--cache-hostname Cache hostname for key generation CACHE_HOSTNAME
--cache-storage-local Local storage directory (use this OR S3 storage) CACHE_STORAGE_LOCAL (1)
--cache-upstream-url Upstream cache URL (repeatable) CACHE_UPSTREAM_URLS
--cache-upstream-public-key Upstream public key (repeatable) CACHE_UPSTREAM_PUBLIC_KEYS

Note (1): Either --cache-storage-local OR S3 storage flags (see below) are required, but not both.

☁️ S3 Storage Options (NEW in v0.5.0)

Use these options for S3-compatible storage instead of --cache-storage-local:

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 (e.g., s3.amazonaws.com, localhost: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-use-ssl Use SSL/TLS for S3 connection CACHE_STORAGE_S3_USE_SSL - true

S3 Storage Examples:

AWS S3
ncps serve \
  --cache-hostname=ncps.example.com \
  --cache-storage-s3-bucket=my-ncps-cache \
  --cache-storage-s3-endpoint=s3.amazonaws.com \
  --cache-storage-s3-region=us-east-1 \
  --cache-storage-s3-access-key-id=AKIAIOSFODNN7EXAMPLE \
  --cache-storage-s3-secret-access-key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
  --cache-database-url=sqlite:/var/lib/ncps/db.sqlite \
  --cache-upstream-url=https://cache.nixos.org \
  --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
MinIO
ncps serve \
  --cache-hostname=ncps.example.com \
  --cache-storage-s3-bucket=ncps-cache \
  --cache-storage-s3-endpoint=http://minio.example.com:9000 \
  --cache-storage-s3-access-key-id=minioadmin \
  --cache-storage-s3-secret-access-key=minioadmin \
  --cache-storage-s3-use-ssl=false \
  --cache-database-url=sqlite:/var/lib/ncps/db.sqlite \
  --cache-upstream-url=https://cache.nixos.org \
  --cache-upstream-public-key=cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=

Note: The endpoint URL scheme (http:// or https://) takes precedence over --cache-storage-s3-use-ssl.

📊 Database & Performance

Option Description Environment Variable Default
--cache-database-url Database URL (sqlite://, postgresql://, or mysql://) CACHE_DATABASE_URL embedded SQLite
--cache-max-size Max cache size (5K, 10G, etc.) CACHE_MAX_SIZE unlimited
--cache-lru-schedule Cleanup cron schedule CACHE_LRU_SCHEDULE -
--cache-temp-path Temporary download directory CACHE_TEMP_PATH system temp

🔐 Security & Signing

Option Description Environment Variable Default
--cache-sign-narinfo Sign narInfo files CACHE_SIGN_NARINFO true
--cache-secret-key-path Path to signing key CACHE_SECRET_KEY_PATH auto-generated
--cache-allow-put-verb Allow PUT uploads CACHE_ALLOW_PUT_VERB false
--cache-allow-delete-verb Allow DELETE operations CACHE_ALLOW_DELETE_VERB false
--netrc-file Path to netrc file for upstream auth NETRC_FILE ~/.netrc

⏱️ Upstream Connection Timeouts

Configure timeout values for upstream cache connections. Increase these values if you experience timeout errors with slow or remote upstream caches.

Option Description Environment Variable Default
--cache-upstream-dialer-timeout Timeout for establishing TCP connections to upstream caches CACHE_UPSTREAM_DIALER_TIMEOUT 3s
--cache-upstream-response-header-timeout Timeout for waiting for upstream server's response headers CACHE_UPSTREAM_RESPONSE_HEADER_TIMEOUT 3s

Common timeout values:

  • 3s - Default, works for most local/fast upstreams
  • 10s - Recommended for slow networks or distant upstreams
  • 30s - For very slow connections (e.g., satellite, slow VPN)

Example: For slow upstream connections, increase timeouts:

ncps serve \
  --cache-hostname=ncps.example.com \
  --cache-storage-local=/var/lib/ncps \
  --cache-upstream-url=https://cache.nixos.org \
  --cache-upstream-dialer-timeout=10s \
  --cache-upstream-response-header-timeout=10s

🌐 Network

Option Description Environment Variable Default
--server-addr Listen address and port SERVER_ADDR :8501

🔧 Client Setup

Get Your Public Key

First, retrieve the public key from your running ncps instance:

curl http://your-ncps-hostname:8501/pubkey

NixOS Configuration

Add ncps to your configuration.nix:

nix.settings = {
  substituters = [
    "http://your-ncps-hostname:8501"  # Use https:// if behind reverse proxy
    "https://cache.nixos.org"
    # ... other substituters
  ];

  trusted-public-keys = [
    "your-ncps-hostname=<paste-public-key-here>"
    "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
    # ... other keys
  ];
};

Non-NixOS Configuration

Edit your nix.conf file (typically /etc/nix/nix.conf or ~/.config/nix/nix.conf):

substituters = http://your-ncps-hostname:8501 https://cache.nixos.org
trusted-public-keys = your-ncps-hostname=<paste-public-key-here> cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=

🔧 Troubleshooting

🐳 Docker Issues

"no such table: nars" Error

Cause: Database not properly initialized

Solutions:

  1. Run migration first:

    docker run --rm -v ncps-storage:/storage kalbasit/ncps /bin/sh -c \
      "mkdir -m 0755 -p /storage/var && mkdir -m 0700 -p /storage/var/ncps && mkdir -m 0700 -p /storage/var/ncps/db && /bin/dbmate --url=sqlite:/storage/var/ncps/db/db.sqlite migrate up"
    
  2. Check database path consistency between migration and application

  3. Verify directory permissions (0700 for database directory)

"unable to open database file" Error

Cause: Permissions or volume mounting issues

Solutions:

  • Ensure storage volume is mounted to /storage
  • Check directory permissions
  • For bind mounts, ensure host directory is writable

Container Exits Immediately

Cause: Missing required parameters

Required options:

  • --cache-hostname
  • --cache-storage-local or (--cache-storage-s3-bucket and other --cache-storage-s3-* such as endpoint and credentials)
  • --cache-database-url
  • At least one --cache-upstream-url and --cache-upstream-public-key
🔍 General Issues

Cache Not Working

  1. Check public key setup:

    curl http://your-ncps-hostname:8501/pubkey
    
  2. Verify Nix configuration:

    nix show-config | grep substituters
    nix show-config | grep trusted-public-keys
    
  3. Test cache connectivity:

    curl http://your-ncps-hostname:8501/nix-cache-info
    

Performance Issues

  • Check available disk space
  • Monitor cache hit rates in logs
  • Consider adjusting --cache-max-size
  • Review LRU cleanup schedule

🤝 Contributing

Contributions are welcome! Here's how to get started:

Development Setup

  1. Clone the repository:

    git clone https://github.com/kalbasit/ncps.git
    cd ncps
    
  2. Start development server:

    The development script supports both local filesystem and S3-compatible storage:

    # Using local filesystem storage (default)
    ./dev-scripts/run.sh
    # or explicitly
    ./dev-scripts/run.sh local
    
    # Using S3/MinIO storage (requires MinIO to be running)
    # First, start dependencies in a separate terminal:
    nix run .#deps  # Starts MinIO with self-validation
    
    # Then run the dev server with S3 backend:
    ./dev-scripts/run.sh s3
    

    The script auto-restarts on code changes using watchexec.

    Storage Backends:

    • local: Uses local filesystem storage (default, no dependencies)
    • s3: Uses S3-compatible storage via MinIO (requires nix run .#deps)

    Dependencies Management:

    • nix run .#deps starts MinIO server configured for local development
    • MinIO runs with self-validation to ensure proper setup
    • Configuration matches the S3 settings in the dev script
  3. Submit your changes:

    • 🐛 Open issues for bugs
    • Submit pull requests for features
    • 📚 Improve documentation

Getting Help


📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


Found this helpful? Give us a star!

Report BugRequest FeatureContribute