プログラミング
小さなNixOS ISOが欲しい?
I can haz smoller NixOS ISOs? (natkr.com)
要約
この記事は、NixOSのISOイメージを可能な限り小型化する方法を詳細に探求しています。デフォルトのNixOS ISOが約458MiBと大きいことから、Nixデーモンの無効化やドキュメントの削除といった設定変更を通じて、より軽量なISOを作成するプロセスを解説しています。Alpine LinuxのVM ISO(約66MiB)を目標に、不要なコンポーネントを特定し削減していく手法が紹介されています。
全文翻訳
もっと小さなNixOS ISOが欲しい?2026-06-19 :: テック :: タグ: #Deep Dive #ISO #Nix #NixOS #Virtualization この記事では、私が苦労してLinuxライブイメージから機能を削除する様子を紹介します。普通の人と同じように。
しかし、まずISOは手に入るのか NixOSのクールな裏技の一つは、いくつかの設定を使って簡単に仮想マシン(VM)として実行できることです。nixos-rebuild build-vm はあなたのシステム設定用のVMを提供してくれます1。しかし、システムであるかどうかにかかわらず、どんな設定でもVMを作成できます!
```nix
let pkgs = import (fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/567a49d1913ce81ac6e9582e3553dd90a955875f.tar.gz"; sha256 = "1vq77hlx8mi3z03pw2nf6r5h7473r1p9yxyf58ym3fh01zppmfln"; }) {}; in pkgs.nixos { system.stateVersion = "26.05"; services.getty.autologinUser = "root"; }
```
これで最小限のVMが得られます。$(nix-build basic-vm.nix --attr vm --log-format bar --no-out-link)/bin/run-nixos-vm で自分で実行できます。これは「シン」VMを作成します。ディスクイメージはありますが、VM内に入ってから自分で作成したファイルしか含まれません2。それ以外のすべて(/nix/storeなど)はホストOSからマウントされます。
それがうまくいく場合は素晴らしいのですが、時にはもう少し普通のものが欲しいこともあります。libvirt3で実行できるものや、Nixを持たないかもしれないリモートホストに送れるものです。Linuxさえ実行しないかもしれません。ひょっとしたらハイパーバイザーすらないかもしれません!4要するに、私はただISOが欲しいのです。
幸いなことに、NixOSはここでも私の味方です。
```nix
let pkgs = import (fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/567a49d1913ce81ac6e9582e3553dd90a955875f.tar.gz"; sha256 = "1vq77hlx8mi3z03pw2nf6r5h7473r1p9yxyf58ym3fh01zppmfln"; }) {}; in pkgs.nixos ({ lib, ... }: { system.stateVersion = "26.05"; services.getty.autologinUser = "root"; imports = [ "${pkgs.path}/nixos/modules/installer/cd-dvd/iso-image.nix" ]; image.baseName = lib.mkForce "nixos"; })
```
今回はQEMUを自分で実行する必要がありますが、それほど悪くはありません。
```bash
qemu-system-x86_64 --cdrom $(nix-build basic-iso.nix --attr isoImage --log-format bar --no-out-link)/iso/nixos.iso -m 1G --accel kvm5
```
楽園のトラブル では、これで終わりですね?しかし...まだタイトルの本題に触れていませんでした!ええと、それについてですが...
```bash
$ ls -lh $(nix-build basic-iso.nix --attr isoImage --log-format bar --no-out-link)/iso/nixos.iso
-r--r--r-- 1 root root 458M jan 1 1970 /nix/store/kg8mv6296hbhm8als26r400nj1s7ry1n-nixos.iso/iso/nixos.iso
```
おお、458MiB‽6?まだ何もしていないのに!
```bash
[root@nixos:~]# vim
-bash: vim: command not found
```
これは、私の子供時代のDamn Small Linuxが驚くほど完成されたデスクトップ環境を実行するのに必要だったサイズのほぼ10倍です!7おそらくそこまでのレベルには達しないでしょうが、もう少し良くする余地はきっとあるはずです。比較のために、AlpineのVM ISOは現在約66MiBです。なので、それが比較対象として妥当なベースラインでしょう。
他に何があるのでしょうか?では、何にお金を払っているのか見てみましょう...
```bash
$ sudo mount $(nix-build basic-iso.nix --attr isoImage --log-format bar --no-out-link)/iso/nixos.iso iso --mkdir
$ du iso --all --block-size=1M | sort -n | tail -n10
3 iso/isolinux
13 iso/boot/nix/store/92id8yn2g9kj7bskld42p222pmk3y3ms-linux-6.18.35
13 iso/boot/nix/store/92id8yn2g9kj7bskld42p222pmk3y3ms-linux-6.18.35/bzImage
26 iso/boot/nix/store/zvn61hpw86ncvgsr8vjrfi3ahnk2c9hb-initrd-linux-6.18.35
26 iso/boot/nix/store/zvn61hpw86ncvgsr8vjrfi3ahnk2c9hb-initrd-linux-6.18.35/initrd
39 iso/boot
39 iso/boot/nix
39 iso/boot/nix/store
416 iso/nix-store.squashfs
458 iso
```
つまり...メインのユーザー空間に416MiB、初期ブート環境に26MiB、カーネル自体に13MiBです。少なくとも後者2つは今のところ無視できますね8。では、そのsquashfsも開いて、それがどんな秘密を隠しているのか見てみましょう...
```bash
$ sudo mount iso/nix-store.squashfs squash --mkdir
$ du squash --max-depth=1 --block-size=1M | sort -n | tail -n20
11 squash/bizyfqdw0h67wzqmp10knmf9s2pqahdb-file-5.47
13 squash/pa0x6m662kr9vr875fcp1cl9wwkswsa8-coreutils-full-9.11
14 squash/dscn63ni6fp8p58y99b3ywk478b4bvmv-texinfo-interactive-7.2
14 squash/gf6i4cbisapj28y2dnqhpk1s95vd2r36-util-linux-2.42-lib
15 squash/qmajd4nyy8zf70g9p4x2lcq45gq5gzy3-boost-1.89.0
16 squash/jlyahda14aya375lv7k9fsin2zk90nxz-glib-2.88.1
21 squash/cfjm0s2jnlaiz9y3byvfa0fc6fp2la20-systemd-minimal-260.1
22 squash/92id8yn2g9kj7bskld42p222pmk3y3ms-linux-6.18.35
24 squash/dis2sflz0lifcji3gb81rbr7896dw39l-nix-manual-2.34.7
26 squash/zvn61hpw86ncvgsr8vjrfi3ahnk2c9hb-initrd-linux-6.18.35
28 squash/ryi73l6ic3pz9vh69nj0i4l188vkqgaq-nixos-manual-html
30 squash/r1nzk3ga4fk9q2xw77md2ln88m98d2vc-grub-2.12
32 squash/cl0a76f140zrrbx0n0qpjx07794q5gzn-grub-2.12
34 squash/57iz36553175g3178pvxjij8z5rcsd4n-glibc-2.42-61
39 squash/clpq5c7bysml4vqpa1x60a5yk3nzkfj4-icu4c-76.1
56 squash/6plwsm6pkq79yjv4xvy8csk2pd4hzr67-perl-5.42.0
60 squash/a8avqfxd649rfgfpqldja6v38ljb8fj5-systemd-260.1
128 squash/60m4rxhg2fldqaak400c0lry96ijrzqn-python3-3.13.13
144 squash/f060awdpif3c41v4wbshd6h6jzbxdv66-linux-6.18.35-modules
1064 squash
```
まあ、それはNixストアによく似ていますね...9そして、ホストマシンでビルドしたので、その中のものはすべてホストストアにもあるはずです!だから、squash/を/nix/store/に置き換えて、nix why-dependsを使って依存関係の出所を調べることができます!例えば、Boostの依存関係がどこから来ているかを尋ねることができます。
```bash
$ nix why-depends $(nix-build basic-iso.nix --attr config.isoImage.storeContents --no-out-link) /nix/store/qmajd4nyy8zf70g9p4x2lcq45gq5gzy3-boost-1.89.0 --precise
/nix/store/w27j1xagd7cb5qxm1phmvffdwnk4b3wc-nixos-system-nixos-26.11pre-git
└───activate: …fsx38qi-setup-etc.pl /nix/store/7nvwsgl5cplzal9y5m9nnwjjrbbvzcjv-etc/etc..if (( _localstatus > 0…
→ /nix/store/7nvwsgl5cplzal9y5m9nnwjjrbbvzcjv-etc
└───etc/tmpfiles.d/00-nixos.conf -> /nix/store/0zl414yp4h3ppb63h20pljy5rn5v10w4-tmpfiles.d/00-nixos.conf
→ /nix/store/0zl414yp4h3ppb63h20pljy5rn5v10w4-tmpfiles.d
└───nix-daemon.conf -> /nix/store/hqwkw2nala59avjximpdmn1yi474n4h7-nix-2.34.7/lib/tmpfiles.d/nix-daemon.conf
→ /nix/store/hqwkw2nala59avjximpdmn1yi474n4h7-nix-2.34.7
└───bin/nix: …1.3.2.GLIBCXX_3.4.21./nix/store/a90px0h1szz9y9c67ww1sa163z44flf9-nix-util-2.34.7/lib:/nix/store…
→ /nix/store/a90px0h1szz9y9c67ww1sa163z44flf9-nix-util-2.34.7
└───lib/libnixutil.so.2.34.7: …5-libcpuid-0.8.1/lib:/nix/store/qmajd4nyy8zf70g9p4x2lcq45gq5gzy3-boost-1.89.0/lib:/nix/store>
→ /nix/store/qmajd4nyy8zf70g9p4x2lcq45gq5gzy3-boost-1.89.0
```
ああ!10 Nixデーモンをインストールすると、それがBoostも一緒に取り込んでいたのですね。
軽量化の開始 非常に有用なsearch.nixos.orgをしばらく調べた結果、nix.enable = falseを設定することでNixの出荷を完全に無効にできるはずです。また、ドキュメントを完全に無効にするキルスイッチとしてdocumentation.enable = falseもあります。では、両方を試してみましょう...
```nix
let pkgs = import (fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/567a49d1913ce81ac6e9582e3553dd90a955875f.tar.gz"; sha256 = "1vq77hlx8mi3z03pw2nf6r5h7473r1p9yxyf58ym3fh01zppmfln"; }) {}; in pkgs.nixos ({ lib, ... }: { system.stateVersion = "26.05"; services.getty.autologinUser = "root"; imports = [ "${pkgs.path}/nixos/modules/installer/cd-dvd/iso-image.nix" ]; image.baseName = lib.mkForce "nixos"; nix.enable = false; documentation.enable = false; })
```
これで...大成功、家に帰って祝いましょうか?
```bash
$ ls -lh $(nix-build sans-nix.nix --attr isoImage --log-format bar --no-out-link)/iso/nixos.iso
-r--r--r-- 1 root root 384M jan 1 1970 /nix/store/rm5zhcmxmypgg4rl2yb2c9lcpaqda85y-nixos.iso/iso/nixos.iso
```
まあ、いいスタートです。しかし、まだ終わりではありません。残念ながら、Boostを完全に排除できたわけではないことがわかります。
```bash
$ nix why-depends $(nix-build sans-nix.nix --attr config.isoImage.storeContents --no-out-link) /nix/store/qmajd4nyy8zf70g9p4x2lcq45gq5gzy3-boost-1.89.0 --precise
/nix/store/aznzf6j6mjllgxllmx92wgmjc977ryin-nixos-system-nixos-26.11pre-git
└───activate: …fsx38qi-setup-etc.pl /nix/store/3kmvk7vy9gr83xnp
```