Categorygithub.com/117503445/nix-binary-cache
modulepackage
0.0.0-20250212154701-c80965feba12
Repository: https://github.com/117503445/nix-binary-cache.git
Documentation: pkg.go.dev

# README

nix-binary-cache

An easy-to-deploy and maintain NixOS binary cache service

Many existing NixOS binary cache services, such as nix-serve, nix-serve-ng, attic, etc., require Nix for their own deployment. I find this quite absurd. Deploying a NixOS cache service should have a simpler and more universal approach.

nix-binary-cache is an extremely simple NixOS binary cache service.

  • It can configure multiple upstream mirror sources and set up independent proxies for each.
  • It maintains a cache on the local filesystem to avoid repeated access to upstream mirrors.
  • It supports uploading built packages to the filesystem cache on NixOS.
  • It is implemented in Go and can be easily deployed using Docker Compose!

Quick Start

Prepare the configuration file and Docker Compose declaration file.

git clone https://github.com/117503445/nix-binary-cache.git
cd nix-binary-cache/docs/example

Start the service.

docker compose up -d

Using the Mirror

Include the following in flake.nix:

nixConfig = {
  require-sigs = false;
};

When executing switch, specify the cache service address via --option substituters to use the cache service.

nixos-rebuild switch --accept-flake-config --print-build-logs --show-trace --option substituters http://SERVER_IP:8080

Using the Mirror and Pushing Cache [Recommended]

Include the following in flake.nix:

nixConfig = {
  require-sigs = false;
  post-build-hook = ./scripts/upload-to-cache.sh;
};

The content of ./scripts/upload-to-cache.sh is:

#!/bin/sh

# https://nix.dev/manual/nix/2.19/advanced-topics/post-build-hook
set -eu

echo "Uploading to cache, paths: $OUT_PATHS"
echo "NIX_CACHE_URL: $NIX_CACHE_URL"

# if "ustc" in $NIX_CACHE_URL, skip
if echo "$NIX_CACHE_URL" | grep -q "ustc"; then
    echo "Skip uploading to cache"
    exit 0
fi

nix copy --no-check-sigs --to $NIX_CACHE_URL $OUT_PATHS

When executing switch, the upload-to-cache.sh script will be triggered after each package build, uploading the built package to the cache service via nix copy.

NIX_CACHE_URL=http://SERVER_IP:8080 nixos-rebuild switch --accept-flake-config --print-build-logs --show-trace --option substituters http://SERVER_IP:8080

Configuration Reference

Using a TOML format configuration file, take the configuration in the quick start as an example:

[[upstreams]]
url = "https://mirrors.ustc.edu.cn/nix-channels/store"

[[upstreams]]
url = "https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store"

[[upstreams]]
url = "https://cache.nixos.org"
proxy = "http://host.docker.internal:1080"

Multiple upstreams are configured in order. Each upstream has a mandatory url and an optional proxy. When proxy is empty, it defaults to using a direct connection. When proxy is not empty, it connects to the upstream mirror source via an HTTP/SOCKS5 proxy server.

Implementation

After setting substituters, the HTTP API calls initiated by Nix can be simplified as:

PUT $PATH with $CONTENT: Write $CONTENT to a certain HTTP Path
GET $PATH: Read $CONTENT from a certain HTTP Path

nix-binary-cache maps a $PATH to a filesystem path using SHA256. It then handles PUT and GET requests from Nix:

  • For PUT requests, if the corresponding cache path does not exist, create the file and write the content.
  • For GET requests:
    • If the corresponding cache path exists, return the corresponding content and 200.
    • If the corresponding cache path does not exist, sequentially access the upstream mirrors. If it exists, return the corresponding content and 200, and write to the cache path.
    • If none of the upstream mirrors exist, return 404.

Note that Nix's HTTP API actual calling rules are more complex, with certain PATHs having special semantics, and they do not seem to be standardized or documented. However, in my own usage, this implementation works flawlessly.

References

https://www.rectcircle.cn/posts/nix-4-http-binary-cache/

# Packages

No description provided by the author

# Functions

No description provided by the author
No description provided by the author

# Structs

No description provided by the author
No description provided by the author
No description provided by the author