1. Философия Nix: Почему декларативный подход меняет всё
Философия Nix: Почему декларативный подход меняет всё
Вы решили обновить библиотеку для одного пет-проекта. Пакетный менеджер скачивает новую версию, попутно обновляя пару системных зависимостей. Проект запускается отлично. Но на следующий день вы открываете свой основной рабочий инструмент, а он падает с ошибкой: «version GLIBC_2.34 not found». Вы пытаетесь откатить обновление, но система сообщает, что это сломает графическое окружение. Добро пожаловать в «ад зависимостей» — фундаментальную проблему традиционных операционных систем, которую NixOS решает на архитектурном уровне.
Чтобы понять, как построить по-настоящему надежную рабочую станцию, нам нужно разобраться, почему ломаются обычные системы и как философия Nix меняет правила игры.
Глобальное изменяемое состояние: корень всех зол
Традиционные дистрибутивы Linux (Ubuntu, Arch, Fedora) работают по стандарту иерархии файловой системы (FHS). Это значит, что в системе есть глобальные директории: /bin для программ, /lib для библиотек, /etc для конфигураций.
Когда вы выполняете команду apt install nodejs, пакетный менеджер распаковывает файлы прямо в эти глобальные директории. Если двум разным программам нужны разные версии одной и той же библиотеки (например, OpenSSL 1.1 и OpenSSL 3.0), возникает конфликт. В глобальной папке /lib может лежать только один файл с конкретным именем.
Такая модель называется императивной. Вы управляете системой, отдавая ей последовательность команд: установи это, удали то, измени эту строчку в конфиге.
Проблема императивного подхода в том, что текущее состояние вашей ОС — это сумма всех команд, которые вы выполнили с момента установки. Если вы купите новый ноутбук, вы не сможете в точности воссоздать свою среду, пока не вспомните и не повторите каждую команду в правильном порядке.
Декларативный подход: от рецепта к меню
NixOS предлагает совершенно иную парадигму — декларативную.
Вместо того чтобы писать скрипты или вводить команды, шаг за шагом меняющие систему, вы описываете желаемое конечное состояние в одном конфигурационном файле. Вы говорите системе: «Мне нужен включенный SSH, браузер Firefox, Docker и таймзона Берлина». Как именно система к этому придет — задача пакетного менеджера Nix.
| Особенность | Императивный подход (Ubuntu, Arch) | Декларативный подход (NixOS) |
| :--- | :--- | :--- |
| Управление | Выполнение команд во времени (apt, pacman, rm, sed) | Описание желаемого состояния в текстовом файле |
| Воспроизводимость | Низкая (зависит от истории действий пользователя) | Абсолютная (один конфиг = один результат на любой машине) |
| Разрешение конфликтов | Ручное, часто через контейнеры (Docker) или виртуальные окружения | Встроенное на уровне файловой системы |
| Откат изменений | Сложен, часто требует бэкапов файловой системы (Timeshift, Btrfs snapshots) | Мгновенный, встроен в архитектуру ОС |
Декларативность сама по себе не нова (вспомните Ansible или Terraform), но NixOS уникальна тем, как глубоко эта концепция интегрирована в ядро системы. Это становится возможным благодаря особому хранилищу.
Анатомия чистоты: Как устроен /nix/store
Чтобы декларативный подход работал, NixOS полностью отказывается от стандарта FHS. В NixOS нет привычных директорий /bin или /lib. Вместо этого абсолютно всё — программы, библиотеки, конфигурационные файлы — хранится в едином месте: /nix/store.
Каждый объект в /nix/store лежит в собственной директории, имя которой начинается с криптографического хеша.
Например, путь к Python может выглядеть так:
/nix/store/8n5z4...-python3-3.11.5/bin/python
Откуда берется этот хеш? Это не просто случайный набор символов. Хеш вычисляется на основе всех входных данных, необходимых для сборки этого пакета:
Если изменится хотя бы один байт в исходном коде или обновится зависимость — изменится хеш. А значит, пакет будет установлен в совершенно новую директорию в /nix/store.
!Структура /nix/store и разрешение конфликтов зависимостей
Этот механизм элегантно решает проблему «ада зависимостей». Если Программе А нужен OpenSSL 1.1, а Программе Б — OpenSSL 3.0, Nix просто скачает обе версии в разные директории с разными хешами. Программы будут жестко ссылаться (через абсолютные пути) только на свои версии библиотек. Они никогда не пересекутся и не сломают друг друга.
!Что происходит при обновлении пакета в NixOS
Неизменяемость и поколения (Generations)
Важнейшее свойство /nix/store — неизменяемость (immutability). Как только пакет собран и помещен в хранилище, его файлы становятся доступны только для чтения. Ни пользователь, ни программы не могут их изменить.
Но если всё неизменяемо, как обновлять систему?
В NixOS вы не обновляете систему «на месте». Когда вы меняете конфигурационный файл и просите систему применить изменения, Nix:
/nix/store.Текущее состояние вашей операционной системы — это просто символическая ссылка (symlink), которая указывает на конкретное поколение в /nix/store. Обновление системы — это атомарная операция: Nix просто переключает один симлинк со старого поколения на новое.
!Процесс переключения поколений и отката
Поскольку старые файлы в /nix/store не перезаписываются и не удаляются (пока вы сами не запустите сборщика мусора), предыдущее поколение остается полностью целым и работоспособным.
Если после обновления у вас не загружается графический интерфейс или отвалился Wi-Fi, вам не нужно искать логи и пытаться откатить пакеты. Вы просто перезагружаете компьютер, в меню загрузчика (GRUB/systemd-boot) выбираете предыдущее поколение, и система загружается ровно в том состоянии, в котором была до обновления. Это дает невероятную свободу: вы можете смело экспериментировать с настройками, зная, что систему невозможно сломать безвозвратно.
Что это значит для разработчика?
Для повседневной разработки декларативный подход NixOS означает конец эпохи «работает на моей машине».
Ваша рабочая станция становится полностью детерминированной. Конфигурационный файл — это единый источник истины. Вы можете выложить его на GitHub, скачать на новый ноутбук, запустить одну команду — и через 10 минут получить точную копию своей системы: с теми же версиями компиляторов, теми же настройками IDE и теми же утилитами командной строки.
В следующих главах мы разберем, как именно выглядит этот конфигурационный файл, как Nix собирает из него поколения и как написать свои первые декларативные правила для идеального рабочего окружения.