Day 5:硬體配置 — 拆解 `hardware-configuration.nix` 與伺服器硬體管理
拆解 hardware-configuration.nix 的結構與用途,說明 NixOS 如何以聲明式方式管理硬體驅動、檔案系統與開機引導等伺服器硬體配置。
Day 5:硬體配置 — 拆解 hardware-configuration.nix 與伺服器硬體管理
🗓 系列:NixOS 30 天學習之旅
📦 階段:第一階段 — 基礎與生存守則(Day 1 – Day 7)
🎯 階段核心目標:理解 Declarative 配置與不可變性
前言:我們的場景 — Headless NixOS Server
在開始之前,先釐清我們的使用環境:
- 遠端 NixOS server:純 CLI 環境,沒有顯示器、沒有桌面環境、沒有 GUI。所有操作都是透過 SSH 完成。
- 本地 MacBook:使用 nix-darwin 管理,擁有 GUI 與 CLI。
這代表我們今天要討論的硬體配置,全部聚焦在 headless server 的情境。GPU 渲染、音效輸出、觸控板、藍牙配對這些桌面專屬的設定,在我們的場景裡完全用不到。我們要關心的是磁碟、檔案系統、網路介面卡、虛擬化支援、RAID 這些伺服器的核心議題。
傳統的 Linux distribution 在安裝過程中,installer 會偵測你的硬體,然後把相關設定散落在 /etc/fstab、/etc/modprobe.d/、/etc/mkinitrd.conf 等各處。時間久了,你根本不記得哪些設定是 installer 自動產生的、哪些是你後來手動改的。
NixOS 做了一件很漂亮的事:把所有硬體相關的設定,集中在一份檔案裡 — hardware-configuration.nix。這份檔案在你安裝 NixOS 時自動產生,描述了磁碟分割、檔案系統掛載、需要載入的 kernel module 等等。跟 configuration.nix 拆開的原因很簡單:硬體設定是機器特定的,而 configuration.nix 是可攜的。
今天我們要拆解這份檔案的每個區塊,同時深入伺服器環境常見的硬體配置。
hardware-configuration.nix 的角色與生成方式
它住在哪?
安裝完 NixOS 之後,你的 /etc/nixos/ 目錄下通常會有兩個檔案:
/etc/nixos/
├── configuration.nix # 你的系統配置(手動編輯)
└── hardware-configuration.nix # 硬體配置(自動產生)
它怎麼來的?
在安裝 NixOS 的過程中,installer 會執行 nixos-generate-config 這個指令。它會掃描你的硬體環境,自動產生 hardware-configuration.nix。
而在 configuration.nix 中,你會看到它被 import 進來:
# /etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
imports =
[ ./hardware-configuration.nix ];
# ... 其他設定
}
這行 imports 就是把 hardware-configuration.nix 的內容「合併」到整份系統配置中。NixOS 的 module system 會幫你把兩份檔案的設定整合在一起,不需要你手動處理衝突。
為什麼要拆成兩個檔案?
這是一個非常實際的設計考量:
configuration.nix— 你的軟體配置、服務設定、使用者管理。這份可以放進 Git,帶到任何機器上使用。hardware-configuration.nix— 機器特定的硬體設定。每台機器自動產生,通常不會手動編輯。
這樣的分離讓你的配置具備真正的 portability。同一份 configuration.nix 可以用在不同的 server 上,只要各自搭配對應的 hardware-configuration.nix 就好。
檔案結構詳解
讓我們來看一份典型的伺服器 hardware-configuration.nix 長什麼樣子:
# /etc/nixos/hardware-configuration.nix
# 請勿手動編輯此檔案。
# 此檔案由 nixos-generate-config 自動產生,可隨時重新生成。
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix") ];
# ─── Kernel Modules ────────────────────────────────────
boot.initrd.availableKernelModules = [
"xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
# ─── File Systems ──────────────────────────────────────
fileSystems."/" = {
device = "/dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/XXXX-XXXX";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
# ─── Swap ──────────────────────────────────────────────
swapDevices =
[ { device = "/dev/disk/by-uuid/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"; } ];
# ─── Hardware Detection ────────────────────────────────
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode =
lib.mkDefault config.hardware.enableRedistributableFirmware;
}
看起來不少東西,但其實結構很清晰。我們一個區塊一個區塊來拆解。
1. imports 與 modulesPath
imports =
[ (modulesPath + "/installer/scan/not-detected.nix") ];
modulesPath 指向 NixOS module 的根目錄。not-detected.nix 這個 module 會自動啟用 hardware.enableRedistributableFirmware,載入常見硬體需要的 firmware(例如網路卡的 firmware)。
簡單說,這行的作用是:「幫我把那些自動偵測可能遺漏的 firmware 也一起載入」。
2. Kernel Modules(核心模組)
boot.initrd.availableKernelModules = [
"xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
這裡有四個相關的設定,分別負責不同的載入階段:
| 設定 | 用途 |
|---|---|
boot.initrd.availableKernelModules | 在 initrd(initial ramdisk)階段可以使用的模組。這些是開機過程中最早需要的 driver,例如磁碟控制器(nvme、ahci)和 USB 支援(xhci_pci) |
boot.initrd.kernelModules | 在 initrd 階段強制載入的模組。與上面不同的是,available 只是「讓模組可用」,但不一定會載入;這裡列出的會直接載入 |
boot.kernelModules | 系統完整開機後才載入的模組,例如 kvm-intel(虛擬化支援) |
boot.extraModulePackages | 額外的 kernel module 套件,用於 out-of-tree 的 driver(例如某些特殊的網卡 driver) |
💡 白話解釋 initrd:initrd(initial ramdisk)是 Linux 開機時的「迷你作業系統」。在真正的 root filesystem 掛載之前,kernel 需要先有足夠的 driver 才能讀取磁碟。initrd 就是裝載這些最關鍵 driver 的地方。
3. File Systems(檔案系統掛載)
fileSystems."/" = {
device = "/dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/XXXX-XXXX";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
這部分等同於傳統 Linux 的 /etc/fstab,定義了哪個 partition 掛載到哪個路徑。
幾個值得注意的細節:
device使用 UUID:而不是/dev/sda1這種路徑。UUID 是不變的識別碼,不會因為插了一顆新硬碟就導致裝置代號跑掉。在伺服器上這尤其重要 — 你可能有多顆磁碟,裝置代號容易亂掉。fsType:指定檔案系統類型。常見的有ext4、btrfs、xfs、vfat(EFI 分割通常用vfat)。options:掛載選項。fmask=0077和dmask=0077是安全性設定,確保 EFI 分割只有 root 能讀取。
4. Swap 設定
swapDevices =
[ { device = "/dev/disk/by-uuid/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"; } ];
如果你有獨立的 swap partition,就會出現這個區塊。如果你偏好使用 swap file 而非 swap partition,可以改成:
swapDevices = [
{
device = "/swapfile";
size = 8192; # 單位是 MiB
}
];
💡 伺服器的 swap 建議:在記憶體充足的 server 上,swap 通常設為 RAM 的 1–2 倍(上限通常 8–16 GB 就夠了)。如果你跑的是資料庫之類對 latency 敏感的服務,可以考慮把
vm.swappiness調低,減少 swap 使用。
5. Platform 與 CPU Microcode
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode =
lib.mkDefault config.hardware.enableRedistributableFirmware;
nixpkgs.hostPlatform:指定目標平台架構。常見值有x86_64-linux和aarch64-linux(ARM64)。hardware.cpu.intel.updateMicrocode:啟用 Intel CPU microcode 更新。如果你用的是 AMD CPU,這行會變成hardware.cpu.amd.updateMicrocode。Microcode 更新可以修補 CPU 層級的 bug 和安全漏洞,在伺服器上務必保持開啟。
💡 關於
lib.mkDefault:這個函式設定一個「預設值」,代表你可以在configuration.nix中用更高優先級的值覆蓋它。這就是為什麼hardware-configuration.nix大量使用mkDefault— 它提供合理的預設,但不阻止你自行調整。
伺服器磁碟與檔案系統配置
對 headless server 來說,磁碟與檔案系統的規劃是硬體配置中最核心的議題。不同的檔案系統各有優缺點,我們來看看在 NixOS 上怎麼設定。
EXT4 — 穩定可靠的萬用選擇
EXT4 是 Linux 上最成熟的檔案系統,效能穩定、工具齊全。如果你沒有特殊需求,EXT4 就是最安全的選擇。
fileSystems."/" = {
device = "/dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
fsType = "ext4";
options = [ "noatime" "discard" ];
};
noatime:不記錄每次檔案存取的時間戳記,減少磁碟寫入,提升效能。在伺服器上幾乎沒有理由不開。discard:如果底層是 SSD,會自動送出 TRIM 指令,幫助 SSD 維持效能。
Btrfs — 快照與彈性空間管理
Btrfs 的殺手級功能是 subvolume 和 snapshot。搭配 NixOS 的 rollback 哲學,是很自然的選擇。
fileSystems."/" = {
device = "/dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
fsType = "btrfs";
options = [ "subvol=@" "compress=zstd" "noatime" ];
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
fsType = "btrfs";
options = [ "subvol=@nix" "compress=zstd" "noatime" ];
};
fileSystems."/var/log" = {
device = "/dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
fsType = "btrfs";
options = [ "subvol=@log" "compress=zstd" "noatime" ];
};
Btrfs 在伺服器上的實用場景:
- 定期 snapshot:配合
services.btrbk或services.snapper做自動排程快照 - 透明壓縮:
compress=zstd可以節省磁碟空間,對 log 目錄特別有效 - 軟體 RAID:Btrfs 內建 RAID 0/1/10 支援(RAID 5/6 仍不建議用於 production)
# 啟用 Btrfs 自動 scrub(定期檢查資料完整性)
services.btrfs.autoScrub = {
enable = true;
interval = "weekly";
fileSystems = [ "/" ];
};
ZFS — 企業級資料保護
ZFS 是資料完整性要求最高的場景的首選,內建 checksum 驗證、snapshot、compression、RAID-Z 等功能。NixOS 對 ZFS 的支援非常好。
# configuration.nix
boot.supportedFilesystems = [ "zfs" ];
boot.zfs.forceImportRoot = false;
networking.hostId = "abcd1234"; # ZFS 需要一個固定的 hostId
# ZFS 自動 scrub
services.zfs.autoScrub = {
enable = true;
interval = "weekly";
};
# ZFS 自動 snapshot
services.zfs.autoSnapshot = {
enable = true;
frequent = 4; # 每 15 分鐘,保留最近 4 個
hourly = 24;
daily = 7;
weekly = 4;
monthly = 12;
};
ZFS pool 與 dataset 的建立通常在安裝階段用指令完成(zpool create、zfs create),然後在 hardware-configuration.nix 中宣告掛載:
fileSystems."/" = {
device = "zpool/root";
fsType = "zfs";
};
fileSystems."/home" = {
device = "zpool/home";
fsType = "zfs";
};
⚠️ ZFS 與 kernel 版本:ZFS module 不在 Linux kernel 的 mainline 中,是以 out-of-tree module 的方式維護的。當 NixOS 更新 kernel 版本時,偶爾會遇到 ZFS module 尚未跟上的情況。可以透過
boot.zfs.enableUnstable或鎖定 kernel 版本來處理。
檔案系統比較(伺服器角度)
| 特性 | EXT4 | Btrfs | ZFS |
|---|---|---|---|
| 穩定性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Snapshot | ❌ | ✅ | ✅ |
| 壓縮 | ❌ | ✅(zstd) | ✅(lz4/zstd) |
| 資料完整性驗證 | ❌ | ✅(checksum) | ✅(checksum) |
| 軟體 RAID | 需搭配 mdadm | 內建 RAID 0/1/10 | 內建 RAID-Z |
| 記憶體需求 | 低 | 中 | 高(建議 ≥ 8 GB) |
| NixOS 整合度 | 原生 | 原生 | 需額外設定 |
伺服器核心模組管理
在 headless server 上,kernel module 的管理重點跟桌面完全不同。我們不需要 GPU driver 或音效模組,但需要確保磁碟控制器、網路卡、虛擬化等模組正確載入。
常見的伺服器 kernel module
# configuration.nix
boot.kernelModules = [
"kvm-intel" # Intel VT-x 虛擬化(AMD 用 "kvm-amd")
"vfio" # IOMMU / PCI passthrough(進階虛擬化)
"vfio-pci"
"br_netfilter" # Bridge 網路的 netfilter 支援(Docker/K8s 常需要)
"ip_vs" # IPVS(負載平衡,K8s 常用)
"nf_conntrack" # 連線追蹤(防火牆基礎)
];
停用不需要的模組
在伺服器上,你可以明確停用不需要的模組來減少攻擊面:
# configuration.nix
boot.blacklistedKernelModules = [
"snd_pcm" # 音效
"snd_hda_intel"
"bluetooth" # 藍牙
"btusb"
"pcspkr" # PC 喇叭
];
Kernel 參數調校
伺服器常見的 kernel 參數調校:
# configuration.nix
boot.kernel.sysctl = {
# 網路效能調校
"net.core.somaxconn" = 65535;
"net.ipv4.tcp_max_syn_backlog" = 65535;
"net.core.netdev_max_backlog" = 65535;
# 開啟 IP forwarding(如果你需要跑 Docker 或當 router)
"net.ipv4.ip_forward" = 1;
# 減少 swap 使用傾向(適合記憶體充足的 server)
"vm.swappiness" = 10;
# 增加 file descriptor 上限
"fs.file-max" = 2097152;
# 增加 inotify watch 上限(大量檔案的服務需要)
"fs.inotify.max_user_watches" = 524288;
};
虛擬化支援:KVM 與 IOMMU
如果你的 server 要跑虛擬機器,KVM 是 Linux 上效能最好的虛擬化方案。NixOS 設定起來也非常直覺。
啟用 KVM
# configuration.nix
boot.kernelModules = [ "kvm-intel" ]; # AMD 用 "kvm-amd"
virtualisation.libvirtd = {
enable = true;
qemu = {
swtpm.enable = true; # TPM 模擬(某些 guest OS 需要)
ovmf.enable = true; # UEFI 開機支援
};
};
IOMMU 與 PCI Passthrough
如果你需要把實體 PCI 裝置(例如一張網卡)直接 passthrough 給虛擬機器使用:
# configuration.nix
# 在 BIOS/UEFI 啟用 VT-d(Intel)或 AMD-Vi 後
boot.kernelParams = [
"intel_iommu=on" # AMD 用 "amd_iommu=on"
"iommu=pt" # passthrough mode,減少對 host 的效能影響
];
boot.kernelModules = [ "vfio" "vfio_iommu_type1" "vfio_pci" "vfio_virqfd" ];
💡 使用情境:PCI passthrough 常見於將一張 10GbE 網卡直接交給虛擬機器使用,讓 VM 獲得接近裸機的網路效能。或是把 GPU 直通給需要硬體加速的 VM(不過在 headless server 上比較少見)。
網路介面卡設定
伺服器通常有多張網路卡,甚至需要做 bonding(聚合)或 VLAN 切割。這些都可以在 NixOS 中 declaratively 設定。
多網卡基本設定
# configuration.nix
networking = {
interfaces = {
eno1 = {
useDHCP = false;
ipv4.addresses = [{
address = "192.168.1.10";
prefixLength = 24;
}];
};
eno2 = {
useDHCP = false;
ipv4.addresses = [{
address = "10.0.0.10";
prefixLength = 24;
}];
};
};
defaultGateway = "192.168.1.1";
nameservers = [ "1.1.1.1" "8.8.8.8" ];
};
Network Bonding(網卡聚合)
多張網卡聚合可以提供更高的頻寬或容錯能力:
# configuration.nix
networking.bonds.bond0 = {
interfaces = [ "eno1" "eno2" ];
driverOptions = {
mode = "802.3ad"; # LACP 聚合(需要交換器支援)
miimon = "100"; # 每 100ms 檢查一次連線狀態
lacp_rate = "fast";
};
};
networking.interfaces.bond0 = {
useDHCP = false;
ipv4.addresses = [{
address = "192.168.1.10";
prefixLength = 24;
}];
};
常見的 bonding mode:
| Mode | 名稱 | 說明 |
|---|---|---|
balance-rr | Round Robin | 輪流使用各網卡,增加頻寬 |
active-backup | 主備模式 | 一張壞了自動切換,最簡單的容錯 |
802.3ad | LACP | 需要交換器支援,頻寬與容錯兼具 |
VLAN 設定
# configuration.nix
networking.vlans = {
vlan100 = {
id = 100;
interface = "eno1";
};
};
networking.interfaces.vlan100 = {
ipv4.addresses = [{
address = "10.100.0.10";
prefixLength = 24;
}];
};
網卡 Firmware
某些伺服器等級的網卡(如 Intel X710、Mellanox ConnectX 系列)需要額外的 firmware:
# configuration.nix
hardware.enableRedistributableFirmware = true; # 載入所有可散布的 firmware
# 或者更精確地只啟用網路相關的:
hardware.firmware = with pkgs; [
linux-firmware # 包含大多數網卡的 firmware
];
軟體 RAID(mdadm)
如果你的伺服器沒有硬體 RAID 卡,或者你偏好使用軟體 RAID(事實上在現代 SSD 環境下,軟體 RAID 的效能通常不輸硬體 RAID),NixOS 支援透過 mdadm 設定。
# configuration.nix
boot.swraid = {
enable = true;
mdadmConf = ''
MAILADDR admin@example.com
'';
};
mdadm array 通常在安裝階段建立,然後 nixos-generate-config 會自動偵測並寫入 hardware-configuration.nix。你也可以手動宣告:
# configuration.nix
boot.initrd.availableKernelModules = [ "raid1" "raid456" ];
fileSystems."/data" = {
device = "/dev/md/data";
fsType = "ext4";
options = [ "noatime" ];
};
💡 RAID 層級選擇:伺服器常用 RAID 1(mirror,適合系統碟)或 RAID 10(mirror + stripe,適合需要效能又要容錯的場景)。如果用 ZFS 或 Btrfs,它們內建了自己的 RAID 機制,不需要 mdadm。
Boot Loader 設定
伺服器的 boot loader 設定有一些特殊考量,尤其是遠端管理的需求。
GRUB 基本設定
# configuration.nix
boot.loader.grub = {
enable = true;
device = "/dev/sda"; # BIOS/Legacy boot
# 或者 UEFI 模式:
# efiSupport = true;
# device = "nodev";
};
# UEFI 模式
boot.loader.efi.canTouchEfiVariables = true;
systemd-boot(UEFI 環境推薦)
# configuration.nix
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
伺服器常用的 boot 設定
# configuration.nix
boot.loader.timeout = 3; # 縮短等待時間,加速開機
# 保留較多的歷史 generation(方便遠端 rollback)
boot.loader.systemd-boot.configurationLimit = 20;
# Serial console — 遠端 IPMI/BMC 管理必備
boot.kernelParams = [
"console=tty0"
"console=ttyS0,115200n8" # 同時輸出到 serial port
];
boot.loader.grub.extraConfig = ''
serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
terminal_input serial console
terminal_output serial console
'';
💡 Serial console 的重要性:在 headless server 上,如果 SSH 進不去,serial console 是你唯一的救命繩。透過 IPMI/BMC 的 SOL(Serial Over LAN)功能,你可以遠端存取 serial console,即使系統開機失敗也能看到輸出並進行除錯。
何時需要手動修改 hardware-configuration.nix?
官方的建議是:大多數情況下,你不需要手動修改它。但以下情境是例外:
1. 調整掛載選項
更好的做法是在 configuration.nix 中覆蓋設定,而不是直接改 hardware-configuration.nix:
# configuration.nix 中覆蓋掛載選項
fileSystems."/".options = [ "noatime" "discard" ];
2. 新增額外的磁碟掛載
當你接上一顆新的資料碟:
# configuration.nix
fileSystems."/data" = {
device = "/dev/disk/by-uuid/zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz";
fsType = "ext4";
options = [ "nofail" "noatime" ]; # nofail:開機時若此磁碟不存在,不會阻止系統啟動
};
3. 手動指定 kernel module
# configuration.nix
boot.kernelModules = [ "bonding" "8021q" ]; # bonding 和 VLAN 支援
原則整理
| 情境 | 建議做法 |
|---|---|
| 調整已有的掛載選項 | 在 configuration.nix 中用 fileSystems."/".options 覆蓋 |
| 新增額外的磁碟掛載 | 寫在 configuration.nix |
| 新增 kernel module | 寫在 configuration.nix |
| 更換硬碟後重新偵測 | 執行 nixos-generate-config 重新產生 |
直接修改 hardware-configuration.nix | 除非你非常清楚自己在做什麼,否則盡量避免 |
nixos-generate-config 指令
這個指令是 hardware-configuration.nix 的幕後功臣。了解它,你就能在需要時重新產生或更新硬體配置。
基本用法
# 重新偵測硬體,產生(或覆蓋)hardware-configuration.nix
sudo nixos-generate-config
執行後,它會:
- 掃描
/sys、/proc等虛擬檔案系統,偵測當前載入的 kernel module - 讀取已掛載的檔案系統資訊
- 偵測 CPU 類型與平台架構
- 將結果寫入
/etc/nixos/hardware-configuration.nix
⚠️ 注意:如果
/etc/nixos/configuration.nix已經存在,它不會被覆蓋。但hardware-configuration.nix會被覆蓋。所以你自訂的硬體設定請務必寫在configuration.nix中。
常見使用情境
| 情境 | 指令 |
|---|---|
| 安裝 NixOS 時初次產生 | nixos-generate-config --root /mnt |
| 更換硬碟或重新分割後更新 | sudo nixos-generate-config |
| 預覽偵測結果(不寫檔) | nixos-generate-config --show-hardware-config |
| 輸出到自訂目錄 | sudo nixos-generate-config --dir ~/my-config/ |
進階技巧:nixos-hardware
NixOS 社群維護了一個非常實用的專案:nixos-hardware。
這個 repository 收錄了大量硬體平台的最佳化配置。雖然大部分是筆電和桌面硬體,但也包含了伺服器相關的 profile,例如特定 CPU 世代的最佳化和常見伺服器主機板的設定。
# 以 Intel CPU 最佳化為例
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
<nixos-hardware/common/cpu/intel>
];
# ... 其他設定
}
目前收錄的平台包含各世代 Intel/AMD CPU 的最佳化、Raspberry Pi、各品牌筆電等。
💡 在你的硬體沒有自動偵測到某些功能時,先到
nixos-hardware找找看有沒有對應的 module,往往能省下大量的除錯時間。
桌面 NixOS 專屬設定(附錄)
以下設定僅適用於有桌面環境的 NixOS 機器,我們的 headless server 不需要,但為了知識完整性,簡要列出供參考。
展開桌面專屬設定
GPU 驅動:
# NVIDIA
hardware.nvidia.modesetting.enable = true;
services.xserver.videoDrivers = [ "nvidia" ];
# AMD(通常不需要額外設定,開源 driver 已內建)
hardware.graphics.enable = true;
音效(PipeWire):
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
pulse.enable = true;
};
藍牙 / 觸控板 / 電源管理:
hardware.bluetooth.enable = true;
services.libinput.enable = true;
services.tlp.enable = true; # 筆電省電
小結
今天我們從 headless server 的角度,深入拆解了 hardware-configuration.nix 並探討了伺服器環境的核心硬體配置:
| 概念 | 說明 |
|---|---|
| 檔案分離原則 | configuration.nix 管軟體配置(可攜),hardware-configuration.nix 管硬體設定(機器特定) |
| Kernel Modules | 分為 initrd 階段(開機必備 driver)和系統階段(功能性 module)兩個載入時機 |
| 檔案系統選擇 | EXT4(穩定萬用)、Btrfs(snapshot + 壓縮)、ZFS(企業級資料保護) |
| 虛擬化支援 | KVM + IOMMU 讓伺服器變身虛擬化平台 |
| 網路介面卡 | bonding 聚合、VLAN 切割、firmware 管理 |
| 軟體 RAID | mdadm 或直接使用 Btrfs/ZFS 內建的 RAID 機制 |
| Boot Loader | Serial console 設定是 headless server 的救命繩 |
| 自訂硬體設定 | 盡量寫在 configuration.nix 中覆蓋,避免直接修改 hardware-configuration.nix |
經過今天的學習,你應該已經能看懂 hardware-configuration.nix 的每一行在做什麼,也知道如何為你的伺服器配置適當的檔案系統、kernel module、網路介面和虛擬化支援。
明日預告
Day 6:網路與防火牆 — 我們會深入 NixOS 的 networking module,學習如何設定靜態 IP、DNS、防火牆規則,以及如何用 declarative 的方式管理伺服器的網路安全。讓你的 NixOS server 安全地上線,也守住該守的門。
我們明天見! 🚀
📚 延伸閱讀
- NixOS Manual — File Systems
- NixOS Manual — Kernel Modules
- NixOS Wiki — ZFS
- NixOS Wiki — Btrfs
- nixos-hardware — GitHub Repository
- NixOS Options Search — 搜尋所有可用的
hardware.*、boot.*設定選項