Installing NixOS on Raspberry Pi 4

Michael Lynch

在 Raspberry Pi 4 上安裝 NixOS

原文由 Michael Lynch 發布,訂閱此部落格

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 格式。

選項一:balenaEtcher

如果你不確定該用哪一套 microSD 燒錄工具,我推薦 balenaEtcher。它操作簡單,且可在各大作業系統上使用。

balenaEtcher 截圖

選項二: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 卡槽:

已插入 Raspberry Pi microSD 卡槽的 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。

如果一切順利,你應該會看到如下的開機過程:

在 Raspberry Pi 4 上成功啟動 NixOS microSD 映像檔的過程。

當你看到 NixOS 的命令提示字元時,代表開機已完成:

[nixos@nixos~:]$

如果開機失敗,請嘗試將 Pi 的 bootloader 更新至最新版本後再重試一次。

啟用 SSH 存取(選用)

在使用 Raspberry Pi 時,我覺得用 SSH 遠比在另一組鍵盤上輸入來得方便。

在全新的 NixOS 系統上,有兩種啟用 SSH 存取的方式。

選項一:設定密碼

在 NixOS 系統上,你可以執行以下指令,為預設的 nixos 使用者帳號設定密碼:

passwd

設定好密碼後,你就可以像平常一樣透過 SSH 連進 NixOS 系統:

ssh [email protected]

選項二:加入 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,不過我在下方提供了幾個適合新手在新系統上嘗試的實驗。

實驗一:更換桌面環境

上述的 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 只需要修改兩行設定。

要改變整個桌面環境,只需要修改兩行就完成了。

實驗二:建立臨時的軟體環境

我覺得最容易上手的 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 bootloader

如果你在啟動 NixOS 時遇到問題,可能需要更新 Pi 的 bootloader 和 EEPROM

請先啟動最新版本的 Raspberry Pi OS(又稱「Raspbian」),然後執行以下指令來安裝最新的 bootloader:

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 教學中的貢獻。

本文章由 muse-spark-1.2-contributor 進行翻譯

留言