Skip to content

sophronesis/peerix

 
 

Repository files navigation

Peerix

Peer-to-peer binary cache for Nix. Share derivations between machines via Iroh P2P or local network broadcast. Basically like torrent tracker, but for your /nix/store/

Quick Start

Add to flake.nix inputs:

inputs.peerix.url = "github:sophronesis/peerix";

Add peerix.nixosModules.peerix to your modules, then in configuration.nix:

Iroh Mode (default)

Uses Iroh for NAT-traversing P2P connectivity with automatic relay fallback:

services.peerix.enable = true;
# trackerUrl defaults to "https://sophronesis.dev/peerix"

LAN Mode

Zero-config peer discovery on local networks (no internet required). Set trackerUrl = null to use LAN mode:

services.peerix = {
  enable = true;
  trackerUrl = null;  # Use LAN mode instead of Iroh
};

Mode is auto-selected based on trackerUrl:

  • trackerUrl set (default) → Iroh mode (P2P with NAT traversal via tracker)
  • trackerUrl = nullLAN mode (UDP broadcast, local network only)

Run Your Own Tracker

# On server
services.peerix-tracker.enable = true;

# On clients
services.peerix.trackerUrl = "http://your-server:12305";

How It Works

Peerix implements a Nix binary cache. When Nix queries peerix for a package:

  1. Iroh mode: Queries peers via Iroh P2P protocol, fetches NAR directly from peer
  2. LAN mode: Broadcasts UDP request, peers respond if they have the package

Store path hashes are verified against cache.nixos.org by default.

Iroh Mode Details

  • NAT traversal via Iroh relay servers (euw1-1.relay.iroh.network)
  • Direct peer connections when possible
  • Persistent node identity across restarts
  • Connection pooling with retry logic
  • Pre-buffered NAR streaming for reliability
  • Web dashboard at http://localhost:12304/dashboard
  • Health check at http://localhost:12304/health
  • Prometheus metrics at http://localhost:12304/metrics

Configuration

Option Default Description
enable false Enable peerix
trackerUrl "https://sophronesis.dev/peerix" Tracker URL (null=LAN mode, set=Iroh mode)
openFirewall true Open firewall ports
privateKeyFile null Path to signing key
publicKey null Public key for signature verification
priority 5 Cache priority (lower = higher priority)
timeout 10.0 Connection timeout in seconds
scanInterval 3600 Seconds between store scans (0 to disable)

Tracker Options

Option Default Description
services.peerix-tracker.enable false Enable tracker server
services.peerix-tracker.port 12305 Tracker HTTP port

Signing

Generate a key pair:

nix-store --generate-binary-cache-key myhost cache-priv-key.pem cache-pub-key.pem

Set privateKeyFile on the serving node and publicKey (or publicKeyFile) on consuming nodes so nix can verify signatures.

Alternatively, set NIX_SECRET_KEY_FILE environment variable — peerix will sign narinfo responses with ed25519 directly (requires pynacl).

Dashboard

Peerix includes a web dashboard at http://localhost:12304/dashboard:

  • Node Status: Iroh node ID, relay URL, direct addresses
  • Peers: Connected peers with country flags and IPs
  • Store: Available hashes, filter progress, scan status
  • Most Requested: Top requested derivations
  • Most Served: Top served derivations with per-peer tracking
  • Activity Log: Recent checks, downloads, and serves with peer IDs

Stats persist across restarts to /var/lib/peerix/stats.json.

Configuration Options

Peerix Service

Option Description Default
services.peerix.enable Enables Peerix false
services.peerix.trackerUrl Tracker URL (null=LAN mode, set=Iroh mode) "https://sophronesis.dev/peerix"
services.peerix.openFirewall Open the necessary firewall ports true
services.peerix.user User to run the peerix service under "nobody"
services.peerix.group Group to run the peerix service under "nobody"
services.peerix.privateKeyFile Path to the private key file for signing null
services.peerix.publicKeyFile Path to the public key file for verification null
services.peerix.publicKey Public key string for verification null
services.peerix.upstreamCache Upstream cache URL for hash verification "https://cache.nixos.org"
services.peerix.priority Cache priority (lower = higher priority) 5
services.peerix.timeout Connection timeout in seconds 10.0
services.peerix.scanInterval Seconds between store scans (0 to disable) 3600
services.peerix.filterMode Filter mode: "nixpkgs" or "rules" "nixpkgs"
services.peerix.filterConcurrency Max concurrent filter requests 10
services.peerix.noFilter Disable filtering (serve all packages) false
services.peerix.noVerify Disable hash verification against upstream false
services.peerix.allowInsecureHttp Allow HTTP (non-TLS) connections false
services.peerix.lanDiscovery Enable LAN discovery alongside Iroh false

Tracker Service

Option Description Default
services.peerix-tracker.enable Enable the peerix tracker server false
services.peerix-tracker.port Port for the tracker HTTP server 12305
services.peerix-tracker.dbPath Path to the tracker SQLite database "/var/lib/peerix-tracker/tracker.db"
services.peerix-tracker.openFirewall Open the firewall for the tracker port true

Security

  • Hash verification: Store path hashes verified against upstream cache before sharing
  • NixpkgsFilteredStore: Only serves packages that exist in cache.nixos.org
  • Narinfo signing: When NIX_SECRET_KEY_FILE or privateKeyFile is set, narinfo responses are signed with ed25519
  • Localhost restriction: Main narinfo endpoint restricted to 127.0.0.1

Network Protocol

  • Iroh: Custom protocols /peerix/narinfo/1.0.0 and /peerix/nar/1.0.0 over QUIC. NAT traversal via relay servers, direct connections when possible.
  • LAN: UDP port 12304 for broadcast-based peer discovery. Packet byte 0 is message type (0=request, 1=response), bytes 1-4 are request ID.
  • HTTP: Port 12304 serves local narinfo/NAR to peers and proxied remote content to the local nix daemon.
  • Tracker: HTTP API for peer registration and package hash lookup.

Dependencies

  • Python 3.12+: trio, starlette, httpx, pynacl, uvicorn
  • Iroh mode: iroh Python bindings
  • System: nix, nix-serve

CLI Usage

# Run with Iroh mode (default)
peerix-iroh --port 12304 --tracker https://sophronesis.dev/peerix --verbose

# Run with LAN discovery enabled (supplements Iroh)
peerix-iroh --lan-discovery --verbose

# Options
--config, -c    Path to config file (default: ~/.config/peerix/config.toml)
--port          HTTP port (default: 12304)
--tracker       Tracker URL for peer discovery
--peer-id       Human-readable peer ID (default: hostname)
--priority      Cache priority (default: 5)
--timeout       Connection timeout in seconds (default: 10)
--state-dir     Directory for persistent state
--private-key   Path to signing key
--scan-interval Seconds between store scans (default: 3600)
--no-filter     Disable package filtering
--no-verify     Disable hash verification
--filter-concurrency  Max concurrent filter requests (default: 10)
--lan-discovery Enable LAN peer discovery via UDP broadcast
--verbose       Enable verbose logging

Version History

  • v0.0.4: Health/metrics endpoints, peer reputation, unified LAN+Iroh, config file, test suite
  • v0.0.3: Iroh P2P integration, dashboard, peer tracking, stats persistence
  • v0.0.2: IPFS mode, filtering, verification
  • v0.0.1: Initial release with LAN mode

About

Peer2Peer Nix-Binary-Cache

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Python 91.3%
  • Nix 4.9%
  • Shell 3.8%