Switching to GNU Guix: A Beginner's Perspective

Switching to GNU Guix: A Beginner’s Perspective

转向 GNU Guix:初学者的视角

2026-09-13 #linux #guix

Background: A Decade of Arch Linux

背景:Arch Linux 的十年

Arch Linux was my distribution of choice for more than a decade. With its rolling-release model, minimal base, and the invaluable ArchWiki, it felt like the final distribution I would ever need. 在过去十多年里,Arch Linux 一直是我的首选发行版。凭借其滚动更新模式、极简的基础系统以及极其宝贵的 ArchWiki,我曾一度认为这就是我所需要的终极发行版。

My primary Linux machine is a dedicated home server, handling services like Home Assistant, local DNS, background jobs, and developer sandboxes. For a server running 24/7, long-term stability and maintainability are critical. Over years of incremental tweaks, configuration entropy inevitably crept in. System state became scattered across /etc, /usr, systemd service units, and package manager transactions. Whenever I made changes, I had to keep diligent notes about which files were edited, when, and why. 我的主力 Linux 机器是一台专门的家用服务器,负责处理 Home Assistant、本地 DNS、后台任务和开发沙箱等服务。对于一台 24/7 运行的服务器来说,长期的稳定性和可维护性至关重要。经过多年的增量调整,配置熵不可避免地增加了。系统状态变得分散在 /etc/usr、systemd 服务单元以及包管理器的事务记录中。每当我进行更改时,都必须勤奋地记录下修改了哪些文件、何时修改以及原因。

Recent events, such as the Arch Linux AUR security incidents (which I touched upon in my previous post on Caddy) and developments around Omarchy, prompted me to re-evaluate my setup. I wanted an operating system that was declarative, reproducible, and manageable entirely in code. 最近发生的一些事件,例如 Arch Linux AUR 的安全事故(我在之前关于 Caddy 的文章中提到过)以及围绕 Omarchy 的进展,促使我重新评估了我的系统配置。我想要一个声明式、可复现且能完全通过代码管理的操作系统。

NixOS vs GNU Guix

NixOS 与 GNU Guix

Declarative operating systems offer a compelling answer to configuration drift. When researching options, NixOS was actually my first choice. 声明式操作系统为解决“配置漂移”问题提供了一个令人信服的方案。在研究各种选项时,NixOS 实际上是我的首选。

Testing NixOS in a VM: I spun up a NixOS virtual machine and spent time experimenting by replicating the core services I was running on Arch to ensure everything worked properly. It worked really well: declaring the entire system state in a configuration file with instant rollback capabilities felt like the right model for operating systems. 在虚拟机中测试 NixOS:我启动了一个 NixOS 虚拟机,并花时间通过复制我在 Arch 上运行的核心服务来进行实验,以确保一切正常工作。它的表现非常好:在配置文件中声明整个系统状态,并具备即时回滚功能,这感觉像是操作系统的正确模型。

However, as I explored deeper, documentation in NixOS became a major source of friction. The newer nix command line interface and Flakes remain experimental features that are not yet enabled by default or standardized across the ecosystem, leading to divergent documentation and tutorials. Finding guidance was further complicated by the presence of two separate wikis. 然而,随着探索的深入,NixOS 的文档成为了主要的阻碍。较新的 nix 命令行界面和 Flakes 仍然是实验性功能,尚未默认启用或在整个生态系统中标准化,这导致了文档和教程的分歧。两个独立的 Wiki 存在,使得寻找指导变得更加复杂。

Discovering GNU Guix

发现 GNU Guix

While learning more about NixOS, I came across David Wilson’s video from System Crafters: Why I Choose Guix Over NixOS. As a fan of David Wilson, his arguments resonated strongly with me. Shortly after, I also watched YouTux’s video, One of the Best Linux Distros Isn’t Even in DistroWatch’s Top 100. 在深入了解 NixOS 的同时,我偶然发现了 System Crafters 频道 David Wilson 的视频:《为什么我选择 Guix 而不是 NixOS》。作为 David Wilson 的粉丝,他的观点引起了我的强烈共鸣。不久之后,我还观看了 YouTux 的视频:《最好的 Linux 发行版之一甚至没进 DistroWatch 前 100 名》。

These videos prompted me to research GNU Guix and try it inside a VM. 这些视频促使我研究 GNU Guix 并在虚拟机中进行了尝试。

GNU Guix shares the same core architectural foundation as NixOS (functional package management, declarative configuration, and atomic rollbacks), but its design choices felt much more cohesive: GNU Guix 与 NixOS 共享相同的核心架构基础(函数式包管理、声明式配置和原子回滚),但其设计选择感觉更加统一:

  • Language (GNU Guile Scheme vs Nix DSL): Nix uses its own bespoke domain-specific language. Guix configurations are written entirely in GNU Guile, a general-purpose Scheme (Lisp). As an Emacs user accustomed to Emacs Lisp, Scheme felt familiar and expressive. Rather than learning a specialized configuration syntax, I could leverage a real programming language with first-class functions, macros, and modules. 语言(GNU Guile Scheme vs Nix DSL): Nix 使用其定制的领域特定语言。而 Guix 的配置完全使用 GNU Guile 编写,这是一种通用的 Scheme (Lisp) 语言。作为一名习惯了 Emacs Lisp 的 Emacs 用户,Scheme 感觉既熟悉又富有表现力。我无需学习专门的配置语法,而是可以利用一门真正的编程语言,使用其一等函数、宏和模块。

  • Init System (GNU Shepherd vs systemd): NixOS builds on systemd, while Guix System uses GNU Shepherd as its service manager. In Guix, Shepherd services are also defined in Guile Scheme. Everything from package recipes to system daemons to PID 1 shares a unified language and data model. 初始化系统(GNU Shepherd vs systemd): NixOS 基于 systemd,而 Guix System 使用 GNU Shepherd 作为其服务管理器。在 Guix 中,Shepherd 服务同样使用 Guile Scheme 定义。从软件包配方到系统守护进程再到 PID 1,一切都共享统一的语言和数据模型。

  • Documentation: Guix’s documentation is remarkably cohesive. Even though some community tutorials can be dated, the official GNU Guix reference manual is consistent, comprehensive, and avoids the fragmented wiki landscape of Nix. 文档: Guix 的文档非常统一。尽管一些社区教程可能已经过时,但官方的 GNU Guix 参考手册始终保持一致且全面,避免了 Nix 那种碎片化的 Wiki 现状。

  • Philosophy (GNU Libre Standards vs Pragmatism): NixOS takes a pragmatic stance, offering toggles for proprietary software and unfree drivers. GNU Guix strictly adheres to the GNU Free System Distribution Guidelines, shipping the Linux-libre kernel and free software exclusively by default. 哲学(GNU 自由标准 vs 实用主义): NixOS 采取实用主义立场,为专有软件和非自由驱动程序提供了开关。而 GNU Guix 严格遵守 GNU 自由系统发行版指南,默认仅提供 Linux-libre 内核和自由软件。

This philosophical strictness has its trade-offs. For my home server, which connects to the network through an Ethernet cable, proprietary Wi-Fi firmware is unnecessary, and the Linux-libre kernel works out of the box. The purity and auditability feel satisfying, though it does mean dealing with a more curated package catalog. Also, a personal server is personal, I can have my own opinion – I prefer purity over pragmatism, but I think GNU Guix is pragmatic enough for my use cases. 这种哲学上的严格性是有代价的。对于通过以太网线连接网络的家用服务器来说,专有的 Wi-Fi 固件是不必要的,Linux-libre 内核可以直接开箱即用。这种纯粹性和可审计性令人满意,尽管这意味着需要面对一个经过更严格筛选的软件包目录。此外,个人服务器就是个人的,我可以有自己的观点——我更喜欢纯粹而非实用主义,但我认为 GNU Guix 对我的使用场景来说已经足够实用。

Between the familiarity of Scheme, the unified architecture, and its close kinship with Emacs, I decided to make the switch to GNU Guix. 考虑到 Scheme 的熟悉感、统一的架构以及它与 Emacs 的紧密联系,我决定转向 GNU Guix。

What I Like as a Beginner

作为初学者,我喜欢什么

Unified Declarative Config in Git Git 中的统一声明式配置

With GNU Guix, the entire operating system configuration lives in code and is tracked in Git. I manage both Guix System (operating system declarations, system daemons, kernel parameters) and Guix Home (user packages, shell environments, and dotfiles) within a single literate Org-mode file (guix.org) using Org Babel. 在 GNU Guix 中,整个操作系统的配置都以代码形式存在,并由 Git 进行跟踪。我通过 Org Babel 在一个单一的文学编程 Org-mode 文件 (guix.org) 中管理 Guix System(操作系统声明、系统守护进程、内核参数)和 Guix Home(用户软件包、Shell 环境和点文件)。

At any point, I can see exactly which packages are installed and which services are active directly from the codebase. In the past, I hesitated to invest in complex system configurations because maintaining them across updates was fragile. With Guix, configuring the operating system feels as manageable and predictable as tweaking my Emacs configuration. 在任何时候,我都可以直接从代码库中准确地看到安装了哪些软件包以及哪些服务处于活动状态。过去,我不敢投入精力进行复杂的系统配置,因为在更新过程中维护它们非常脆弱。有了 Guix,配置操作系统感觉就像调整我的 Emacs 配置一样,既可管理又可预测。

Flexible Guile Configuration 灵活的 Guile 配置

Guix configurations are written in a full-featured programming language rather than static YAML or JSON. This gives immense flexibility when composing services. Guix 的配置是使用功能齐全的编程语言编写的,而不是静态的 YAML 或 JSON。这在组合服务时提供了巨大的灵活性。

Using Guix’s service extension mechanism with simple-service, you can extend existing system services cleanly without modifying base declarations. In a traditional distribution, deploying a service forces you to fragment its configuration across completely separate subsystems: a systemd unit in /etc/systemd/system/, and reverse proxy blocks in /etc/nginx/conf.d/. 使用 Guix 的 simple-service 服务扩展机制,你可以干净地扩展现有的系统服务,而无需修改基础声明。在传统发行版中,部署服务会迫使你将其配置分散在完全独立的子系统中:/etc/systemd/system/ 中的 systemd 单元,以及 /etc/nginx/conf.d/ 中的反向代理块。

With Guix, you can co-locate a service and its surrounding infrastructure side by side in the exact same configuration block: 而在 Guix 中,你可以将服务及其周围的基础设施并排放在同一个配置块中:

;; Home Assistant container (simple-service 'home-assistant-container oci-service-type (oci-extension (containers (list (oci-container-configuration (provision "home-assistant") (image "ghcr.io/home-assistant/home-as