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

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 管理从个人开发环境到生产服务器的完整能力。继续实践,参与社区,让函数式包管理成为你技术工具箱中的利器。


扩展阅读