mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-11-13 12:13:46 +01:00
* chore(aquamarine): take the NPU stack from nixos-unstable-small * refactor(aquamarine): load the NPU driver via hardware.cpu.intel.npu Assisted-by: DeepSeek Harness (claude-opus-5-5)
153 lines
5.3 KiB
Nix
153 lines
5.3 KiB
Nix
{
|
|
disko,
|
|
myvars,
|
|
...
|
|
}:
|
|
#############################################################
|
|
#
|
|
# Aquamarine - headless AI inference server. Hardware, install and runbook:
|
|
# ./README.md.
|
|
#
|
|
#############################################################
|
|
let
|
|
hostName = "aquamarine"; # Define your hostname.
|
|
|
|
inherit (myvars.networking) proxyGateway proxyGateway6 nameservers;
|
|
inherit (myvars.networking.hostsAddr.${hostName}) ipv4;
|
|
ipv4WithMask = "${ipv4}/24";
|
|
in
|
|
{
|
|
imports = [
|
|
disko.nixosModules.default
|
|
../../modules/nixos/power.nix
|
|
# disks
|
|
./disko-fs.nix
|
|
|
|
# hardware
|
|
./hardware-configuration.nix
|
|
./hardware-intel-cpu.nix
|
|
./hardware-amd-gpu.nix
|
|
./hardware-intel-igpu.nix
|
|
|
|
./preservation.nix
|
|
./secureboot.nix
|
|
|
|
# services
|
|
./asr.nix
|
|
./idle-suspend.nix
|
|
];
|
|
|
|
# Bind the board's NCT6798D SuperIO, otherwise fan RPM and board temperatures
|
|
# are missing.
|
|
boot.kernelModules = [ "nct6775" ];
|
|
|
|
# Zram consumes physical memory for compression, which deadlocks when the
|
|
# model being loaded approaches the physical memory limit — exactly the
|
|
# workload this host exists for. Use the disk swapfile that disko creates at
|
|
# /swap instead, and keep zswap as a compressed cache in front of it so cold
|
|
# anonymous pages stay in RAM rather than hitting the SSD.
|
|
modules.zram.enable = false;
|
|
boot.zswap = {
|
|
enable = true;
|
|
compressor = "zstd";
|
|
# 10% of 96G; the module default 25% would compete with the page cache that
|
|
# holds the model weights being read in.
|
|
maxPoolPercent = 10;
|
|
};
|
|
|
|
# Local btrfs snapshots of @persistent (SSH host keys, /etc/secureboot, the
|
|
# NixOS state). Same layout as the other physical hosts; no off-host target.
|
|
modules.btrbk.enable = true;
|
|
modules.security.audit.enable = true;
|
|
|
|
# smartd autodetects devices and logs to the journal; the smartctl exporter
|
|
# (modules/nixos/base/monitoring.nix) is what feeds wear and media errors to
|
|
# VictoriaMetrics.
|
|
services.smartd.enable = true;
|
|
|
|
# The inference engine ships as an OCI image and runs under the agent
|
|
# profile's rootless Podman (modules/nixos/agent.nix), built from the `~/src`
|
|
# checkout that ./preservation.nix keeps.
|
|
|
|
# The daemons of the hosts that build here (modules/nixos/base/remote-builders.nix).
|
|
# Their host keys have no passphrase, so they only get the daemon protocol, as
|
|
# nix.sshServe does. `--store daemon` hands builds to the system daemon instead
|
|
# of running them inside this audited login session (modules/nixos/base/auditd.nix).
|
|
users.users.root.openssh.authorizedKeys.keys = map (
|
|
key: ''restrict,command="nix-daemon --stdio --store daemon" ${key}''
|
|
) myvars.remoteBuilderClientKeys;
|
|
|
|
# systemd-journal - cap disk usage
|
|
# https://www.freedesktop.org/software/systemd/man/latest/journald.conf.html
|
|
services.journald.settings.Journal = {
|
|
SystemMaxUse = "10G";
|
|
RuntimeMaxUse = "256M";
|
|
};
|
|
|
|
networking = {
|
|
inherit hostName;
|
|
|
|
# off: this host uses networkd (below).
|
|
networkmanager.enable = false;
|
|
useDHCP = false;
|
|
};
|
|
|
|
# A `boot.kernel.sysctl` that disabled IPv6 was removed on 2026-10-14: networkd
|
|
# re-enables it on the wired link for the `DHCP = "ipv6"`/`IPv6AcceptRA` settings
|
|
# below, so it never applied. The gateway now hands out fake-IP AAAA records too.
|
|
|
|
networking.useNetworkd = true;
|
|
systemd.network.enable = true;
|
|
|
|
# Rootless Podman's user units wait for the system network-online.target before
|
|
# starting containers. Nothing else starts that target on this networkd host
|
|
# since the LAN exporters moved to FreeBind sockets, so the user wait unit timed
|
|
# out after 90s and held llama-swap and magpie back on every boot.
|
|
systemd.targets.network-online.wantedBy = [ "multi-user.target" ];
|
|
|
|
# Predictable names follow the PCIe topology, so match the `en*` prefix instead of
|
|
# a name; one wired port, so one link.
|
|
# `Name=` is not a valid [Match] key in systemd.link; systemd 262 ignores
|
|
# the whole file with "Unknown key 'Name'". Match the kernel name instead.
|
|
systemd.network.links."40-wake-on-lan" = {
|
|
matchConfig.OriginalName = "en*";
|
|
linkConfig.WakeOnLan = "magic";
|
|
};
|
|
|
|
systemd.network.networks."10-lan" = {
|
|
matchConfig.Name = [ "en*" ];
|
|
networkConfig = {
|
|
Address = [
|
|
ipv4WithMask
|
|
];
|
|
# DNS goes to the proxy gateway, which resolves through the proxy;
|
|
# `nameservers` is the plain upstream-DNS alternative.
|
|
# DNS = nameservers;
|
|
DNS = [ proxyGateway ];
|
|
DHCP = "ipv6"; # enable DHCPv6 only, so we can get a GUA.
|
|
IPv6AcceptRA = true; # for Stateless IPv6 Autoconfiguration (SLAAC)
|
|
LinkLocalAddressing = "ipv6";
|
|
# The RTL8125BG flaps carrier on link re-training; without this networkd
|
|
# tears the static address and route down and the host drops off the LAN.
|
|
IgnoreCarrierLoss = "10s";
|
|
};
|
|
routes = [
|
|
{
|
|
Destination = "0.0.0.0/0";
|
|
Gateway = proxyGateway;
|
|
}
|
|
{
|
|
Destination = "::/0";
|
|
Gateway = proxyGateway6;
|
|
GatewayOnLink = true; # it's a gateway on local link.
|
|
}
|
|
];
|
|
linkConfig.RequiredForOnline = "routable";
|
|
};
|
|
|
|
# This value determines the NixOS release from which the default
|
|
# settings for stateful data (file locations, database versions) are taken.
|
|
# It is the release this host was installed on.
|
|
system.stateVersion = "26.11";
|
|
}
|