Installing NixOS on Raspberry Pi 4

Michael Lynch

在 Raspberry Pi 4 上安装 NixOS

Nix 是一种工具,可让你通过代码定义软件环境。Nix 包含多个组件,其中最令我感兴趣的是 NixOS,它能让你使用 Nix 工具通过纯文本文件定义整个操作系统的配置。

我最近才开始尝试使用 Nix,有大量内容需要学习。我尝试做的第一件事就是在我的 Raspberry Pi 上安装 NixOS,但最初的几次尝试都失败了。我能找到的每一个 NixOS Pi 教程要么不完整,要么已经过时。

在此,我为你提供一份完整且可行的在 Raspberry Pi 4 上安装 NixOS 的指南。我也是 NixOS 新手,因此本指南面向 Nix 初学者,但我假定你对 Raspberry Pi 和 Linux 有基本的了解。

要求

学习本教程,你需要:

  • 配备至少 2 GB 内存的 Raspberry Pi 4
  • 至少 8 GB 存储空间的 microSD 卡
  • microSD 读卡器
  • 一台用于烧录 microSD 卡的备用电脑

下载 NixOS microSD 镜像

首先,请通过以下链接下载 NixOS microSD 镜像:

你可以在 Nix 的构建服务器上查看带有绿色对勾的最新构建,以找到更新的镜像。

我最近尝试使用一个更新的构建(nixos-image-sd-card-25.05beta741800.78886a72ed11,构建于 2025-01-19)来执行此过程,但安装失败了。后续的 nixos-build 步骤耗尽了我这台 2 GB 内存的 Pi 4 的内存。

解压 NixOS microSD 镜像

NixOS 团队使用一种名为 Zstandard 的压缩格式来压缩他们的 microSD 镜像,这是一种来自 Facebook 的开源格式。

要解压 NixOS 镜像,请为你的平台下载最新版本的 Zstandard:

同时备好 Zstandard 工具和 NixOS microSD 镜像后,使用以下命令解压 .img.zst 文件:

zstd --decompress 'nixos-sd-image-23.11pre515819.8ecc900b2f69-aarch64-linux.img.zst'

解压该 Zstandard 文件后,应会生成一个名为 nixos-sd-image-23.11pre515819.8ecc900b2f69-aarch64-linux.img 的文件。

烧录 NixOS microSD 镜像

解压镜像后,使用你喜欢的 microSD 烧录工具将其烧录到 microSD 卡上。

烧录 microSD 时,请选择 .img 文件而非 .img.zst 文件,因为大多数烧录工具无法识别 Zstandard 格式。

选项 1:balenaEtcher

如果你不知道该使用哪款 microSD 烧录工具,我推荐 balenaEtcher。它易于使用,且可在所有主流操作系统上运行。

balenaEtcher 截图

选项 2:caligula

balenaEtcher 在 NixOS 上不可用,因此如果你使用的是 NixOS,一个不错的替代工具是 caligula

caligula burn \
  nixos-sd-image-23.11pre515819.8ecc900b2f69-aarch64-linux.img.zst

caligula 原生支持 Zstandard 文件压缩,因此你无需先解压镜像。

将 microSD 卡插入 Pi

烧录完成后,将 microSD 卡插入 Raspberry Pi 的 microSD 卡槽:

microSD 卡插入 Raspberry Pi 的 microSD 卡槽的照片

将已烧录的 microSD 卡插入 Pi 的 microSD 卡槽。

为 Pi 连接显示器和键盘

大多数 Raspberry Pi 镜像都提供在首次启动时通过网络访问设备的方式。我在 NixOS 上还没找到这样的方法,因此你需要暂时为 Pi 连接键盘和 HDMI 显示器,以查看运行情况。

键盘和 HDMI 显示器连接到正在启动 NixOS 的 Raspberry Pi 的照片

NixOS 没有完全通过网络进行的安装方式,因此在初始设置期间,你需要连接键盘和 HDMI 显示器。

在本教程中,我使用 TinyPilot 来控制我的 Pi,这是一款我为这类场景而创建的设备。

TinyPilot 连接到 Raspberry Pi 4 的照片TinyPilot 控制运行 Plasma 桌面环境的 NixOS 系统的截图

我使用 TinyPilot 设备在 Raspberry Pi 上安装了 NixOS,因为它让我无需在不同键盘之间来回切换。

本教程并不需要 TinyPilot,使用普通的键盘和 HDMI 显示器即可完成操作。

启动你的 NixOS 系统

激动人心的时刻到了。给你的 Raspberry Pi 通电。

如果一切顺利,你应该会看到如下的启动序列:

NixOS microSD 镜像在 Raspberry Pi 4 上成功启动。

当你看到 NixOS 命令提示符时,即表示启动已完成:

[nixos@nixos~:]$

如果启动失败,请尝试将 Pi 的引导加载程序更新到最新的可用版本,然后重试。

启用 SSH 访问(可选)

在使用 Raspberry Pi 时,我发现通过 SSH 要比在独立键盘上输入方便得多。

在全新的 NixOS 系统上启用 SSH 访问有两种方法。

选项 1:添加密码

在 NixOS 系统上,你可以通过运行以下命令为默认的 nixos 用户账户设置密码:

passwd

设置密码后,你就可以像往常一样通过 SSH 连接到你的 NixOS 系统:

ssh [email protected]

选项 2:添加 SSH 密钥

你也可以将你的 SSH 公钥作为授权密钥添加到系统上。

如果你使用 SSH 密钥向 GitHub 进行身份验证,GitHub 提供了一种便捷的方式,可将你的 SSH 公钥下载到任何设备上:

GITHUB_USERNAME='your-github-username' # Replace this.

mkdir -p ~/.ssh && \
  curl "https://github.com/${GITHUB_USERNAME}.keys" > ~/.ssh/authorized_keys

如果你看到提示 certificate is not valid yet 的错误,意味着你的 Pi 仍在同步系统时间。请等待 60 秒,然后重试该命令。

将你的 SSH 公钥添加到 NixOS 系统后,你就可以像往常一样通过 SSH 连接:

ssh [email protected]

编写 NixOS 配置文件

你现在已经进入 NixOS 了!

目前还做不了太多事情,因为这是一个最小化的 NixOS 环境,尚未安装任何内容。

为了让你的 NixOS 体验更有趣,请安装一个桌面图形界面和一些应用程序。首先,下载我的 NixOS 配置文件示例

curl \
  --show-error \
  --fail \
  https://mtlynch.io/nixos-pi4/configuration.nix \
  | sudo tee /etc/nixos/configuration.nix

此时你可以使用 nanovim/etc/nixos/configuration.nix 进行修改。你可能想要更改文件顶部的 hostnameuserpassword 的值。

sudo nano /etc/nixos/configuration.nix

暂时不必过于担心配置文件的完美程度。使用 NixOS,你可以随时改变任何选项的想法,应用更改只需再次编辑配置文件即可。

当你对 configuration.nix 文件满意后,运行以下命令将配置应用到系统并重启:

sudo nixos-rebuild boot && \
  echo "install complete, rebooting..." && \
  sudo poweroff --reboot

重启完成后,你应该会看到如下界面:

你的 Pi 现在正运行着搭载 Gnome 桌面环境的 NixOS!

如果你使用的是上面默认的 configuration.nix 文件,你的用户名是 tempuser,密码是 somepass

体验 NixOS

至此,你的 NixOS 系统已经启动并运行。

你可以随心所欲地探索 NixOS,不过我在你的新系统上准备了几个适合初学者的实验供你尝试。

实验 1:更换桌面环境

上面的 configuration.nix 文件假定你想使用 Gnome 桌面环境,但也许你更喜欢其他环境。还有一款名为 Plasma 的桌面管理器,其设计与 Microsoft Windows 相似。

要将你的 NixOS 系统从 Gnome 切换为使用 Plasma,请在文本编辑器中打开你的 configuration.nix 文件:

sudo nano /etc/nixos/configuration.nix

在文件中找到以下几行:

    displayManager.gdm.enable = true;
    desktopManager.gnome.enable = true;

将其替换为以下几行:

    displayManager.sddm.enable = true;
    desktopManager.plasma5.enable = true;

要应用更改,请保存文件,退出 nano,然后运行以下命令:

sudo nixos-rebuild boot && sudo reboot

重启后,你应该会看到如下桌面:

TinyPilot 控制运行 Plasma 桌面环境的 NixOS 系统的截图,登录界面TinyPilot 控制运行 Plasma 桌面环境的 NixOS 系统的截图,桌面界面

在 NixOS 中,将桌面管理器从 Gnome 切换到 Plasma 只需改动两行配置。

改变整个桌面环境只需改动两行配置。

实验 2:创建临时软件环境

我发现最容易上手的 Nix 工具之一是 nix-shell。它能让你即时创建包含你指定软件包的软件环境。

nix-shell 不会影响系统上的任何其他配置,因此你可以放心尝试新工具,而不用担心破坏其他内容。

我有时会遇到几年前写的、依赖旧版本 Node.js 的项目。我曾尝试使用像 nvm 这样的工具来并排安装多个 Node 版本,但每次都要花 20 分钟来回忆如何正确使用和配置 nvm

尽管 nix-shell 是一个用于安装软件包的通用工具,我发现它甚至比 nvm 这类特定语言的开发工具更方便。

以下是如何使用 nix-shell 创建一个包含 Node.js 18.x 的环境:

$ nix-shell --packages nodejs-18_x
these paths will be fetched (11.25 MiB download, 52.36 MiB unpacked):
  /nix/store/87kgx3ym4kgmqwaijckqvbfrkzm8ax75-nodejs-18.2.0
copying path '/nix/store/87kgx3ym4kgmqwaijckqvbfrkzm8ax75-nodejs-18.2.0' from 'https://cache.nixos.org'...

[nix-shell:~]$ node --version
v18.2.0

[nix-shell:~]$ npm --version
8.9.0

使用完该环境后,只需按下 Ctrl+D 或输入 exit 即可退出。

以下是创建 Node.js 16.x 环境的同样方法:

$ nix-shell --packages nodejs-16_x
these paths will be fetched (10.77 MiB download, 50.24 MiB unpacked):
  /nix/store/1ba3sqw3rkadg2ksywqc85lq2hvx9fvk-nodejs-16.15.0
copying path '/nix/store/1ba3sqw3rkadg2ksywqc85lq2hvx9fvk-nodejs-16.15.0' from 'https://cache.nixos.org'...

[nix-shell:~]$ node --version
v16.15.0

[nix-shell:~]$ npm --version
8.5.5

故障排除

升级到最新的 Pi 引导加载程序

如果在启动 NixOS 时遇到问题,你可能需要更新 Pi 的引导加载程序和 EEPROM

启动一个最新版本的 Raspberry Pi OS(又称“Raspbian”),然后运行以下命令来安装最新的引导加载程序:

sudo raspi-config nonint do_boot_rom E1 && \
  sudo reboot

要更新 EEPROM,请运行以下命令:

sudo apt update && \
  sudo apt install --yes rpi-eeprom && \
  sudo rpi-eeprom-update -a && \
  sudo reboot

我测试的 Pi 4 设备可以开箱即用地启动 NixOS 23.11 磁盘镜像,因此对我来说无需执行上述步骤。

附录:失败的尝试

在编写本教程的过程中,我尝试了许多行不通的方法。为了节省他人重复尝试相同步骤的时间,我将它们收集在此:


感谢来自 NixOS 文档团队的 Alex Groleau(亚历克斯·格罗洛) 对本指南的帮助,以及他为官方 NixOS Raspberry Pi 教程所做的工作。

原文由 Michael Lynch 发布

本文章由 muse-spark-1.2-contributor 进行翻译