强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

GNU Guix 函数式包管理教程 / 第十二章 最佳实践

第十二章:最佳实践

12.1 日常工作流

12.1.1 推荐的日常工作流

日常操作流程:
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   guix pull  │────►│ guix upgrade │────►│   验证系统    │
│  更新通道     │     │  升级包       │     │  确认正常     │
└──────────────┘     └──────────────┘     └──────────────┘
                                                   │
                                          ┌────────┴────────┐
                                          │                 │
                                    正常运行           出现问题
                                          │                 │
                                    ┌─────┘           ┌─────┘
                                    ▼                 ▼
                              Git commit       guix roll-back
                              记录配置         回滚到上一版本

12.1.2 系统管理日常检查清单

频率 操作 命令
每日 检查系统状态 sudo herd status
每周 更新通道 guix pull
每周 升级系统/包 sudo guix system reconfigure /etc/config.scm
每周 检查安全公告 订阅 guix-security 邮件列表
每月 清理旧 generation sudo guix system delete-generations 30d
每月 垃圾回收 sudo guix gc -C 10G
每月 备份配置 git push

12.1.3 更新操作的标准流程

# 步骤 1:备份当前状态
guix describe --format=channels > channels-backup-$(date +%Y%m%d).scm
sudo guix system describe /etc/system-backup-$(date +%Y%m%d).scm

# 步骤 2:更新通道
guix pull

# 步骤 3:测试升级(不设为默认启动项)
sudo guix system reconfigure /etc/config.scm --no-bootloader

# 步骤 4:验证系统正常
# - 检查所有服务是否运行
sudo herd status
# - 检查网络
ping -c 3 gnu.org
# - 检查关键应用

# 步骤 5:确认无问题后提交配置
cd /etc/guix-config && git add -A && git commit -m "chore: system upgrade"

# 步骤 6:如果出现问题,回滚
sudo guix system roll-back

12.2 配置管理最佳实践

12.2.1 版本控制一切

# 项目结构
~/.config/guix/
├── channels.scm          # 通道配置(版本锁定)
├── home-configuration.scm # Guix Home 配置
└── config/                # 辅助配置文件
    ├── bashrc-extra
    ├── gitconfig-extra
    └── ssh-config

# 系统配置
/etc/guix-config/
├── config.scm            # 系统配置
├── channels-lock.scm     # 锁定的通道版本
└── README.md

# 项目级配置
project/
├── manifest.scm          # 项目依赖
├── channels.scm          # 锁定的通道版本
├── .guix-env             # 环境配置
└── README.md

12.2.2 配置分层策略

;; base-config.scm — 基础配置(所有机器共享)
(define %base-system
  (operating-system
    (timezone "Asia/Shanghai")
    (locale "zh_CN.utf8")
    ;; ...通用配置
    ))

;; server-config.scm — 服务器配置
(define %server-system
  (operating-system
    (inherit %base-system)
    (host-name "server")
    (services (append
                (list (service nginx-service-type ...)
                      (service postgresql-service-type ...))
                %base-services))))

;; desktop-config.scm — 桌面配置
(define %desktop-system
  (operating-system
    (inherit %base-system)
    (host-name "desktop")
    (services (append
                (list (service gnome-desktop-service-type))
                %desktop-services))))

12.2.3 Manifest 模块化

;; manifests/base.scm — 基础工具
(specifications->manifest
  '("vim" "git" "htop" "curl" "openssh"))

;; manifests/dev.scm — 开发工具
(use-modules (guix gexp))
(append-manifests
  (list
    (specifications->manifest
      '("gcc-toolchain" "cmake" "gdb"))
    ;; 可以引用其他 manifest
    (load-manifest "base.scm")))

;; manifests/python.scm — Python 环境
(specifications->manifest
  '("python" "python-pip" "python-virtualenv"
    "python-numpy" "python-pandas"))

12.3 包开发最佳实践

12.3.1 包定义规范

规范 说明
命名 小写,连字符分隔,遵循上游名称
版本 与上游保持一致
描述 使用完整句子,首字母大写
许可证 必须准确标注
主页 必须指向项目的官方主页
依赖 区分 inputs、native-inputs、propagated-inputs

12.3.2 代码质量检查

# 1. 语法检查
guix build my-package

# 2. 风格检查
guix style my-package

# 3. 静态分析
guix lint my-package

# 4. 安全检查
guix lint --check-for-vulnerabilities my-package

# 5. 可重现性检查
guix build --no-substitutes --check my-package

12.3.3 包定义模板

;; 标准包定义模板
(define-module (mychannel packages example)
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix git-download)
  #:use-module (guix build-system gnu)
  #:use-module (guix gexp)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (gnu packages)
  #:use-module (gnu packages base))

(define-public my-package
  (package
    (name "my-package")
    (version "1.0.0")
    (source
      (origin
        (method git-fetch)
        (uri (git-reference
               (url "https://github.com/user/my-package")
               (commit (string-append "v" version))))
        (sha256
          (base32 "0abc..."))))
    (build-system gnu-build-system)
    (native-inputs
      (list autoconf automake pkg-config))
    (inputs
      (list zlib libpng))
    (home-page "https://github.com/user/my-package")
    (synopsis "Short description of my package")
    (description "Longer description of my package, explaining
what it does and who it is for.  This should be at least
two sentences.")
    (license license:gpl3+)))

12.4 通道维护最佳实践

12.4.1 通道仓库结构规范

my-guix-channel/
├── .gitignore
├── .guix-channel          # 通道元数据
├── LICENSE
├── README.md
├── news.scm               # 更新日志
├── ci/
│   └── build-all.sh       # CI 脚本
└── mychannel/
    ├── packages/
    │   ├── web.scm
    │   ├── dev.scm
    │   └── utils.scm
    └── services/
        └── myapp.scm

12.4.2 CI/CD 配置

#!/bin/bash
# ci/build-all.sh — 构建通道中的所有包
set -e

CHANNEL_DIR="$(dirname "$0")/.."
cd "$CHANNEL_DIR"

echo "Linting all packages..."
guix lint -L . --all

echo "Styling all packages..."
guix style -L . --all

echo "Building all packages..."
# 找出所有公共包并构建
guix build -L . $(guix package -A -L . | awk '{print $1}' | sort -u)

echo "All checks passed!"
# .gitlab-ci.yml
stages:
  - lint
  - build

lint:
  stage: lint
  image: guix
  script:
    - guix pull
    - guix lint -L . --all
    - guix style -L . --check

build:
  stage: build
  image: guix
  script:
    - guix pull
    - bash ci/build-all.sh
  timeout: 2h

12.4.3 版本发布流程

# 1. 确保所有包构建通过
bash ci/build-all.sh

# 2. 运行测试
guix build -L . --no-substitutes my-package

# 3. 更新 news.scm
vim news.scm

# 4. 提交并打标签
git add -A
git commit -m "release: update packages to latest versions"
git tag -a v2026.05 -m "May 2026 release"
git push && git push --tags

# 5. 通知用户
echo "New release! Run: guix pull"

12.5 迁移策略

12.5.1 从传统 Linux 迁移到 Guix System

阶段一:评估(1-2 周)

# 1. 检查硬件兼容性
lspci -v | grep -i network
lspci -v | grep -i vga

# 2. 列出当前安装的软件包
# Debian/Ubuntu:
dpkg --get-selections | grep -v deinstall > packages.txt
# Fedora:
dnf list installed > packages.txt

# 3. 检查 Guix 中是否有这些包
while read pkg _; do
  guix search "^${pkg}$" | head -1
done < packages.txt

阶段二:双系统(2-4 周)

# 在现有系统上安装 Guix 包管理器
# 逐步将开发环境迁移到 Guix
guix install vim git python node

# 创建项目 manifest
guix shell --manifest=project.scm -- make

阶段三:完整迁移(1-2 周)

# 备份所有数据
# 安装 Guix System
# 使用之前编写的 config.scm
guix system init config.scm /mnt

# 部署 Guix Home
guix home reconfigure home-configuration.scm

12.5.2 从 NixOS 迁移

NixOS 概念 Guix 对应
/etc/nixos/configuration.nix /etc/config.scm
nix-env -i guix install
nix-channel guix channels.scm
nixos-rebuild switch guix system reconfigure
Home Manager guix home reconfigure
Nix Flakes guix channels + guix describe
nix-shell guix shell
nix build guix build

迁移步骤:

  1. 将 Nix 表达式翻译为 Scheme
  2. 列出所有包,查找 Guix 等价物
  3. 服务配置需要重写(Shepherd vs systemd)
  4. 测试并逐步切换

12.5.3 迁移检查清单

检查项 状态
硬件兼容性已确认
所有必需软件在 Guix 中可用
系统配置已完成并测试
用户数据已备份
网络配置已确认
SSH 密钥已迁移
项目 manifest 已创建
通道版本已锁定
回滚计划已准备

12.6 性能优化

12.6.1 二进制替代(Substitute)优化

# 使用官方构建服务器
guix build --substitute-urls=https://ci.guix.gnu.org vim

# 添加 Nonguix 替代源
# 在系统配置中:
(guix-service-type config =>
  (guix-configuration
    (inherit config)
    (substitute-urls
      (append '("https://substitutes.nonguix.org")
              %default-substitute-urls))
    (authorized-keys
      (append (list (plain-file "nonguix.pub" "..."))
              %default-authorized-guix-keys))))

12.6.2 并行构建

# 设置最大并行构建数
guix build vim --max-jobs=8

# 在系统配置中设置
(guix-service-type config =>
  (guix-configuration
    (inherit config)
    (max-jobs 8)))          ; 每个构建 8 个并行任务

12.6.3 缓存优化

# 查看 store 大小
du -sh /gnu/store

# 清理不再使用的对象
guix gc --collect-garbage

# 保留更多空间给缓存
guix gc -C 50G   ; 保留至少 50GB

# 查看可回收空间
guix gc --list-dead | wc -l
guix gc --list-dead | du -sh

12.7 故障排除指南

12.7.1 常见问题速查表

问题 原因 解决方案
guix: command not found PATH 未配置 添加 Guix bin 到 PATH
permission denied on store daemon 未运行 sudo systemctl start guix-daemon
hash mismatch 源码已更新 guix pull 更新通道
下载极慢 网络或替代服务器问题 检查代理或切换替代源
构建失败 依赖缺失或兼容性 查看构建日志 guix build -v 3
guix pull 超时 Git 仓库较大 使用 --depth=1 或镜像
locale 警告 GUIX_LOCPATH 未设置 export GUIX_LOCPATH=~/.guix-profile/lib/locale
服务无法启动 配置错误 sudo herd log <service>

12.7.2 诊断命令集合

# 系统状态
guix describe                    # 通道版本
guix package --list-installed    # 已安装包
guix package --list-generations  # 历史版本
sudo herd status                 # 服务状态

# 磁盘使用
du -sh /gnu/store                # store 大小
guix gc --list-dead | wc -l     # 可回收对象数

# 网络诊断
guix build vim -v 3              # 详细构建日志
curl -I https://ci.guix.gnu.org  # 替代服务器连通性

# 配置验证
guix system build /etc/config.scm  # 验证系统配置
guix home build ~/.config/guix/home-configuration.scm  # 验证 Home 配置

12.8 贡献指南

12.8.1 向 Guix 官方仓库贡献

步骤 1:设置开发环境

# 克隆 Guix 源码
git clone https://git.savannah.gnu.org/git/guix.git
cd guix

# 设置 Git 邮件列表工作流
git config format.subjectPrefix "PATCH guix"

步骤 2:创建补丁

# 创建新分支
git checkout -b add-my-package

# 添加包定义
# 编辑 gnu/packages/my-category.scm

# 提交
git add gnu/packages/my-category.scm
git commit -m "gnu: Add my-package."

步骤 3:检查补丁

# 风格检查
./pre-inst-env guix style my-package

# Lint 检查
./pre-inst-env guix lint my-package

# 构建测试
./pre-inst-env guix build my-package

# 发送邮件
git send-email --to=guix-patches@gnu.org

12.8.2 提交信息规范

gnu: Add my-package.                      ← 新增包
gnu: Update vim to 9.1.0.                 ← 更新版本
gnu: Fix build of gcc on aarch64.         ← 修复构建
gnu: my-package: Fix CVE-2024-1234.       ← 安全修复
services: Add myapp-service-type.         ← 新增服务
doc: Update installation guide.           ← 文档更新

12.8.3 包审查检查清单

检查项 说明
源码来源可信 官方发布页或可信 Git 仓库
许可证准确 与上游一致
构建可重现 两次构建结果一致
测试通过 make check 通过
Lint 无警告 guix lint 通过
风格正确 guix style 通过
描述完整 synopsis + description
依赖最小化 不包含不必要的依赖

12.9 社区资源

12.9.1 官方资源

资源 链接
官方网站 https://guix.gnu.org/
手册 https://guix.gnu.org/manual/
Cookbook https://guix.gnu.org/cookbook/
Bug 追踪 https://issues.guix.gnu.org/
邮件列表 guix-devel@gnu.org
IRC #guix on Libera.Chat
Matrix #guix:matrix.org
代码仓库 https://git.savannah.gnu.org/cgit/guix.git/

12.9.2 社区资源

资源 链接
Awesome Guix https://awesome-guix.com/
Guix 数据服务 https://data.guix.gnu.org/
替代包浏览器 https://guix.gnu.org/packages/
Nonguix https://gitlab.com/nonguix/nonguix
Guix Science https://gitlab.com/guix-science/

12.9.3 学习路径

入门 → 手册安装章节 → 本教程前三章
进阶 → Cookbook → 本教程中间章节
高级 → Guix 源码 → 邮件列表 → 贡献代码

12.10 Guix 的未来展望

12.10.1 发展方向

方向 说明
内容寻址存储 减少存储冗余,提高效率
更多包 社区持续增加包数量
更好的硬件支持 与 Linux 内核社区合作
GUI 工具 更友好的图形界面
云原生集成 更好的容器和 Kubernetes 支持
RISC-V 支持 新架构支持

12.10.2 参与方式

  • 测试和报告问题:使用 Guix 并报告 bug
  • 贡献包:添加新包或更新现有包
  • 翻译:帮助翻译文档
  • 推广:撰写教程、博客文章
  • 赞助:支持 GNU 项目

12.11 总结

本章总结了 Guix 使用的最佳实践:

  1. 日常工作流——更新、升级、验证的标准流程
  2. 配置管理——版本控制、分层、模块化
  3. 包开发——规范、检查、模板
  4. 通道维护——CI/CD、版本发布
  5. 迁移策略——从传统 Linux 或 NixOS 迁移
  6. 性能优化——替代源、并行构建、缓存
  7. 故障排除——常见问题和诊断方法
  8. 贡献指南——向官方仓库贡献的流程
  9. 社区资源——学习和交流的平台

12.12 教程回顾

经过 12 章的学习,你已经掌握了:

章节 核心收获
01 理解函数式包管理的理念
02 安装和配置 Guix
03 日常包管理操作
04 包定义的内部结构
05 通道和版本管理
06 声明式系统配置
07 服务管理体系
08 容器和隔离技术
09 可重现构建原理
10 用户环境管理
11 Docker 集成部署
12 最佳实践和工作流

现在,你已经具备了使用 Guix 管理从个人开发环境到生产服务器的完整能力。继续实践,参与社区,让函数式包管理成为你技术工具箱中的利器。


扩展阅读