Эта статья является прямым продолжением этой статьи, посвящённой декларативной разметке диска через disko.
Что мы будем делать сегодня?
Мы с вами составим минимально‑рабочий конфиг для нашей системы. Под «минимально‑рабочим» я имею в виду: без графического окружения(XFCE, GNOME и прочее), углублённых настроек(установка zsh, например). Всё это будет в другом материале, который я посвящу райсированию NixOs через home‑manager, а также прочим прикладным моментам: поиску пакетов, настроек в nix‑формате и прочему.
Что у нас будет в конфиге?
Рабочий загрузчик(systemd‑boot или GRUB — я приведу оба)
Настойка сети(имя хоста, включение networkmanager и фаерволла)
Локализация: часовой пояс и язык
Настройка звука
Настройка пользователя
Установка наиболее важных на первое время системных пакетов(vim, git, curl, wget)
Прежде чем начать!
Сейчас наступает тот самый момент, когда мы начинаем сталкиваться с Никсой вживую, поэтому, прежде чем продолжить, я бы порекомендовал вам попробовать пройти этот тур по языку Nix: https://nixcloud.io/tour/.
Вы наверняка уже знаете, что вся конфигурация нашей системы представляет из себя файлы, которые написаны на этом языке, а потому его знание(хоть и не является жизненно важным) существенно облегчит вам работу. Не пожалейте двух‑трёх часов, которые сэкономят вам время на понимание в будущем, особенно когда мы коснёмся флейков.
Каково положение дел на данный момент? Как я и говорил в предисловии, эта статья является продолжением статьи про разметку диска, а это значит, что у нас уже есть полностью размеченный диск, а в папке /tmp сейчас лежит disko-config.nix(не зря мы его туда спрятали).
1. Генерируем файл конфигурации
Сразу после окончания разметки диска нам нужно создать директорию /mnt/etc/nixos, где и будут храниться ВСЕ наши файлы конфигурации: configuration.nix и disko-config.nix:
$ sudo mkdir -p /mnt/etc/nixos
А затем скопировать наш disko-config.nix в эту директорию и самим перейти в неё:
$ sudo cp /tmp/disko-config.nix /mnt/etc/nixos $ cd /mnt/etc/nixos
А теперь сгенерируем configuration.nix:
$ sudo nixos-generate-config --no-filesystems --root /mnt writing /mnt/etc/nixos/hardware-configuration.nix... writing /mnt/etc/nixos/configuration.nix... For more hardware-specific settings, see https://github.com.
Теперь в нашей папке появилось два новых файла:
configuraton.nix— основной файл настроек операционной системы. Именно в нём настраиваются пользователи, пакеты, сетевые службы и графическое окружение.hardware-configuration.nix— файл с параметрами нашего железа. Автоматически подключает нужные модули ядра и файловую систему(НЕ В НАШЕМ СЛУЧАЕ!)
Но перед тем, как приступить непосредственно к ним, давайте разберём, как работает команда nixos-generate-config и что она только что сделала:
nixos-generate-config— Она сканирует текущее железо компьютера(процессор, видеокарту, сетевые адаптеры) и подключенные диски, чтобы автоматически создать базовые файлы конфигурации для новой ОС.--no-filesystems— специальный флаг, который приказывает утилите пропустить этап сканирования дисковых разделов и точек монтирования. Он отключает генерацию блоков с UUID файловых систем, чтобы они не дублировали настройки нашегоdisko-config.nix. Именно благодаря нейhardware-configuration.nixне содержит информацию о диске, к нашему счастью.--root /mnt— указывает утилите, куда именно нужно сохранить сгенерированные файлы. По умолчанию она пытается писать в корневую папку текущей системы(/etc/nixos/), но поскольку мы сидим в live‑образе, нам нужно сохранить конфиги на наш настоящий жесткий диск, который сейчас смонтирован внутри папки/mnt. В итоге файлы записываются по пути/mnt/etc/nixos/.
Вот, как выглядит hardware-configuration.nix у меня. у вас, в зависимости от вашего железа, он будет выглядеть по‑другому. Файл этот не стоит редактировать, если вы не знаете, что делаете:
# Do not modify this file! It was generated by ‘nixos-generate-config’ # and may be overwritten by future invocations. Please make changes # to /etc/nixos/configuration.nix instead. { config, lib, pkgs, modulesPath, ... }: { imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ]; boot.initrd.kernelModules = [ "dm-snapshot" ]; boot.kernelModules = [ "kvm-intel" ]; boot.extraModulePackages = [ ]; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; }
Немного оффтопа: Вообще, настройка железа в NixOs — это отдельная тема. Некоторые юзеры(включая меня) и вовсе удаляют
hardware-configuration.nix, так как настраивают всё по‑своему. В этом нет ничего страшного и в какой‑нибудь другой статье, может быть, мы поговорим о настройке системы под железо поподробнее.
2. Структура configuration.nix
Давайте взглянем, как выглядит сам «необработанный» configuration.nix после nixos-generate-config:
# Edit this configuration file to define what should be installed on # your system. Help is available in the configuration.nix(5) man page, on # https://search.nixos.org/options and in the NixOS manual (`nixos-help`). { config, lib, pkgs, ... }: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix ]; # Use the systemd-boot EFI boot loader. boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; # networking.hostName = "nixos"; # Define your hostname. # Configure network connections interactively with nmcli or nmtui. networking.networkmanager.enable = true; # Set your time zone. # time.timeZone = "Europe/Amsterdam"; # Configure network proxy if necessary # networking.proxy.default = "http://user:password@proxy:port/"; # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; # Select internationalisation properties. # i18n.defaultLocale = "en_US.UTF-8"; # console = { # font = "Lat2-Terminus16"; # keyMap = "us"; # useXkbConfig = true; # use xkb.options in tty. # }; # Enable the X11 windowing system. # services.xserver.enable = true; # Configure keymap in X11 # services.xserver.xkb.layout = "us"; # services.xserver.xkb.options = "eurosign:e,caps:escape"; # Enable CUPS to print documents. # services.printing.enable = true; # Enable sound. # services.pulseaudio.enable = true; # OR # services.pipewire = { # enable = true; # pulse.enable = true; # }; # Enable touchpad support (enabled default in most desktopManager). # services.libinput.enable = true; # Define a user account. Don't forget to set a password with ‘passwd’. # users.users.alice = { # isNormalUser = true; # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. # packages = with pkgs; [ # tree # ]; # }; # programs.firefox.enable = true; # List packages installed in system profile. # You can use https://search.nixos.org/ to find more packages (and options). # environment.systemPackages = with pkgs; [ # vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. # wget # ]; # Some programs need SUID wrappers, can be configured further or are # started in user sessions. # programs.mtr.enable = true; # programs.gnupg.agent = { # enable = true; # enableSSHSupport = true; # }; # List services that you want to enable: # Enable the OpenSSH daemon. # services.openssh.enable = true; # Open ports in the firewall. # networking.firewall.allowedTCPPorts = [ ... ]; # networking.firewall.allowedUDPPorts = [ ... ]; # Or disable the firewall altogether. # networking.firewall.enable = false; # Copy the NixOS configuration file and link it from the resulting system # (/run/current-system/configuration.nix). This is useful in case you # accidentally delete configuration.nix. # system.copySystemConfiguration = true; # This option defines the first version of NixOS you have installed on this particular machine, # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions. # # Most users should NEVER change this value after the initial install, for any reason, # even if you've upgraded your system to a new NixOS release. # # This value does NOT affect the Nixpkgs version your packages and OS are pulled from, # so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how # to actually do that. # # This value being lower than the current NixOS release does NOT mean your system is # out of date, out of support, or vulnerable. # # Do NOT change this value unless you have manually inspected all the changes it would make to your configuration, # and migrated your data accordingly. # # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . system.stateVersion = "26.05"; # Did you read the comment? }
Как видите, разработчики уже позаботились о нас и закомментировали большую часть всего того, что нам нужно, чтобы мы могли просто убрать решётку с нужных нам параметров. Чтобы нам было легче работать, я удалю ненужную справочную информацию и получу такой конфиг(вам этого делать не обязательно, я делаю это только из удобства):
{ config, lib, pkgs, ... }: { imports = [ ./hardware-configuration.nix ./disko-config.nix # ОБЯЗАТЕЛЬНО УКАЖИТЕ ЭТОТ ФАЙЛ! ]; # --- 1. ЗАГРУЗЧИК(мне по дефолту дало systemd-boot) --- boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; # --- 2. НАСТРОЙКА СЕТИ --- # networking.hostName = "nixos"; # networking.firewall.enable = false; networking.networkmanager.enable = true; # --- 3. ЛОКАЛИЗАЦИЯ: ВРЕМЯ И ЯЗЫК --- # time.timeZone = "Europe/Amsterdam"; # i18n.defaultLocale = "en_US.UTF-8"; # --- 4. ЗВУК --- # services.pulseaudio.enable = true; # # services.pipewire = { # enable = true; # pulse.enable = true; # }; # --- 5. ТАЧПАД --- # services.libinput.enable = true; # --- 6. ПОЛЬЗОВАТЕЛЬ --- # users.users.alice = { # isNormalUser = true; # extraGroups = [ "wheel" ]; # packages = with pkgs; [ # tree # ]; # }; # --- 7. СИСТЕМНЫЕ ПАКЕТЫ --- # environment.systemPackages = with pkgs; [ # vim # wget # ]; # --- НЕ ТРОГАТЬ НИ В КОЕМ СЛУЧАЕ(расскажу в конце)! --- system.stateVersion = "26.05"; }
Уже не так устрашающе, правда? Понимаю, что у вас сейчас есть вопросы по типу «что за { config, lib, pkgs, ... }: {}?» или «что за with pkgs?». Всё это мы сейчас обсудим.
Но упомяну, что внутри imports = [ ... ]; находятся ссылки на другие файлы нашей конфигурации. Иными словами, мы можем раздробить наш configuration.nix на разные файлы ради удобства boot.nix, networking.nix и тд. Скажу даже больше — так НУЖНО делать.
В NixOs каждый файл конфигурации — это не статичный текст(наподобие .conf или .yaml), а функция, написанная на языке Nix. И каждая функция имеет следующую структуру:
{ параметр_1, параметр_2, параметр_3, ... }: { /* Тело функции - наши настройки */ }
На что это похоже? Правильно, на структуру нашей конфигурации:
{ config, lib, pkgs, ... }: { /* Настройки загрузчика, сети, юзера и прочее */ }
Как я и говорил, вся наша конфигурация представляет из себя код на языке программирования Nix.
То есть:
{ config, lib, pkgs, ...}: {} — это ФУНКЦИЯ, а config, pkgs, lib и ... — это её параметры. А сами настройки загрузчика сети и прочего, что прячется между последних фигурных скобок — это тело функции.
Что такое config, pkgs, lib и ...?
-
pkgs(Packages)Это ваш главный склад, где лежат абсолютно все приложения, драйверы и утилиты, доступные в репозитории
nixpkgs.Пример в коде:
environment.systemPackages = [ pkgs.git pkgs.curl pkgs.vscode ]; -
config(Configuration)Это объект, который содержит текущие значения всех настроек системы, служб и пакетов. NixOS собирает настройки из всех ваших файлов в один большой клубок, и через
configвы можете посмотреть, что настроено в других местах.Пример в коде: «если на компьютере включен Wi‑Fi, то автоматически установи утилиту для сканирования сетей»:
environment.systemPackages = if config.networking.wireless.enable then [ pkgs.wirelesstools ] else [ ]; -
lib(Library)Это встроенная библиотека полезных функций Nix. Сам по себе язык Nix довольно лаконичен, поэтому
libдобавляет в него логику: работу со строками, списками и условиями.Пример в коде: Функция
lib.mkIfпозволяет применить ту или иную настройку только при определенном условии:{ config, lib, pkgs, ... }: { # 1. Включаем драйвер Nvidia hardware.nvidia.modesetting.enable = true; # 2. Устанавливаем Steam, ТОЛЬКО ЕСЛИ включена Nvidia programs.steam.enable = lib.mkIf config.hardware.nvidia.modesetting.enable true; } -
...(Многоточие)Этот параметр нужен для того, чтобы принимать любые дополнительные аргументы, которые система передает файлу конфигурации, даже если они не указаны явно.
Все конфигурационные файлы NixOs написаны по этой структуре, кроме(единственное исключение) флейка. Но об этом в другой раз.
Конфигурируем configuration.nix
-
Настройка загрузчика — как поставить systemd‑boot и grub?
Рассуждать или спорить о том, какой загрузчик лучше, я не буду, как и отдельно объяснять, за что отвечает та или иная строка в systemd‑boot я не стану, обойдусь обычными комментариями, так как там всё предельно просто:
/* --- SYSTEMD-BOOT --- */ # Включение systemd-boot boot.loader.systemd-boot.enable = true; # Разрешение для NixOS изменять переменные EFI boot.loader.efi.canTouchEfiVariables = true;Или вариант для GRUB. Вот его мы построчно и разберём:
/* --- GRUB --- */ boot.loader.grub = { enable = true; efiSupport = true; device = "nodev"; }; boot.loader.efi.canTouchEfiVariables = true;boot.loader.grub.enable = true;— активирует загрузчик GRUB. NixOS понимает, что при сборке системы нужно скомпилировать GRUB, создать его конфигурационные файлы и сделать его главным загрузчиком по умолчанию.boot.loader.grub.efiSupport = true;— включает компиляцию GRUB с поддержкой архитектуры UEFI. Без этой строки GRUB попытается собраться для старого режима BIOS(Legacy), что может привести к ошибкам на современном ПК.boot.loader.grub.device = "nodev";— Буквально означает «нет устройства»(nodev → no device). В старом режиме BIOS нужно было жестко указывать диск для установки загрузочного сектора(например,/dev/sda). В режиме UEFI загрузчик устанавливается не в сектор диска, а в виде обычного файла на специальный EFI‑раздел. Значение"nodev"указывает GRUB, что не нужно искать конкретный диск, а следует просто скопировать файлы в общую EFI‑папку.boot.loader.efi.canTouchEfiVariables = true;— разрешает операционной системе NixOS изменять настройки внутри энергонезависимой памяти материнской платы(NVRAM). Знаю, что не особо понятно, но крайне рекомендую оставить это как есть, особенно если у вас современный ноутбук/ПК.
Мой фаворит — GRUB, так что я буду ставить систему через него. Вы же можете поставить systemd‑boot, сути это вообще никак не поменяет.
-
Настройка сети
networking.hostName = "nixoshostname"; networking.networkmanager.enable = true; networking.firewall.enable = true; /* НЕОБЯЗАТЕЛЬНО! Встроенный iptables можно заменить на nftables Просто добавьте в конфигурацию эту строчку: */ # networking.nftables.enable = true;networking.hostName = "nixoshostname";— это имя нашего хоста. Так как это гайд, я выбралnixoshostname, вы же можете поставить, что душе угодно.networking.networkmanager.enable = true;— включает в NixOS службу NetworkManager для управления сетевыми подключениями.networking.firewall.enable = true;— это активация встроенного фаерволла. По умолчанию в NixOS работает встроенный, основанный наiptables.networking.nftables.enable = true;— заменяет встроенный в NixOs фаерволл на nftables. Я никогда последним не пользовался, поэтому порекомендовать его не могу. Оставляйте на своё усмотрение. Я его включать не буду.
-
Локализация
time.timeZone = "Europe/Moscow"; # Часовой пояс i18n.defaultLocale = "ru_RU.UTF-8"; # Системный язык(интерфейс программ, консольные утилиты и прочее) -
Настройка звука
Ни для кого ни секрет, что в мире Linux существует два звуковых сервера: pulseaudio и pipewire. В большинстве случаев нужно ставить PipeWire и вам, я уверен, тоже. PulseAudio используют только на очень старых или слабых ПК, либо при специфических проблемах совместимости.
Сам я с pulseaudio никогда не работал и всю свою жизнь даже на своём двенадцатилетнем стареньком Lenovo всегда использовал pipewire.
-
Тачпад
services.libinput.enable = true;Libinput — это библиотека, используемая для обработки ввода с устройств периферии в операционных системах на базе Linux: мышки, тачпада и тд. Если вы пользуетесь ноутбуком, то активация этой библиотеки ОБЯЗАТЕЛЬНА!
Немного оффтопа: у некоторых вендоров(привет, Honor), чьи ноутбуки официально не расчитаны на линукс, могут быть проблемы с тачпадами. У меня он просто может выключиться в определённый момент(происходит не часто, раз в неделю‑две, иногда даже в месяц, но всё равно неприятно). Просто поделился опытом, не более. Если смогу разобраться с проблемой, обязательно сделаю отдельный пост на эту тему. Также буду рад почитать комментарии на этот счёт.
-
Пользователь
Здесь нам нужно выбрать имя для нашего юзера, а затем его в группу «wheel», чтобы у него был доступ к sudo, и в группу «networkmanager», чтобы мы могли управлять сетевыми подключениями без sudo.
users.users.alice = { # Поменяйте alice на своё имя, а я оставлю как есть isNormalUser = true; # Указывает, что это профиль человека, а не службы extraGroups = [ "wheel" "networkmanager"]; # Группы пользователя packages = with pkgs; [ cowsay ]; };users.users.alice.packagesнужен, чтобы установить пакеты, доступные конкретному пользователю. Иными словами, если в нашей системе появится и другой пользователь(условно «ivan»), то воспользоваться утилитойcowsay, которую мы установили для «alice», он не сможет(терминал просто выведет command not found). -
Установка системных пакетов
Вот список того, что нам понадобится после установки. Не волнуйтесь, в будущем вы в любой момент сможете добавить нужные пакеты или убрать их:
environment.systemPackages = with pkgs; [ vim git curl wget ];Что здесь происходит?
environment.systemPackages— это системный параметр NixOS(список). Все пакеты, указанные в нем, будут установлены глобально и станут доступны всем пользователям в терминале.= [ ... ];— знак равенства присваивает список(в Nix списки берутся в квадратные скобки[]) этому параметру. Строка ОБЯЗАТЕЛЬНО завершается точкой с запятой.with pkgs;— это языковая конструкция, которая временно открывает доступ к содержимому набораpkgs. Если вы уже имели дело с языком Nix, то понимаете, что происходит.
Зачем здесь нужен
with pkgs? Удобство, не более, чтобы перед каждым пакетом нам не приходилось писать приставкуpkgs.<название_пакета>:# Если убрать with pkgs: environment.systemPackages = [ pkgs.vim pkgs.git pkgs.curl pkgs.wget ];Что такое
pkgs?pkgs— это огромный склад всех программ, утилит и библиотек, которые умеет устанавливать NixOs. Только хранит он не сами программы, а инструкции по сборке софта(деривации) для нашей с вами NixOs. В этих инструкциях написано: откуда скачать исходный код программы, какими компиляторами его собрать и какие зависимости ему нужны. Берёт же он всё это добро из из официального репозитория Nixpkgs, который поддерживают тысячи людей.Тут можно было бы упомянуть механизм каналов, рассказать про стабильный и нестабильный канал, но я этого делать не буду, так как каналы — это уже устаревшая и вытесняемая флейками вещь, которую вы даже использовать не будете. Поверьте, это очень хорошо, и я в статье про флейки расскажу, почему.
3. Финальная конфигурация
Итого после всего, что я понавытворял, у меня получился такой configuration.nix:
{ config, lib, pkgs, ... }: { imports = [ ./hardware-configuration.nix ]; # --- 1. ЗАГРУЗЧИК(GRUB) --- boot.loader.grub = { enable = true; efiSupport = true; device = "nodev"; }; boot.loader.efi.canTouchEfiVariables = true; # --- 2. НАСТРОЙКА СЕТИ --- # networking.hostName = "nixos"; networking.networkmanager.enable = true; # --- 3. ЛОКАЛИЗАЦИЯ: ВРЕМЯ И ЯЗЫК --- time.timeZone = "Europe/Moscow"; i18n.defaultLocale = "ru_RU.UTF-8"; i18n.supportedLocales = [ "ru_RU.UTF-8/UTF-8" "en_US.UTF-8/UTF-8" ]; console = { font = "cyr-sun16"; keyMap = "ru"; }; # --- 4. ЗВУК --- security.rtkit.enable = true; services.pipewire = { enable = true; alsa.enable = true; alsa.support32Bit = true; pulse.enable = true; }; # --- 5. ТАЧПАД --- services.libinput.enable = true; # --- 6. ПОЛЬЗОВАТЕЛЬ --- users.users.alice = { isNormalUser = true; extraGroups = [ "wheel" "networkmanager"]; packages = with pkgs; [ cowsay ]; }; # --- 7. СИСТЕМНЫЕ ПАКЕТЫ --- environment.systemPackages = [ pkgs.vim pkgs.git pkgs.curl pkgs.wget ]; # --- НЕ ТРОГАТЬ НИ В КОЕМ СЛУЧАЕ! --- system.stateVersion = "26.05"; }
Что такое system.stateVersion = "26.05"; и почему его нельзя убирать или менять? (выдержка из MyNixos)
Эта опция определяет первую версию NixOS, которую вы установили на этой конкретной машине, и используется для поддержания совместимости с данными приложений (например, базами данных), созданными на старых версиях NixOS.
Источник: https://mynixos.com/nixpkgs/option/system.stateVersion
Представьте, что вы построили дом в 2024 году. Программы в NixOS смотрят на этот параметр и думают: «Ага, этот дом построен в 24-м году, значит, ключи от подвала лежат на старом месте, а трубы подключены по старым правилам».
Если вы обновите саму систему(скачаете новые программы), ваш дом обновится. Но если вы вручную измените stateVersion на "26.05", вы обманете систему. Программа подумает: «О, этот дом построен в 2026 году по новым чертежам!» — и пойдет искать ключи и трубы там, где у вас их никогда не было. В итоге программа просто не запустится.
Что нужно запомнить:
ЭТО НЕ ВЕРСИЯ ВАШИХ ПРОГРАММ: Вы можете обновлять NixOS до самых свежих версий, иметь самый новый софт и ядро. Параметр
stateVersionпри этом трогать НЕ НУЖНО. Он остается старым.Что будет, если изменить: Сломаются базы данных, изменятся права доступа к некоторым папкам, и система может выдать ошибку.
Лучшее, что вы можете сделать: просто забудьте про эту строчку в файле
configuration.nix. Она должна оставаться точно такой же, какой была в день, когда вы впервые установили NixOS на свой ПК.
Финал — Устанавливаем систему
Остались сущие мелочи. Просто запустите эту команду через sudo:
sudo nixos-install
В конце не забудьте поменять пароль для рута через passwd. После этого сделайте ребут:
reboot
Дальше отключите флешку, а после захода поменяйте пароль, используя passwd <имя_пользователя>, для пользователя, которого мы создали в пункте 6(в моём случае — alice)
Послесловие
На данный момент положение дел таково, у нас есть:
Декларативно размеченный диск.
Декларативно настроенная и установленная операционная система.
Разумеется, ни графического интерфейса, ни прикладных программ по типу браузера у нас сейчас нет. Да и настройку мы полностью не закончили. В следующем материале мы разберёмся с флейками, переведём нашу систему на полностью декларативный и воспроизводимый формат и избавим себя от необходимости каждый раз писать sudo, чтобы что‑то изменить в configuration.nix
baalmef
Недолгая у вас была линукс-жизнь, да и двенадцатилетний Lenovo явно не всю свою жизни работал на PipeWire, которому лет девять только, а массово внедряться в популярных дистрибутивах его начали лишь несколько лет назад.
Т. к. статья снова без нормальной атрибуции, уточню для тех, кто не сталкивался с NixOS, но хотел бы с ней познакомиться: здесь описан специфический ручной вариант установки системы, обычно всё делается куда проще через стандартный графический установщик, и уже в установленной системе можно будет спокойно разбираться с её конфигами.
unreal_undead2
Да, вспоминаю времена когда ожидалось, что alsa решит все проблемы oss...