Extract the reusable core module list into modules/default.nix (single source of truth) and expose it as nixosModules.omnixy / .default. configuration.nix now imports ./modules instead of listing each module, so this repo's hosts and external consumers share one definition. Theme stays a settings.theme-driven import inside the aggregate. Packs, dev-env, sops and home-manager remain injected by mkSystem. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
221 lines
6.3 KiB
Nix
221 lines
6.3 KiB
Nix
# 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 = [
|
||
# Omnixient core module aggregate (modules/default.nix) — the same set
|
||
# exposed as nixosModules.omni for external consumers, so there's a
|
||
# single source of truth for the core module list. The active theme
|
||
# is selected inside it from settings.theme.
|
||
#
|
||
# hardware-configuration.nix is imported per-host from
|
||
# hosts/<name>/default.nix (machine-specific), not here.
|
||
./modules
|
||
];
|
||
|
||
# --- 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;
|
||
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" ];
|
||
};
|
||
}
|