Как я ужал NixOS ISO с 458 МБ до 183 МБ
Автор блога natkr.com уменьшил установочный ISO NixOS с 458 МБ до 183 МБ. Разбираем, какие модули и пакеты можно убрать, и почему готовую конфигурацию не стоит копировать на рабочую машину.
Базовый установочный ISO NixOS весит 458 МБ — и в нём даже нет vim. Для сравнения, Alpine Linux укладывается примерно в 66 МБ. Разбираем, как автор блога natkr.com уменьшил NixOS почти в 2,5 раза, и где здесь подвох.
Что такое NixOS
NixOS — это дистрибутив Linux, в котором всё системное окружение описывается декларативно на языке Nix и воспроизводится из одного конфигурационного файла. Каждая сборка помещает зависимости в /nix/store, что даёт атомарные откаты и воспроизводимость, но при этом легко разрастается размер.
Одна из удобных фич — команда nixos-rebuild build-vm: она превращает конфигурацию в виртуальную машину. Но иногда нужен не «тонкий» образ, привязанный к хосту, а самодостаточный ISO, который можно записать на флешку или загрузить в облаке.
Ключевые выводы
- Базовый NixOS ISO занимает 458 МБ: 416 МБ — squashfs с пользовательским окружением, 26 МБ — initrd, 13 МБ — ядро.
- Главные «тяжеловесы» внутри образа: модули ядра (144 МБ), Python 3 (128 МБ), systemd (60 МБ), Perl (56 МБ), GRUB (около 62 МБ).
- Отключение Nix, документации, SSH, firewall и лишних зависимостей сокращает ISO до 197 МБ.
- Замена Perl-активации на экспериментальные system.etc.overlay и services.userborn даёт финальный размер около 183 МБ.
- Это игрушечный эксперимент: для десктопа и сервера такие отсечения небезопасны, но полезны как источник идей.
От VM к ISO за несколько строк
Минимальная виртуальная машина на NixOS собирается из файла примерно такого вида:
Запуск: $(nix-build basic-vm.nix --attr vm --no-out-link)/bin/run-nixos-vm. При этом /nix/store монтируется с хоста, поэтому VM «тонкая». Для независимого ISO импортируем модуль iso-image.nix и собираем атрибут isoImage:
ISO собирается, загружается в QEMU, но размер сразу бросается в глаза.
458 МБ — из чего они сложились
Автор примонтировал полученный ISO и посмотрел распределение места. Вот ключевые цифры:
- 416 МБ — сжатый
nix-store.squashfsс пользовательским окружением. - 26 МБ — начальная загрузочная среда initrd.
- 13 МБ — ядро Linux.
- 3 МБ — загрузчик isolinux.
При распаковке squashfs картина ещё интереснее:
- 144 МБ — модули ядра (
linux-6.18.35-modules). - 128 МБ — Python 3.13.
- 60 МБ — systemd.
- 56 МБ — Perl.
- ~62 МБ суммарно — две копии GRUB (UEFI + BIOS).
Поскольку ISO собирается локально, все пакеты из него есть и в хостовом /nix/store. Это позволяет использовать nix why-depends, чтобы найти, кто тащит каждую зависимость.
Отключаем Nix, документацию и лишние сервисы
Первый очевидный шаг — отказаться от демона Nix внутри ISO, ведь мы строим автономный образ, а не полноценную NixOS для работы с пакетами. Достаточно двух опций:
Результат: 384 МБ. Экономия скромная, потому что часть зависимостей Nix всё ещё тянется через сервис register-nix-paths. Он регистрирует содержимое хранилища ISO при загрузке — но Nix-то мы уже убрали. Отключаем и его:
Теперь ISO уменьшился до 360 МБ, а зависимость от Boost исчезла полностью.
SSH: модуль без выключателя
Следующий кандидат на удаление — OpenSSH-клиент. Проблема в том, что модуль programs/ssh.nix добавляет его в environment.corePackages, а отдельного переключателя programs.ssh.enable нет.
Попытка полностью исключить модуль через disabledModules ломает другие модули, например Plasma 6, которые ожидают существования опций programs.ssh. Выход — подменить опцию «пустышкой», не затрагивающей реальную конфигурацию:
Параллельно автор убрал firewall, documentation.man.enable и принудительно очистил environment.defaultPackages.
GRUB: зачем две копии загрузчика
ISO-пресет NixOS включает сразу и UEFI-, и BIOS-версии GRUB — отсюда около 62 МБ. Чёткого флага для отключения одной из них нет, поэтому автор пошёл грубым путём: сбросил system.extraDependencies и environment.systemPackages, оставив только environment.corePackages, чтобы shell хотя бы стартовал.
Ядерные модули: четверть образа
Модули ядра весили 144 МБ — больше, чем весь Alpine ISO. NixOS не предоставляет удобного способа ограничить их набор для runtime, поэтому автор просто удалил папку модулей из системы после сборки:
Это полностью отключает динамическую загрузку модулей. Если что-то нужно — оно должно оказаться в boot.initrd.kernelModules или availableKernelModules. После этого образ уменьшился до 197 МБ.
Perl: заменяем активацию системы
Perl в образе нужен только для скриптов активации: настройки /etc и создания пользователей. В nixpkgs уже есть экспериментальные замены — system.etc.overlay и нативный менеджер пользователей userborn.
Оба механизма помечены как экспериментальные, но в контексте «самодельного минимального ISO» это уже не самая безумная идея. Финальный размер: 183 МБ.
Что получилось и стоит ли повторять
За несколько итераций образ сократился с 458 МБ до 183 МБ — почти в 2,5 раза. При этом система всё ещё загружается, автор смог залогиниться под root, правда разрешение экрана перестало переключаться.
Важно: конфигурация выше — это не рецепт для продакшена. Отсутствие Nix, SSH, модулей ядра и Perl-активации ломает массу сценариев. Результат интересен скорее как демонстрация границ NixOS, чем как готовый шаблон.
Автор сама отмечает: для рабочего десктопа или сервера так делать не стоит. Но если вам нужен крошечный live-образ под единичный эксперимент — здесь много идей, с которых можно начать.
Часто задаваемые вопросы
Почему базовый NixOS ISO такой большой?
Потому что в него вкладывается почти всё пользовательское окружение: systemd, Python, Perl, GRUB, модули ядра, документация и сам Nix. В отличие от Alpine, NixOS не стремится к минимализму по умолчанию.
Можно ли уменьшить ISO ещё сильнее?
Да, но это потребует более глубокой работы. Автор указывает на дублирование systemdMinimal и systemd, а также множество мелких зависимостей, которые можно вычищать вручную.
Безопасно ли использовать userborn и etc overlay?
Это экспериментальные функции nixpkgs. Для игрушечного ISO — приемлемо, для продакшена стоит дождаться стабилизации и протестировать восстановление после сбоев.
Почему нельзя просто взять Alpine вместо NixOS?
Alpine меньше, но у NixOS другая философия: декларативная конфигурация, воспроизводимые сборки и атомарные откаты. Выбор зависит от задачи, а не только от размера.
Выводы
Эксперимент показывает, что NixOS позволяет не только собирать сложные системы, но и жёстко урезать их — иногда в ущерб удобству. Главный инструмент здесь не волшебная опция, а последовательный анализ: смотреть, что занимает место, находить виновника через nix why-depends и решать, готовы ли вы от него отказаться.
«At some point I just kept going because I got curious.»
Если захотите повторить — начните с отключения Nix и документации, а дальше решайте, какие модули и пакеты действительно нужны в вашем live-образе. Исходный материал — в блоге автора: I can haz smoller NixOS ISOs?.