例の 25 万円の PC には NixOS をインストールしました。すでに一ヶ月以上四苦八苦していますが、永住するつもりで末永く取り組んでいこうと思います。

NixOS の設定方法

設定ファイル

NixOS における設定方法は、主に 3 種類あります:

  1. システム全体の設定 (/run/current-system)
    /etc/nixos/configuration.nix を編集して設定します。
  2. ユーザ毎の設定 (~/.nix-profile)
    nix-env またはその wrapper で設定します。
    1. nix-env
      ユーザ毎に nix-env コマンドでパッケージをインストールできます。手続き的です。 nix-env は直接使用せず、次項の home-manager を使うことが推奨されています。
    2. home-manager
      nix-env の宣言的なバージョンです。ユーザ毎の設定を宣言的に記述できます。 ~/.config/nixpkgs/home.nix を編集するか、 /etc/nixos/configuration.nix からも設定できます。
  3. プロジェクト毎の設定
    default.nixshell.nix を書いて設定します。
    1. nix-shell (nix-shell --pure)
      • nix-shell は、現在の環境に追加でパッケージを読み込んでシェルを作ります。
      • nix-shell --pure は、設定ファイルに記述されたパッケージのみを取り込んだ純粋な環境のシェルを作ります。
    2. nix-direnv
      nix-direnv を使用すると、現在のシェルに default.nixshell.nix で宣言されたパッケージを (自動で) ロードできます。

Flakes を導入すれば話は変わってくるようですが、まだそれは調べられていません。

設定ファイルを現環境に反映するとは

通常の Linux では、 /usr 以下にツールをインストールします。一方 NixOS のファイル構成は LSB (Linux Standard Base) から外れています

NixOS の /usr はほぼ空です:

$ ls /usr
bin/

bin/ の中もスカスカでした:

$ ls /bin
@sh

$ ls /usr/bin
@env

しかし実際には多数のコマンドをインストールしています。

NixOS における環境

バイナリはどこへ?

調べると、 bash/run/current-system の下にありました。これが『現環境』に相当します:

$ which bash
/run/current-system/sw/bin/bash

また /run/current-system とは、『プロファイル』への symlink です:

$ realpath /run/current-system
/nix/store/zzzmz1yzhd0p648h447f7lwn18mhw4xz-nixos-system-nixos-22.11.2050.cc4bb87f545

プロファイルはどこに?

プロファイルの実体は /nix/store に保存され、プロファイルへの symlink が /nix/var/nix/profiles に保存されます。設定を反映するというのは、新しいプロファイルを作成し、現環境として反映されるプロファイルを更新するということになります。

System-wide なプロファイルの symlink を見てます:

$ realpath /run/current-system
/nix/store/zzzmz1yzhd0p648h447f7lwn18mhw4xz-nixos-system-nixos-22.11.2050.cc4bb87f545

$ realpath /nix/var/nix/profiles/system
/nix/store/zzzmz1yzhd0p648h447f7lwn18mhw4xz-nixos-system-nixos-22.11.2050.cc4bb87f545

ユーザ毎のプロファイルも確認します:

$ realpath ~/.nix-profile
/nix/store/6xbn0yjfz44rn7r11q402hddgprrwbsa-user-environment

$ realpath /nix/var/nix/profiles/per-user/tbm/profile
/nix/store/6xbn0yjfz44rn7r11q402hddgprrwbsa-user-environment

どちらも /nix/var/nix/profiles 以下の最新プロファイルと一致しました。

シェルの wrapper

特に設定を書いていないのに /run/current-system/sw/bin がシェルのパスに入っていたということは、 nixpkgs 上のシェルには何らかの細工が成されているはずです。

まとめ

バイナリとパスについては、だいたいイメージできました。動的ライブラリ (共有ライブラリ) はまだちょっと分かりません。