mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-11-13 12:13:36 +01:00
feat(youko): add pull-through cache for two Nix upstreams (#499)
Run nginx on youko as a loopback pull-through HTTP cache for cache.nixos.org and cache.numtide.com, exposed by Caddy at https://nix-cache.writefor.fun. Assisted-by: DeepSeek Harness (deepseek-flash)
This commit is contained in:
1 parent
9fe86de51d
commit
58d1af8f9d
9 files changed
+136
-8
No files matched your search
@@ -199,8 +199,7 @@ defaults become less transparent than a file you can read in the diff; your deli
|
|||||||
|
|
||||||
## A7. attic self-hosted binary cache
|
## A7. attic self-hosted binary cache
|
||||||
|
|
||||||
**Current:** substituters are the two Chinese mirrors plus numtide's cache; a cachix endpoint exists
|
**Current:** substituters are the two Chinese mirrors plus numtide's cache.
|
||||||
in the config but is unused.
|
|
||||||
|
|
||||||
**Proposed:** `services.networking.atticd` on youko.
|
**Proposed:** `services.networking.atticd` on youko.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
{ myvars, ... }:
|
||||||
|
let
|
||||||
|
cacheDir = "/data/apps/nix-cache-proxy";
|
||||||
|
inherit (myvars.ports) youkoNixCacheProxy;
|
||||||
|
|
||||||
|
# Nix clients verify narinfo signatures and NAR hashes, so this only needs to
|
||||||
|
# be a transparent HTTP cache, not a Nix-aware store. Keep it on the btrfs
|
||||||
|
# data volume, never on the /data tmpfs.
|
||||||
|
cacheConfig = ''
|
||||||
|
proxy_ssl_server_name on;
|
||||||
|
proxy_ssl_verify on;
|
||||||
|
proxy_ssl_verify_depth 3;
|
||||||
|
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-bundle.crt;
|
||||||
|
|
||||||
|
proxy_cache nix_cache;
|
||||||
|
proxy_cache_key "$scheme$request_method$host$request_uri";
|
||||||
|
proxy_cache_valid 200 206 30d;
|
||||||
|
proxy_cache_valid 404 1m;
|
||||||
|
proxy_cache_lock on;
|
||||||
|
proxy_cache_lock_timeout 60s;
|
||||||
|
proxy_cache_use_stale
|
||||||
|
error timeout updating
|
||||||
|
http_500 http_502 http_503 http_504;
|
||||||
|
|
||||||
|
add_header X-Cache-Status $upstream_cache_status always;
|
||||||
|
'';
|
||||||
|
|
||||||
|
cacheLocation = upstream: {
|
||||||
|
proxyPass = "https://${upstream}/";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header Host ${upstream};
|
||||||
|
${cacheConfig}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
appendHttpConfig = ''
|
||||||
|
proxy_cache_path ${cacheDir}
|
||||||
|
levels=1:2
|
||||||
|
keys_zone=nix_cache:256m
|
||||||
|
max_size=300g
|
||||||
|
inactive=30d
|
||||||
|
use_temp_path=off;
|
||||||
|
'';
|
||||||
|
|
||||||
|
virtualHosts."nix-cache-proxy" = {
|
||||||
|
# Caddy owns the public listener and terminates HTTPS; nginx is internal.
|
||||||
|
listen = [
|
||||||
|
{
|
||||||
|
addr = "127.0.0.1";
|
||||||
|
port = youkoNixCacheProxy;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
locations = {
|
||||||
|
"/cache.nixos.org/" = cacheLocation "cache.nixos.org";
|
||||||
|
"/cache.numtide.com/" = cacheLocation "cache.numtide.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# `proxy_cache_path` is created at runtime; nginx owns it.
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${cacheDir} 0755 nginx nginx - -"
|
||||||
|
];
|
||||||
|
systemd.services.nginx = {
|
||||||
|
unitConfig.RequiresMountsFor = [ "/data/apps" ];
|
||||||
|
# The NixOS nginx unit runs with ProtectSystem=strict; the custom cache
|
||||||
|
# path must be explicitly writable.
|
||||||
|
serviceConfig.ReadWritePaths = [ cacheDir ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Public Let's Encrypt wildcard, already managed by the Caddy module. This
|
||||||
|
# avoids distributing the private homelab CA to clients that only consume the
|
||||||
|
# cache (including macOS).
|
||||||
|
services.caddy.virtualHosts."nix-cache.writefor.fun".extraConfig = ''
|
||||||
|
tls /var/lib/acme/writefor.fun/fullchain.pem /var/lib/acme/writefor.fun/key.pem {
|
||||||
|
protocols tls1.3 tls1.3
|
||||||
|
curves x25519 secp384r1 secp521r1
|
||||||
|
}
|
||||||
|
reverse_proxy http://127.0.0.1:${toString youkoNixCacheProxy}
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -8,7 +8,8 @@
|
|||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (myvars.networking.hostsAddr.aquamarine) ipv4;
|
inherit (myvars.networking.hostsAddr.aquamarine) ipv4;
|
||||||
port = 18080;
|
inherit (myvars.ports) aquamarineAsr;
|
||||||
|
port = aquamarineAsr;
|
||||||
|
|
||||||
# OpenVINO publishes static IRs for Whisper only, and the NPU compiler accepts
|
# OpenVINO publishes static IRs for Whisper only, and the NPU compiler accepts
|
||||||
# nothing less: any other ASR family keeps a dynamic time axis and aborts it
|
# nothing less: any other ASR family keeps a dynamic time axis and aborts it
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
# The official https://cache.nixos.org is always trusted and is appended
|
# The official https://cache.nixos.org is always trusted and is appended
|
||||||
# automatically, so it does not need to be listed here.
|
# automatically, so it does not need to be listed here.
|
||||||
substituters = [
|
substituters = [
|
||||||
# cache mirror located in China
|
# Domestic mirrors are fast from the LAN; query them directly first.
|
||||||
# status: https://mirrors.ustc.edu.cn/status/
|
# status: https://mirrors.ustc.edu.cn/status/
|
||||||
"https://mirrors.ustc.edu.cn/nix-channels/store"
|
"https://mirrors.ustc.edu.cn/nix-channels/store"
|
||||||
# status: https://mirror.sjtu.edu.cn/
|
# status: https://mirror.sjtu.edu.cn/
|
||||||
@@ -37,11 +37,14 @@
|
|||||||
# "https://mirrors.sustech.edu.cn/nix-channels/store"
|
# "https://mirrors.sustech.edu.cn/nix-channels/store"
|
||||||
"https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store"
|
"https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store"
|
||||||
|
|
||||||
|
# Pull-through cache for upstreams that are slow from the LAN. Nix
|
||||||
|
# appends the official cache.nixos.org last, so list its proxy here.
|
||||||
|
"https://nix-cache.writefor.fun/cache.nixos.org"
|
||||||
# numtide's cache (niks3), which serves the prebuilt packages of the
|
# numtide's cache (niks3), which serves the prebuilt packages of the
|
||||||
# numtide/llm-agents.nix flake input used for the AI agent CLIs.
|
# numtide/llm-agents.nix flake input used for the AI agent CLIs.
|
||||||
|
"https://nix-cache.writefor.fun/cache.numtide.com"
|
||||||
|
# Direct fallback if the LAN proxy is unavailable.
|
||||||
"https://cache.numtide.com"
|
"https://cache.numtide.com"
|
||||||
# my own cache server, currently not used.
|
|
||||||
# "https://ryan4yin.cachix.org"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# WARNING: every key here trusts *everything* that key signs. Add one only
|
# WARNING: every key here trusts *everything* that key signs. Add one only
|
||||||
@@ -49,7 +52,6 @@
|
|||||||
# a third party the ability to ship you arbitrary store paths.
|
# a third party the ability to ship you arbitrary store paths.
|
||||||
trusted-public-keys = [
|
trusted-public-keys = [
|
||||||
"niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g="
|
"niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g="
|
||||||
"ryan4yin.cachix.org-1:Gbk27ZU5AYpGS9i3ssoLlwdvMIh0NxG0w8it/cv9kbU="
|
|
||||||
];
|
];
|
||||||
builders-use-substitutes = true;
|
builders-use-substitutes = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
nginxEnabled = true;
|
||||||
|
caddyVhostExists = true;
|
||||||
|
ustcRemainsFirst = true;
|
||||||
|
nixosProxyConfigured = true;
|
||||||
|
numtideProxyConfigured = true;
|
||||||
|
numtideDirectFallback = true;
|
||||||
|
cacheLivesOnDataVolume = true;
|
||||||
|
nixosUpstream = "https://cache.nixos.org/";
|
||||||
|
numtideUpstream = "https://cache.numtide.com/";
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
outputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = outputs.nixosConfigurations.youko.config;
|
||||||
|
nginx = cfg.services.nginx;
|
||||||
|
substituters = cfg.nix.settings.substituters;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nginxEnabled = nginx.enable;
|
||||||
|
caddyVhostExists = cfg.services.caddy.virtualHosts ? "nix-cache.writefor.fun";
|
||||||
|
ustcRemainsFirst = builtins.head substituters == "https://mirrors.ustc.edu.cn/nix-channels/store";
|
||||||
|
nixosProxyConfigured = builtins.elem "https://nix-cache.writefor.fun/cache.nixos.org" substituters;
|
||||||
|
numtideProxyConfigured = builtins.elem "https://nix-cache.writefor.fun/cache.numtide.com" substituters;
|
||||||
|
numtideDirectFallback = builtins.elem "https://cache.numtide.com" substituters;
|
||||||
|
cacheLivesOnDataVolume = lib.hasInfix "/data/apps/nix-cache-proxy" nginx.appendHttpConfig;
|
||||||
|
nixosUpstream = nginx.virtualHosts."nix-cache-proxy".locations."/cache.nixos.org/".proxyPass;
|
||||||
|
numtideUpstream = nginx.virtualHosts."nix-cache-proxy".locations."/cache.numtide.com/".proxyPass;
|
||||||
|
}
|
||||||
+2
-1
@@ -8,7 +8,8 @@ Common variables and configuration used across my NixOS and nix-darwin configura
|
|||||||
vars/
|
vars/
|
||||||
├── README.md
|
├── README.md
|
||||||
├── default.nix # Main variables entry point
|
├── default.nix # Main variables entry point
|
||||||
└── networking.nix # Network configuration and host definitions
|
├── networking.nix # Network configuration and host definitions
|
||||||
|
└── ports.nix # Loopback HTTP backend port registry
|
||||||
```
|
```
|
||||||
|
|
||||||
## Components
|
## Components
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
userfullname = "Ryan Yin";
|
userfullname = "Ryan Yin";
|
||||||
useremail = "xiaoyin_c@qq.com";
|
useremail = "xiaoyin_c@qq.com";
|
||||||
networking = import ./networking.nix { inherit lib; };
|
networking = import ./networking.nix { inherit lib; };
|
||||||
|
ports = import ./ports.nix;
|
||||||
# Generated using: mkpasswd -m yescrypt --rounds=11
|
# Generated using: mkpasswd -m yescrypt --rounds=11
|
||||||
# Password: long, strong random string (full charset)
|
# Password: long, strong random string (full charset)
|
||||||
# Rotation policy: changed annually
|
# Rotation policy: changed annually
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
# Loopback-only HTTP backends behind Caddy. Allocate services sequentially
|
||||||
|
# from 18080; keep this list sorted by port.
|
||||||
|
aquamarineAsr = 18080;
|
||||||
|
youkoNixCacheProxy = 18081;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user