nix-config/configuration.nix
2026-04-07 11:07:52 -07:00

310 lines
8.4 KiB
HolyC

{ config, pkgs, ... }:
{
imports = [ ./hardware-configuration.nix ];
boot.loader.systemd-boot.enable = true;
boot.loader.systemd-boot.configurationLimit = 3;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.timeout = 1;
boot.loader.systemd-boot.consoleMode = "max";
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
networking.hostName = "framework";
# Ensure current wireless firmware is available.
hardware.enableRedistributableFirmware = true;
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
Experimental = true; # Show battery charge of Bluetooth devices
};
};
};
networking.networkmanager.enable = true;
networking.networkmanager.settings = {
connection = {
"wifi.powersave" = 2;
};
device = {
"wifi.scan-rand-mac-address" = false;
};
};
services.resolved.enable = true;
networking.firewall.enable = true;
# Required for Tailscale
networking.firewall.checkReversePath = "loose";
networking.firewall.interfaces."tailscale0".allowedTCPPorts = [ 4096 ];
services.tailscale = {
enable = true;
};
systemd.services.tailscale-set-operator = {
description = "Set Tailscale operator user";
after = [ "tailscaled.service" ];
requires = [ "tailscaled.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot";
path = [ pkgs.tailscale ];
script = ''
tailscale set --operator=jet
'';
};
time.timeZone = "America/Los_Angeles";
i18n.defaultLocale = "en_US.UTF-8";
# Framework Laptop 13 AMD AI 300 Series specific configurations
# Enable AMD GPU support and power management
hardware.graphics = {
enable = true;
enable32Bit = true;
};
# Enable keyd for key remapping
services.keyd = {
enable = true;
keyboards = {
default = {
ids = [ "*" ]; # Apply to all keyboards
settings = {
main = {
capslock = "esc";
esc = "capslock";
leftalt = "leftcontrol";
leftcontrol = "leftalt";
mute = "mute"; # Key 1: mute
volumedown = "playpause"; # Key 2: play/pause
volumeup = "volumedown"; # Key 3: vol down
previoussong = "volumeup"; # Key 4: vol up
playpause = "command(touch /tmp/keyd-f5-test)"; # Key 5: lock screen (testing)
nextsong = "noop"; # Key 6: disabled
brightnessdown = "noop"; # Key 7: disabled
brightnessup = "noop"; # Key 8: disabled
# Key 9: display toggle (leftmeta+p) - disabled below
rfkill = "brightnessdown"; # Key 10: brightness down
sysrq = "brightnessup"; # Key 11: brightness up
media = "sysrq"; # Key 12: screenshot
};
};
};
frameworkRadio = {
ids = [ "32ac:0006" ];
settings = {
main = {
brightnessdown = "noop"; # Key 7: disabled
brightnessup = "noop"; # Key 8: disabled
rfkill = "brightnessdown"; # Key 10: brightness down
};
};
};
};
};
# Prevent trackpad interference with keyd
environment.etc."libinput/local-overrides.quirks".text = ''
[Serial Keyboards]
MatchUdevType=keyboard
MatchName=keyd virtual keyboard
AttrKeyboardIntegration=internal
'';
# Codex currently probes the conventional FHS bubblewrap path.
systemd.tmpfiles.rules = [
"L+ /usr/bin/bwrap - - - - ${pkgs.bubblewrap}/bin/bwrap"
];
# Set Kitty as default terminal
xdg.terminal-exec = {
enable = true;
settings = {
default = [ "kitty.desktop" ];
};
};
services.flatpak.enable = true;
virtualisation.docker.enable = true;
services.displayManager.gdm.enable = true;
services.desktopManager.gnome.enable = true;
services.gnome.sushi.enable = true;
# Remove default GNOME apps (keeping loupe and file-roller)
environment.gnome.excludePackages = with pkgs; [
epiphany # GNOME Web
gnome-calculator
gnome-calendar
gnome-characters
gnome-clocks
gnome-connections
gnome-console
gnome-contacts
gnome-maps
gnome-music
gnome-weather
snapshot # Camera
gnome-text-editor
simple-scan
totem # Videos (have VLC)
yelp # Help docs
evince # PDF viewer (using Zen Browser)
geary # Email
gnome-tour
gnome-font-viewer # Have font-manager
];
services.printing.enable = true;
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
users.users.jet = {
isNormalUser = true;
description = "Jet";
extraGroups = [
"networkmanager"
"wheel"
"video"
"render"
"docker"
];
};
nixpkgs.config.allowUnfree = true;
nix.settings = {
experimental-features = [
"nix-command"
"flakes"
];
trusted-users = [
"root"
"jet"
];
max-jobs = "auto";
cores = 0;
build-users-group = "nixbld";
};
nix.gc = {
automatic = true;
dates = "daily";
options = "--delete-older-than 7d";
};
nix.optimise.automatic = true;
# Framework-specific services
# Enable fwupd for BIOS updates (distributed through LVFS)
services.fwupd.enable = true;
# Enable periodic TRIM for NVMe/SSD health
services.fstrim.enable = true;
services.irqbalance.enable = true;
services.earlyoom.enable = true;
# Power management for laptop
services.logind = {
settings = {
Login = {
HandleLidSwitch = "suspend";
HandleLidSwitchExternalPower = "suspend";
HandleLidSwitchDocked = "ignore";
HandlePowerKey = "suspend";
};
};
};
# Enable auto-cpufreq for intelligent power management (replaces TLP)
services.auto-cpufreq.enable = true;
services.auto-cpufreq.settings = {
battery = {
governor = "powersave";
turbo = "never";
};
charger = {
governor = "performance";
turbo = "auto";
};
};
# Disable power-profiles-daemon (conflicts with auto-cpufreq)
services.power-profiles-daemon.enable = false;
# Enable power management (governor managed dynamically by auto-cpufreq)
powerManagement.enable = true;
# v4l2loopback for OBS Virtual Camera
boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
boot.kernelModules = [ "v4l2loopback" ];
boot.extraModprobeConfig = ''
options cfg80211 ieee80211_regdom=US
options v4l2loopback devices=1 video_nr=1 card_label="OBS Virtual Camera" exclusive_caps=1
'';
# RAM optimizations for 96GB system
boot.kernel.sysctl = {
"vm.vfs_cache_pressure" = 50; # Keep more filesystem cache in RAM
"vm.dirty_ratio" = 15; # Write to disk when 15% of RAM is dirty
"vm.dirty_background_ratio" = 5; # Start writing when 5% dirty
"kernel.nmi_watchdog" = 0;
"net.core.default_qdisc" = "fq";
"net.ipv4.tcp_congestion_control" = "bbr";
};
# Use RAM disk (tmpfs) for temporary files - much faster than disk
fileSystems."/tmp" = {
device = "tmpfs";
fsType = "tmpfs";
options = [
"size=32G" # Use up to 32GB RAM for /tmp (adjust as needed)
"mode=1777"
"nosuid"
"nodev"
];
};
environment.systemPackages = with pkgs; [
bubblewrap
docker
docker-compose
flatpak
wget
nh
];
programs.steam.enable = true;
programs.nix-index-database.comma.enable = true;
# https://wiki.nixos.org/wiki/Appimage
programs.appimage = {
enable = true;
binfmt = true;
};
# GameCube adapter udev rules for Slippi/Dolphin
# Disable USB autosuspend for Framework's problematic devices (fingerprint reader, USB-C hub)
services.udev.extraRules = ''
# GameCube adapter USB device (vendor ID 057e, product ID 0337)
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="0337", MODE="0666"
# GameCube adapter HID device (needed for Dolphin to access controllers)
KERNEL=="hidraw*", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="0337", MODE="0666", GROUP="input"
# Disable autosuspend for Framework fingerprint reader
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="27a6", ATTR{power/autosuspend}="-1"
# Disable autosuspend for Framework USB-C hub controllers
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{power/autosuspend}="-1"
'';
system.stateVersion = "25.05";
}