Introduction
Introduction Statistics Contact Development Disclaimer Help
Title: How to make a local NixOS cache server
Author: Solène
Date: 02 June 2022
Tags: nixos unix bandwidth nocloud
Description: This explains how to create your own local cache for NixOS
packages in order to save bandwidth.
# Introduction
If like me, you have multiple NixOS system behind the same router, you
may want to have a local shared cache to avoid downloading packages
multiple time.
This can be done simply by using nginx as a reverse proxy toward the
official repository and by enabling caching the result.
nix-binary-cache-proxy project I used as a base
# Server side configuration
We will declare a nginx service on the server, using http protocol only
to make setup easier. The packages are signed, so their authenticity
can't be faked. In this setup, using https would add anonymity which
is not much of a concern in a local network, for my use case.
In the following setup, the LAN cache server will be reachable at the
address 10.42.42.150, and will be using the DNS resolver 10.42.42.42
every time it needs to reach the upstream server.
```nix code
services.nginx = {
enable = true;
appendHttpConfig = ''
proxy_cache_path /tmp/pkgcache levels=1:2 keys_zone=cachecache:100m max_s…
# Cache only success status codes; in particular we don't want to cache 4…
# See https://serverfault.com/a/690258/128321
map $status $cache_header {
200 "public";
302 "public";
default "no-cache";
}
access_log /var/log/nginx/access.log;
'';
virtualHosts."10.42.42.150" = {
locations."/" = {
root = "/var/public-nix-cache";
extraConfig = ''
expires max;
add_header Cache-Control $cache_header always;
# Ask the upstream server if a file isn't available locally
error_page 404 = @fallback;
'';
};
extraConfig = ''
# Using a variable for the upstream endpoint to ensure that it is
# resolved at runtime as opposed to once when the config file is loaded
# and then cached forever (we don't want that):
# see https://tenzer.dk/nginx-with-dynamic-upstreams/
# This fixes errors like
# nginx: [emerg] host not found in upstream "upstream.example.com"
# when the upstream host is not reachable for a short time when
# nginx is started.
resolver 10.42.42.42;
set $upstream_endpoint http://cache.nixos.org;
'';
locations."@fallback" = {
proxyPass = "$upstream_endpoint";
extraConfig = ''
proxy_cache cachecache;
proxy_cache_valid 200 302 60d;
expires max;
add_header Cache-Control $cache_header always;
'';
};
# We always want to copy cache.nixos.org's nix-cache-info file,
# and ignore our own, because `nix-push` by default generates one
# without `Priority` field, and thus that file by default has priority
# 50 (compared to cache.nixos.org's `Priority: 40`), which will make
# download clients prefer `cache.nixos.org` over our binary cache.
locations."= /nix-cache-info" = {
# Note: This is duplicated with the `@fallback` above,
# would be nicer if we could redirect to the @fallback instead.
proxyPass = "$upstream_endpoint";
extraConfig = ''
proxy_cache cachecache;
proxy_cache_valid 200 302 60d;
expires max;
add_header Cache-Control $cache_header always;
'';
};
};
};
```
Be careful, the default cache is located under /tmp/ but the nginx
systemd service is hardened and its /tmp/ is faked in a temporary
directory, meaning if you restart nginx you lose the cache. I'd advise
using a directory like /var/cache/nginx/ if you want your cache to
persist across restarts.
# Client side configuration
Using the cache server on a system is really easy. We will define the
binary cache to our new local server, the official cache is silently
added so we don't have to list it.
```nix code
nix.binaryCaches = [ "http://10.42.42.150/" ];
```
Note that you have to use this on the cache server itself if you want
the system to use the cache for its own needs.
# Conclusion
Using a local cache can save a lot of bandwidth when you have more than
one computer at home (or if you extensively use nix-shell and often run
the garbage collector). Due to NixOS packages names being unique, we
won't have any issues of a newer package version behind hidden by a
local copy cached, which make the setup really easy.
You are viewing proxied material from dataswamp.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.