feat: NixOS system entry point (configuration.nix)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-06-28 06:48:38 +02:00
commit 8d2a0357c1

245
configuration.nix Normal file
View file

@ -0,0 +1,245 @@
# Omnixient NixOS Configuration
# This is the main entry point — keep it thin.
# System-level config lives in modules/; this file is for per-host settings.
{
config,
pkgs,
lib,
settings,
...
}:
let
currentTheme = settings.theme;
in
{
imports = [
# NOTE: hardware-configuration.nix is imported per-host from
# hosts/<name>/default.nix (it's machine-specific), not here.
# Omnixient modules
./modules/lib.nix
./modules/core.nix
./modules/colors.nix
./modules/boot.nix
./modules/security.nix
./modules/secrets.nix
./modules/fastfetch.nix
./modules/walker.nix
./modules/scripts.nix
./modules/menus.nix
./modules/desktop/hyprland.nix
./modules/packages.nix
./modules/development.nix
./modules/mcp.nix
./modules/themes/${currentTheme}.nix
./modules/users.nix
./modules/services.nix
./modules/hardware
];
# --- Per-host settings (edit these) ---
nixpkgs.config.allowUnfree = true;
# Electron 39 is EOL upstream but still bundled by signal-desktop /
# element-desktop / obsidian in current nixpkgs. Allow until those
# packages move to a supported electron.
nixpkgs.config.permittedInsecurePackages = [ "electron-39.8.10" ];
nix = {
settings = {
experimental-features = [
"nix-command"
"flakes"
];
auto-optimise-store = true;
# Bound build concurrency so a big rebuild (lnbits/webapp/lamassu)
# can't allocate past available RAM and trigger the OOM-killer
# against the desktop session. 4×4 keeps headroom on a 16-core box.
max-jobs = 4;
cores = 4;
substituters = [
"https://cache.nixos.org"
"https://nix-community.cachix.org"
"https://hyprland.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
];
};
# Run the daemon (and therefore all build workers it spawns) at idle
# CPU + IO priority, so interactive apps always preempt nix.
daemonCPUSchedPolicy = "idle";
daemonIOSchedClass = "idle";
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
};
# Hard memory ceiling on the nix-daemon cgroup: MemoryHigh applies
# backpressure (slows builds before OOM); MemoryMax kills the build
# cgroup before the kernel reaps Chromium/waybar/walker.
systemd.services.nix-daemon.serviceConfig = {
MemoryHigh = "16G";
MemoryMax = "20G";
};
# Compressed swap-in-RAM. With no disk swap the kernel reaches for the
# OOM-killer the moment a build spikes; zram gives it a release valve
# for cold pages without thrashing a disk.
zramSwap = {
enable = true;
memoryPercent = 50;
algorithm = "zstd";
};
networking = {
hostName = settings.hostName;
# iwd-only wifi (impala handles WPA2-Enterprise natively since v0.5.0)
networkmanager.enable = false;
wireless.iwd = {
enable = true;
settings = {
General.EnableNetworkConfiguration = true;
Network.EnableIPv6 = true;
};
};
firewall = {
enable = true;
allowedTCPPorts = [
22
80
443
3000
8080
5173 # webapp hub (Vite dev)
5180 # libra
5181 # activities (sortir)
5182 # wallet
5183 # chat
5184 # forum
5185 # market
5186 # tasks
5187 # restaurant
5001 # LNbits
3333 # Fava (docker maps :5000→:3333; also the deploy default)
6033 # pict-rs
6173 # chateau-du-faune dev
];
};
};
time.timeZone = settings.timeZone;
i18n = {
defaultLocale = "en_US.UTF-8";
extraLocaleSettings = {
LC_ADDRESS = "en_US.UTF-8";
LC_IDENTIFICATION = "en_US.UTF-8";
LC_MEASUREMENT = "en_US.UTF-8";
LC_MONETARY = "en_US.UTF-8";
LC_NAME = "en_US.UTF-8";
LC_NUMERIC = "en_US.UTF-8";
LC_PAPER = "en_US.UTF-8";
LC_TELEPHONE = "en_US.UTF-8";
LC_TIME = "en_US.UTF-8";
};
};
system.stateVersion = settings.stateVersion;
# VM testing settings (ignored on real hardware)
virtualisation.vmVariant = {
virtualisation = {
memorySize = 4096;
cores = 2;
qemu.options = [
"-vga virtio"
];
# Forward host port 2222 -> guest port 22 so we can ssh in
# from the host (`ssh -p 2222 user@localhost`) instead of
# typing into the QEMU window. The host_port=2222 avoids
# needing root for a low port and dodges any local sshd.
forwardPorts = [
{
from = "host";
host.port = 2222;
guest.port = 22;
}
];
};
# Disable services that don't work in VMs
services.smartd.enable = lib.mkForce false;
services.power-profiles-daemon.enable = lib.mkForce false;
services.thermald.enable = lib.mkForce false;
# Use software rendering as fallback for Hyprland
environment.variables.WLR_RENDERER = "pixman";
# VM-only: re-enable password ssh auth so we can ssh in from
# the host to test without injecting keys. Production has these
# disabled in modules/services.nix; this override only applies
# to the vmVariant so it never reaches a real machine.
services.openssh.settings.PasswordAuthentication = lib.mkForce true;
services.openssh.settings.KbdInteractiveAuthentication = lib.mkForce true;
};
# --- Omnixient settings ---
hardware.bluetooth.enhanced.enable = true;
# udev rules for ZSA keyboards (Moonlander) — needed to flash firmware
# and use Oryx live-training. Flash with keymapp (see home.packages).
hardware.keyboard.zsa.enable = true;
omni = {
enable = true;
desktop.enable = true;
mcp.enable = true;
mcp.servers.lnbits = {
enable = true;
url = "http://localhost:5001";
};
mcp.servers.nextcloud = {
enable = true;
url = "https://cloud.ariege.io";
username = "pat";
};
user = settings.user;
theme = currentTheme;
displayManager = "tuigreet";
preset = "developer";
features = {
office = true;
communication = true;
};
security = {
enable = true;
fingerprint = {
enable = false;
autoDetect = true;
};
fido2 = {
enable = false;
autoDetect = true;
};
systemHardening = {
enable = true;
faillock = {
enable = true;
denyAttempts = 10;
unlockTime = 120;
};
};
};
# colorScheme = inputs.nix-colors.colorSchemes.tokyo-night-dark;
# wallpaper = /path/to/your/wallpaper.jpg;
# features = { coding = true; containers = true; };
# packages.exclude = [ "discord" "spotify" ];
};
}