PVE SeaBIOS 模式下 NixOS 的安装与初见

最近在迁移我用来开发编译的服务器,因为之前安装各种编译用的应用,而这些应用又有各自的依赖,搞的系统里面的各种环境越发混乱。趁着这次迁移服务器想着看看能不能解决这个问题,最开始想要使用 Docker 来为不同的工程创建专属的开发镜像,但发现环境搭建以及文件权限管理任然很复杂。

后来在上网冲浪时突然发现了一个工具—— Nix 包管理器,这是一个函数式包管理器和构建工具,它以其可重复性、隔离性和声明式配置而闻名。Nix 可以根据配置文件,定制开发或编译环境,且这些开发环境可以在任何设备上复现,并且 Nix 将包安装到一个特定的子目录中,每个包都是隔离的,所以一个包不会干扰另一个包。了解到这些特性后顿觉它或许会满足我的需求,因此便决定开始尝试使用 Nix。

本来只打算在我常用的 Debian 上直接安装 Nix,但看网上的教程都是基于 NixOS 的,所以还是直接使用 NixOS 来作为我的开发环境吧。因为参照网上的其他安装教程还是遇到了一些坑,所以这里还是自己记录并分享一下我的安装过程。

手动安装

NixOS 的安装镜像可以在官网下载页面挑选适合自己的版本下载,分为带图形界面的与最小安装镜像,因为我的机器性能有限且没有图形界面的需求,所以我用的是 Minimal ISO image,目前最新的版本为 25.05。

因为我是在 PVE 中安装所以我这里就不介绍如何制作安装介质以及设置引导,直接就从进入到 NixOS Live CD 开始。

启动后首先看到的是一个包含不同安装程序选项的菜单,这里保留默认设置并等待倒计时(或按 Enter 键加快速度),随后会系统启动到安装命令行中。

看其他的安装教程有说到 NixOS 的安装需要连接网络获取软件包,而访问境外服务器可能会遇到连接问题,所以也许需要设置镜像源,但我在实际安装过程中并无这样的问题所以就没有配置镜像源。

创建分区

在进行系统安装前首先需要对设备磁盘进行分区,使用的是 parted 工具进行分区的完整过程如下:

[nixos@nixos:~]$ lsblk # 查看磁盘设备
NAME  MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop0   7:0    0  1.5G  1 loop /nix/.ro-store
sda     8:0    0   32G  0 disk
sr0    11:0    1  1.6G  0 rom  /iso

[nixos@nixos:~]$ sudo parted /dev/sda # 对 /dev/sda 进行分区
GNU Parted 3.6
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt # 创建 GPT 分区表
(parted) mkpart primary 1MiB 2MiB # 创建 BIOS Boot 分区
(parted) set 1 bios_grub on # 设置分区标记
(parted) mkpart primary linux-swap 2MiB 2GiB # 创建 SWAP 分区,可以根据需要修改大小
(parted) mkpart primary 2GiB 100% # 剩余全部空间用于创建 Linux 根分区
(parted) p # 打印当前分区
Model: QEMU QEMU HARDDISK (scsi)
Disk /dev/sda: 34.4GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system     Name     Flags
 1      1049kB  2097kB  1049kB                  primary  bios_grub
 2      2097kB  2147MB  2145MB  linux-swap(v1)  primary  swap
 3      2147MB  34.4GB  32.2GB                  primary

(parted) quit # 结束分区设置
Information: You may need to update /etc/fstab.

上面共创建了三个分区,分别为:

  • /dev/sda1:BIOS Boot 分区,用于存放 GRUB 的核心代码;
  • /dev/sda2:SWAP 分区,系统虚拟内存;
  • /dev/sda3:Linux 根分区,存放跟文件系统与用户数据。

这里因为我的安装环境是使用 SeaBIOS,而我看到的教程都是使用 UEFI 的,所以在分区时遇到了一个坑,就是在 BIOS + GPT 情况下,GRUB 需要一个 1–2MiB 的 bios_grub 分区(类型 EF02 或标志 bios_grub on)来存核心代码,也就是需要创建上面的 /dev/sda1 分区。

分区格式化

新分区创建完成之后,还要对分区进行格式化。BIOS Boot 分区无需格式化,而对于 Linux 根分区我没有快照之类的需求所以没有选择使用 btrfs 文件系统,而是使用 ext4 格式。

格式化过程如下:

[nixos@nixos:~]$ sudo mkswap /dev/sda2 # 设置 SWAP 分区
Setting up swapspace version 1, size = 2 GiB (2145382400 bytes)
no label, UUID=a68f40b8-fc4a-482d-af9b-03a66245255a

[nixos@nixos:~]$ sudo swapon /dev/sda2 # 启用 SWAP 分区

[nixos@nixos:~]$ sudo mkfs.ext4 /dev/sda3 # 格式化根分区为 ext4 格式
mke2fs 1.47.2 (1-Jan-2025)
Discarding device blocks: done
Creating filesystem with 7864064 4k blocks and 1966080 inodes
Filesystem UUID: c4b86f33-5548-4388-8eb5-992e75db9aa0
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

挂载分区

在系统安装是安装程序会将根文件系统的内容(/bin, /lib, /etc, /usr …)写入根分区中,因此这里需要把它挂载到当前的 Live CD 环境中。

[nixos@nixos:~]$ sudo mount /dev/sda3 /mnt

创建 NixOS 配置

NixOS 是一个根据配置文件生成系统的发行版,因此需要将当前状态生成配置到目标系统中:

[nixos@nixos:~]$ sudo nixos-generate-config --flake --root /mnt
writing /mnt/etc/nixos/hardware-configuration.nix...
writing /mnt/etc/nixos/flake.nix...
writing /mnt/etc/nixos/configuration.nix...
For more hardware-specific settings, see https://github.com/NixOS/nixos-hardware.

nixos-generate-config 命令会根据系统检测到的硬件和分区创建初始配置文件,这里额外添加了 --flake 选项,是为了启用 NixOS 的 Flakes 支持,与 NixOS 默认的配置方式相比,Flakes 提供了更好的可复现性,同时它清晰的包结构定义原生支持了以其他 Git 仓库为依赖,具体 Flakes 的详细介绍这里不过多赘述。

  • hardware-configuration.nix:此文件包含自动检测到的硬件设置,例如文件系统挂载、交换分区和设备 UUID。 它通常不会直接修改,因为它可能会被将来调用 nixos-generate-config 覆盖;
  • configuration.nix:这是主配置文件,可以在其中定义系统的设置、包、服务和其他自定义项;
  • flake.nix:这是 Nix flakes 的核心组件,是 Nix 包管理器和 NixOS 操作系统中的一项实验性功能。 它充当定义 Nix 项目的输入(依赖项)和输出(flake 生成的内容,例如包、NixOS 配置或开发环境)的声明性入口点。

修改配置

对于 BIOS 模式启动,我们必须设置 boot.loader.grub.device 选项来指定 GRUB 引导加载程序应安装的磁盘,如果没有它,NixOS无法启动。

使用文本编辑器(例如 vim 或 nano)打开 /mnt/etc/nixos/configuration.nix 修改配置内容如下:

# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).

{ config, lib, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Use the GRUB 2 boot loader.
  boot.loader.grub.enable = true;
  # boot.loader.grub.efiSupport = true;
  # boot.loader.grub.efiInstallAsRemovable = true;
  # boot.loader.efi.efiSysMountPoint = "/boot/efi";
  # Define on which hard drive you want to install Grub.
  boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only

  networking.hostName = "nixos"; # Define your hostname.
  # Pick only one of the below networking options.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.
  # networking.networkmanager.enable = true;  # Easiest to use and most distros use this by default.

  # Set your time zone.
  time.timeZone = "Asia/Shanghai";

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";
  # console = {
  #   font = "Lat2-Terminus16";
  #   keyMap = "us";
  #   useXkbConfig = true; # use xkb.options in tty.
  # };

  # Enable the X11 windowing system.
  # services.xserver.enable = true;




  # Configure keymap in X11
  services.xserver.xkb.layout = "us";
  # services.xserver.xkb.options = "eurosign:e,caps:escape";

  # Enable CUPS to print documents.
  # services.printing.enable = true;

  # Enable sound.
  # services.pulseaudio.enable = true;
  # OR
  # services.pipewire = {
  #   enable = true;
  #   pulse.enable = true;
  # };

  # Enable touchpad support (enabled default in most desktopManager).
  # services.libinput.enable = true;

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.username = { # Change "username" to your own username
    isNormalUser = true;
    extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
    shell = pkgs.bashInteractive;
    packages = with pkgs; [
      tree
    ];
  };

  # programs.firefox.enable = true;

  # List packages installed in system profile.
  # You can use https://search.nixos.org/ to find more packages (and options).
  environment.systemPackages = with pkgs; [
    vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
    wget
  ];

  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  services.openssh.enable = true;

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # Copy the NixOS configuration file and link it from the resulting system
  # (/run/current-system/configuration.nix). This is useful in case you
  # accidentally delete configuration.nix.
  # system.copySystemConfiguration = true;

  # This option defines the first version of NixOS you have installed on this particular machine,
  # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
  #
  # Most users should NEVER change this value after the initial install, for any reason,
  # even if you've upgraded your system to a new NixOS release.
  #
  # This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
  # so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
  # to actually do that.
  #
  # This value being lower than the current NixOS release does NOT mean your system is
  # out of date, out of support, or vulnerable.
  #
  # Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
  # and migrated your data accordingly.
  #
  # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
  system.stateVersion = "25.05"; # Did you read the comment?

}

上面是我自己的配置内容,除了BIOS 模式启动必须设置 boot.loader.grub.device 选项外,其他内容都可以根据自己的需要进行修改,也可以完全不修改使用默认配置,后面系统安装完成后仍然可以随时修改系统配置。

安装 NixOS

最后,开始部署系统:

[nixos@nixos:~]$ cd /mnt

[nixos@nixos:/mnt]$ sudo nixos-install
copying channel...
building the configuration in /mnt/etc/nixos/configuration.nix...
these 246 derivations will be built:
  /nix/store/0cw3s005gyh3v10sd9wv0lj00ybni440-mount-pstore.sh.drv
  /nix/store/0cxq5axa7ff81vjcqv2gdrx7wqra6x20-etc-netgroup.drv

...

building '/nix/store/vh9inlgw32820f7h8wz5vgnm84qpfx1g-etc.drv'...
building '/nix/store/8vm2zmmkdzgdk8gwfww2liim4wn902vj-nixos-system-nixos-25.05.807449.ce01daebf848.drv'...
/nix/store/xb9hfiaq8axjnayrwydh7rh8yniqch47-nixos-system-nixos-25.05.807449.ce01daebf848
installing the boot loader...
setting up /etc...
updating GRUB 2 menu...
installing the GRUB 2 boot loader on /dev/sda...
Installing for i386-pc platform.
Installation finished. No error reported.
setting up /etc...
setting up /etc...
setting root password...
New password:
Retype new password:
passwd: password updated successfully
installation finished!

在系统部署的最后会提示设置 root 用户的密码,根据提示设置即可。

到此,NixOS 的安装也基本完成,只需重启系统(注意需要调整启动项,断掉安装介质)即可。

设置用户密码(可选)

在上面的配置 /mnt/etc/nixos/configuration.nix 中我添加了一个普通用户:

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.username = { # Change "username" to your own username
    isNormalUser = true;
    extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
    shell = pkgs.bashInteractive;
    packages = with pkgs; [
      tree
    ];
  };

在进入系统之前也可以利用 nixos-enter 程序对该用户的密码进行设置,过程如下:

nixos-enter 程序是NixOS的一部分,在系统运行之前,它会提供一个shell,脚本会挂载api文件系统,如/proc,并设置目标系统的配置文件和/etc。

[nixos@nixos:~]$ sudo nixos-enter
setting up /etc...

[root@nixos:/]# passwd username # 注意修改 "username" 为你的用户名
New password:
Retype new password:
passwd: password updated successfully

BIOS 模式安装遇到的坑

前面创建分区部分有提到,因为我的安装环境使用的是 SeaBIOS,因此需要创建 BIOS Boot 分区。而我一开始在遵循其他教程时是按照 UEFI 介绍的,因此我在 nixos-install 时出现如下错误:

warning: this GPT partition label contains no BIOS Boot Partition; embedding won’t be possible.
warning: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and their ue is discouragted.
installation of GRUB on /dev/sda failed: No such faile or directory
Failed to install bootloader

只需要在创建分区时分出一个 1MB 左右的 BIOS Boot Partition(分区类型 EF02)即可正常完成安装。

参考

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇