Разбираем эксперимент: отключаем Nix, SSH, GRUB, модули ядра и Perl-активацию. Уменьшаем ISO NixOS почти в 2,5 раза и объясняем, почему это не для продакшена.— Читать дальше «Как я ужал NixOS ISO с 458 МБ до 183 МБ»
Базовый установочный ISO NixOS весит 458 МБ — и в нём даже нет vim. Для сравнения, Alpine Linux укладывается примерно в 66 МБ. Разбираем, как автор блога natkr.com уменьшил NixOS почти в 2,5 раза, и где здесь подвох.
NixOS — это дистрибутив Linux, в котором всё системное окружение описывается декларативно на языке Nix и воспроизводится из одного конфигурационного файла. Каждая сборка помещает зависимости в /nix/store, что даёт атомарные откаты и воспроизводимость, но при этом легко разрастается размер.
Одна из удобных фич — команда nixos-rebuild build-vm: она превращает конфигурацию в виртуальную машину. Но иногда нужен не «тонкий» образ, привязанный к хосту, а самодостаточный ISO, который можно записать на флешку или загрузить в облаке.
Минимальная виртуальная машина на NixOS собирается из файла примерно такого вида:
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";
}
Запуск: $(nix-build basic-vm.nix --attr vm --no-out-link)/bin/run-nixos-vm. При этом /nix/store монтируется с хоста, поэтому VM «тонкая». Для независимого ISO импортируем модуль iso-image.nix и собираем атрибут isoImage:
{
imports = [ "${pkgs.path}/nixos/modules/installer/cd-dvd/iso-image.nix" ];
image.baseName = lib.mkForce "nixos";
}
ISO собирается, загружается в QEMU, но размер сразу бросается в глаза.
Автор примонтировал полученный ISO и посмотрел распределение места. Вот ключевые цифры:
nix-store.squashfs с пользовательским окружением.При распаковке squashfs картина ещё интереснее:
linux-6.18.35-modules).Поскольку ISO собирается локально, все пакеты из него есть и в хостовом /nix/store. Это позволяет использовать nix why-depends, чтобы найти, кто тащит каждую зависимость.
Первый очевидный шаг — отказаться от демона Nix внутри ISO, ведь мы строим автономный образ, а не полноценную NixOS для работы с пакетами. Достаточно двух опций:
{
nix.enable = false;
documentation.enable = false;
}
Результат: 384 МБ. Экономия скромная, потому что часть зависимостей Nix всё ещё тянется через сервис register-nix-paths. Он регистрирует содержимое хранилища ISO при загрузке — но Nix-то мы уже убрали. Отключаем и его:
{
systemd.services.register-nix-paths = lib.mkForce {};
}
Теперь ISO уменьшился до 360 МБ, а зависимость от Boost исчезла полностью.
Следующий кандидат на удаление — OpenSSH-клиент. Проблема в том, что модуль programs/ssh.nix добавляет его в environment.corePackages, а отдельного переключателя programs.ssh.enable нет.
Попытка полностью исключить модуль через disabledModules ломает другие модули, например Plasma 6, которые ожидают существования опций programs.ssh. Выход — подменить опцию «пустышкой», не затрагивающей реальную конфигурацию:
{
imports = [
{
# Заглушка, чтобы другие модули не падали от отсутствия programs.ssh
options.programs.ssh = lib.mkOption {};
}
];
disabledModules = [ "programs/ssh.nix" ];
}
Параллельно автор убрал firewall, documentation.man.enable и принудительно очистил environment.defaultPackages.
ISO-пресет NixOS включает сразу и UEFI-, и BIOS-версии GRUB — отсюда около 62 МБ. Чёткого флага для отключения одной из них нет, поэтому автор пошёл грубым путём: сбросил system.extraDependencies и environment.systemPackages, оставив только environment.corePackages, чтобы shell хотя бы стартовал.
{
environment.systemPackages = lib.mkForce config.environment.corePackages;
system.extraDependencies = lib.mkForce [];
}
Модули ядра весили 144 МБ — больше, чем весь Alpine ISO. NixOS не предоставляет удобного способа ограничить их набор для runtime, поэтому автор просто удалил папку модулей из системы после сборки:
{
system.systemBuilderCommands = lib.mkAfter "rm $out/kernel-modules";
}
Это полностью отключает динамическую загрузку модулей. Если что-то нужно — оно должно оказаться в boot.initrd.kernelModules или availableKernelModules. После этого образ уменьшился до 197 МБ.
Perl в образе нужен только для скриптов активации: настройки /etc и создания пользователей. В nixpkgs уже есть экспериментальные замены — system.etc.overlay и нативный менеджер пользователей userborn.
{
system.etc.overlay.enable = true;
system.etc.overlay.mutable = false;
services.userborn.enable = true;
}
Оба механизма помечены как экспериментальные, но в контексте «самодельного минимального ISO» это уже не самая безумная идея. Финальный размер: 183 МБ.
За несколько итераций образ сократился с 458 МБ до 183 МБ — почти в 2,5 раза. При этом система всё ещё загружается, автор смог залогиниться под root, правда разрешение экрана перестало переключаться.
Важно: конфигурация выше — это не рецепт для продакшена. Отсутствие Nix, SSH, модулей ядра и Perl-активации ломает массу сценариев. Результат интересен скорее как демонстрация границ NixOS, чем как готовый шаблон.
Автор сама отмечает: для рабочего десктопа или сервера так делать не стоит. Но если вам нужен крошечный live-образ под единичный эксперимент — здесь много идей, с которых можно начать.
Часто задаваемые вопросы
1
Почему базовый NixOS ISO такой большой?
Потому что в него вкладывается почти всё пользовательское окружение: systemd, Python, Perl, GRUB, модули ядра, документация и сам Nix. В отличие от Alpine, NixOS не стремится к минимализму по умолчанию.
2
Можно ли уменьшить ISO ещё сильнее?
Да, но это потребует более глубокой работы. Автор указывает на дублирование systemdMinimal и systemd, а также множество мелких зависимостей, которые можно вычищать вручную.
3
Безопасно ли использовать userborn и etc overlay?
Это экспериментальные функции nixpkgs. Для игрушечного ISO — приемлемо, для продакшена стоит дождаться стабилизации и протестировать восстановление после сбоев.
4
Почему нельзя просто взять Alpine вместо NixOS?
Alpine меньше, но у NixOS другая философия: декларативная конфигурация, воспроизводимые сборки и атомарные откаты. Выбор зависит от задачи, а не только от размера.
Эксперимент показывает, что NixOS позволяет не только собирать сложные системы, но и жёстко урезать их — иногда в ущерб удобству. Главный инструмент здесь не волшебная опция, а последовательный анализ: смотреть, что занимает место, находить виновника через nix why-depends и решать, готовы ли вы от него отказаться.
«At some point I just kept going because I got curious.»
Natalie Klestrup Röijezonавтор блога natkr.com
Если захотите повторить — начните с отключения Nix и документации, а дальше решайте, какие модули и пакеты действительно нужны в вашем live-образе. Исходный материал — в блоге автора: I can haz smoller NixOS ISOs?.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | KolibriOS 0.7.7: ОС на ассемблере, которая влезает на дискету | 0 | 5 | 04-07-2026 |
| 2 | Async Rust: как уменьшить бинарник, пока rustc не оптимизирован | 0 | 7 | 29-06-2026 |
| 3 | Как выбрать VPS/VDS под свой проект: гайд по параметрам и 6 провайдеров | 0 | 8 | 30-06-2026 |
| 4 | Аварийное восстановление до аварии: как настроить DRaaS, пока ничего не упал | 5 | 8 | 02-07-2026 |
| 5 | Технический долг в деньгах: как считать ROI рефакторинга легаси-системы | 0 | 7 | 30-06-2026 |
| 6 | VPS vs VDS vs виртуальный хостинг: что выбрать в 2026 году | 0 | 7 | 30-06-2026 |
| 7 | Линус Торвальдс назвал «мерзкой» раскладку файлов sched_ext в Linux — код уже переложили по папкам | -2 | 5 | 26-06-2026 |
| 8 | Горькая правда о Linux на десктопе: Когда старое железо становится приговором | -8 | 6 | 29-06-2026 |
| 9 | Проблемы с очисткой ключей шифрования диска из ОЗУ при переходе Linux в ждущий режим | -2 | 7 | 02-07-2026 |
| 10 | Debian Woody на qemu - не работает горячая смена дисков | -5 | 3 | 13-06-2026 |