NixOS
NixOS 是一個基於 Nix 包管理器與構建系統的 Linux 發行版。它支持聲明式的系統級配置管理以及原子化升級和回滾,同時它仍支持命令式的包管理和用戶管理。在 NixOS 中,發行版的所有組件 — 包括系統內核、已安裝的軟件包和系統配置文件 — 均由 Nix 從被稱為 Nix 表達式 的純函數中構建。
由於 Nix 使用了二進制緩存機制,這便為面向二進制分發(如 Debian)和面向源碼分發(如 Gentoo)的方法提供了一種獨特的折中方案。預編譯的二進制程序被視作標準組件,在其無法獲取時,自助編譯的軟件包與模塊將被自動構建。
NixOS 穩定版本每年發布兩次(大約在五月底和十一月底)。NixOS 由 Eelco Dolstra 和 Armijn Hemel 創建,並於 2003 年首次發布。目前由 NixOS 基金會 管理下的社區開發與維護。
安裝
完整的安裝指南請參閱 NixOS 手冊的 Installation 章節。此維基還包含替代或補充指南,例如 桌面設備上的 NixOS。
大多數用戶通過 任一 ISO 鏡像 安裝 NixOS。每個支持架構均有 「graphical」(圖形化安裝)和 「minimal」(最小化安裝)兩種 ISO 變體;「graphical」 鏡像適用於計劃安裝桌面環境的用戶,而 「minimal」 鏡像適用於計劃將 NixOS 充當伺服器或期望更小 ISO 鏡像文件的用戶。ISO 鏡像為混合鏡像,可以刻錄到光盤介質或原封不動地複製到 USB 驅動器上並直接啟動。請參閱安裝指南以了解詳情。
除了 ISO 鏡像,下載頁面 還提供了多種安裝 NixOS 的替代方法。這些方法包括:
- OVA 格式的虛擬機(兼容 VirtualBox);
- Amazon EC2 AMIs;
此外,許多現有的 Linux 安裝可以通過 nixos-infect 或 nixos-in-place 轉換為 NixOS 安裝;這對於在不原生支持 NixOS 的主機提供商平台安裝 NixOS 十分有用。
系統架構
NixOS 對大多數 x86_64 設備和通用 ARM64 設備提供了開箱即用的支持。
32 位 x86 架構
對於 32 位 x86 架構(即 i686
)的支持正在減少。大多數包仍然可以編譯和運行,但它們的緩存可用性顯著降低[1]。32 位 x86 架構不再提供預構建的 ISO 鏡像文件,但其仍可手動構建。
64 位 x86 架構
大多數 x86_64
設備都能順利運行 NixOS。
32 位 ARM 架構
- Main article: NixOS on ARM
NixOS 不官方支持 ARM32 設備(例如 armv6
和 arm71
),不過對於其中部分設備,可能存在社區支持。
64 位 ARM 架構
- Main article: NixOS on ARM
只要設備支持通用 systemd 引導過程,NixOS 便可開箱即用。但是,使用專有引導加載程序的特定設備可能存在運行問題。
MIPS 架構
- Main article: NixOS on MIPS
NixOS 對於 MIPS 架構的支持有限, Nixpkgs 中可能存在部分對於此架構的支持。但並未有官方支持。
用法
聲明式配置
NixOS 的一個核心特徵便是其聲明式配置模型,其中整個系統狀態 — 包括已安裝的軟件包、系統服務和設置 — 均在配置文件中描述。主配置文件通常位於 /etc/nixos/configuration.nix
。
配置的更改通過使用 nixos-rebuild switch
原子化應用,從而確保可復現性並能回滾到之前狀態。大多數用戶使用版本控制系統來追蹤配置文件,以實現一致且可移植的系統設置。在其他系統中,這些缺陷通常是事後才通過 Puppet、Ansible 或 Chef 等配置管理解決方案來彌補,甚至完全無法彌補。這些工具將系統配置與預期的狀態描述進行協調。然而,其並未集成到作業系統的設計中,而只是簡單地疊加在作業系統之上。因此,當作業系統配置的某個方面未在預期狀態描述中指定時,其配置仍然可能會有所不同。
與傳統發行版通常將系統配置散布於各處需手動編輯的文件中不同,NixOS 將配置管理直接集成到作業系統中。這種方式消除了配置漂移,使得 NixOS 十分適合自動化、可復現的部署。
關於 NixOS 配置的更多細節和示例,請參閱 NixOS 系統配置。
命令式操作
儘管 NixOS 通常儘可能以聲明式方式進行配置,但在某些情況下,命令式操作仍然是必需的;這包括了用戶環境管理和頻道管理。
用戶環境
除了聲明式系統配置之外,NixOS 用戶還可以使用 Nix 的命令式 nix-env 指令在用戶層面安裝軟件包,而無需更改系統狀態。有關更多信息,請參閱 Nix 文檔的用戶環境部分。
頻道
在 Nix 生態系統 中,頻道(channels)是一種用於分發 Nix 軟件包 和 NixOS 模塊定義的機制。頻道代表一組經過精心維護、版本控制的軟件包定義和系統配置,通常對應於一個特定版本或最新的可用開發狀態。
在使用頻道時,您的系統或 用戶環境 會從一個 URL 拉取軟件包定義和選項,該 URL 指向 Nix 軟件包集合(Nixpkgs)及相關 NixOS 模塊的特定快照。
關於如何使用和配置 Nix 頻道的更多信息,請參閱 頻道分支。
內部機制
與傳統 Linux 發行版比較
Main Article: Nix vs. Linux Standard Base
NixOS 與其他 Linux 發行版的主要區別在於,NixOS 不遵循 Linux 標準規範(LSB) 的文件系統結構。在遵循 LSB 的系統中,軟件通常存儲在 /{,usr}/{bin,lib,share}
目錄下,而配置文件通常存儲在 /etc
。如果程序的可執行文件被放置在 LSB 的某個 /bin
目錄下,那麼它就可以在用戶環境中被訪問。當一個程序引用動態連結庫時,它將在 LSB 目錄(/lib
、/usr/lib
)中搜索所需的庫。
然而,在 NixOS 中,/lib
和 /usr/lib
目錄並不存在。相反,所有系統庫文件、可執行文件、內核、固件和配置文件都存放在 Nix store 中。/nix/store
下的文件和目錄均由構建數據的描述信息經哈希後命名。所有位於 Nix Store 的文件與目錄均不可變。
/bin
和 /usr/bin
幾乎不存在:它們分別只包含 /bin/sh
和 /usr/bin/env
,以提供與使用 shebang 行的現有腳本的最低兼容性。用戶級環境通過大量指向所需軟件包和輔助文件的符號連結來實現。
這些環境被稱作 Profiles,被存儲於 /nix/var/nix/profiles
,每個用戶擁有其獨有的 Profiles。
通過這種結構化的系統組織方式,NixOS 獲得了優於傳統 Linux 發行版的核心優勢,例如原子化操作和回滾支持。
Nix Store 的使用
新手的大多數困惑源於配置文件和所有已安裝軟件包均存儲於只讀的 /nix/store
目錄樹下這一事實。這實際上使得手動編輯系統配置變得不可能;所有配置更改必須通過編輯 /etc/nixos/configuration.nix
文件並運行 nixos-rebuild switch
後才可生效。NixOS 提供了模塊系統以供編輯所有需要的配置。用戶應在期望通過低層級的 NixOS 功能(如 activation scripts)手動添加文件或配置之前,首先使用配置選項搜索工具檢查所需選項是否已存在。
系統的純粹性(purity)使得系統配置的集中存儲成為可能,而無需編輯多個文件。此配置方式可以根據需要進行分發或版本控制。它還提供了確定性:如果您提供相同的輸入、相同版本的 Nixpkgs 和相同的 /etc/nixos/configuration.nix
文件,您將得到完全相同的系統狀態。
模塊
定義於 Nixpkgs 的 NixOS 模塊系統 提供了定製作業系統配置所需的方法。通常被用於啟用並定製如 Nginx 這樣的服務、啟用固件以及定製內核。
所有模塊配置通常都是通過向 /etc/nixos/configuration.nix
文件添加選項來完成。維基上的大多數示例都展示了如何使用此文件來配置作業系統。
NixOS 的模塊系統實現了一個類型系統,以允許對選項設置進行類型檢查。它還支持將多處定義的選項進行自動合併。這使得您可以將配置分散到多個文件中,而您在這些文件中設置的選項最終都會被合併在一起:
{
imports = [
./basic-webserver.nix
./blog.nix
];
}
{
services.nginx.enable = true;
services.nginx.virtualHosts."example.com" = {
root = "/var/www/example.com";
};
}
{
services.nginx.virtualHosts."blog.example.com" = {
root = "/var/www/blog.example.com";
};
}
請參閱 NixOS 手冊的模塊部分 以獲取更多詳細信息。
世代
每當使用 nixos-rebuild switch
命令重構系統狀態時,都將創建一個新的世代(generation)。您可以隨時回滾到上一個世代,這在配置更改(或系統更新)被證明是有害時非常有用。
您可以通過以下命令回滾:
$ nix-env --rollback # 回滚用户环境
$ nixos-rebuild switch --rollback # 回滚系统环境
NixOS 還會在引導加載程序菜單中放置前幾代系統的條目,因此,作為最後的手段,您可以通過重啟來恢復到之前的配置。將當前啟動的版本設置為默認運行:
$ /run/current-system/bin/switch-to-configuration boot
由於 NixOS 會保留前幾代系統狀態以供回滾,因此更新後不會立即從系統中刪除舊軟件包版本。您可以手動刪除舊版本:
# 删除早于 30 天前的世代
$ nix-collect-garbage --delete-older-than 30d
# 删除之前的所有世代 - 运行此命令后您将无法回滚
$ nix-collect-garbage -d
List generations:
# 以 root 用户身份
$ nix-env --list-generations --profile /nix/var/nix/profiles/system
Switch generations:
# 以 root 用户身份切换至 204 世代
$ nix-env --profile /nix/var/nix/profiles/system --switch-generation 204
delete broken generation(s):
# 以 root 用户身份删除损坏的 205 和 206 世代
$ nix-env --profile /nix/var/nix/profiles/system --delete-generations 205 206
您可以通過設置 /etc/nixos/configuration.nix
中的 nix.gc 選項來配置自動垃圾回收。這是推薦操作,因為它可以降低 Nix Store 的大小。
另見
- NixOS 模塊 - 一個用於模塊化 Nix 表達式的庫,為 NixOS 的聲明式配置 提供支持。
- NixOS VM 測試 - 一個基於 Nixpkgs、NixOS、QEMU 和 Perl 用於創建可復現基礎設施測試的庫。
- NixOS & Flakes Book (Ryan4yin, 2023) - 🛠️ ❤️ 一本非官方的 NixOS & Flakes 新手入門書籍。