NixOS - это дистрибутив Linux с декларативной конфигурацией. Вы можете один раз описать все настройки системы в конфигурационном файле, а затем развернуть аналогичную конфигурацию на другом компьютере несколькими командами. Настраивается почти всё: установленные программы, параметры этих программ, Firewall и даже графическое окружение. Поэтому это неплохой выбор для домашнего сервера и Raspberry Pi.
В этой статье мы рассмотрим, как установить NixOS на Raspberry Pi 4 без подключения монитора. Я покажу, как записать ОС на SD-карту так, чтобы, вставив её в Raspberry Pi, можно было загрузиться и сразу подключиться к мини-компьютеру по SSH.
Содержание статьи
Как это будет работать?
Самый простой способ установить NixOS на Raspberry Pi - воспользоваться образом SD Image, который можно загрузить из сервиса сборки NixOS под названием Hydra. Этот образ содержит всё необходимое, а также имеет включённый по умолчанию SSH-сервер. Для того чтобы к нему можно было подключиться, нужно только добавить свой SSH-ключ.
После установки рассмотрим минимальную настройку для использования Raspberry Pi в качестве сервера. Рассмотрим, как создать пользователя, установить Docker и некоторые дополнительные полезные программы.
Установка NixOS на Raspberry Pi 4
Шаг 1. Загрузка образа SD Image
Откройте сайт Hydra и перейдите на страницу самого свежего релиза:
Далее перейдите на вкладку Jobs и введите в поиске sd_image:
Для Raspberry Pi требуется архитектура aarch64. Перейдите на страницу образа и выберите самую свежую успешную сборку:
Остается загрузить zst-архив по ссылке:
Теперь можно переходить к записи. Или то же самое можно сделать с помощью команды wget. Загрузка может занять много времени, а использовав команду, вы сможете перезапустить загрузку, если соединение разорвется:
wget https://hydra.nixos.org/build/342779548/download/1/nixos-image-sd-card-26.05.8111.5880666fd9eb-aarch64-linux.img.zst
И для продолжения:
wget -c https://hydra.nixos.org/build/342779548/download/1/nixos-image-sd-card-26.05.8111.5880666fd9eb-aarch64-linux.img.zst
Шаг 2. Распаковка архива
Теперь нужно распаковать zstd-архив, чтобы получить образ. Для этого выполните команду:
zstd --decompress ~/Downloads/nixos-image-sd-card-26.05.8111.5880666fd9eb-aarch64-linux.img.zst
Шаг 3. Запись образа на SD-карту
Вставьте SD-карту в кард-ридер и подключите его к компьютеру. Для записи можно использовать любую программу, способную записывать образы на флешку. Это может быть BalenaEtcher, UNetbootin, Raspberry Pi Imager, Fedora Media Writer или Rufus в Windows.
В этой инструкции будет использоваться BalenaEtcher. Ее можно установить, загрузив пакет для вашего дистрибутива или архив с исполняемыми файлами со страницы релизов на GitHub. После запуска на первом шаге выберите img-файл образа NixOS:
Далее выберите устройство SD-карты, на которое будет записан этот образ. Для этого воспользуйтесь кнопкой Set Target:
Здесь проще всего ориентироваться по имени файла устройства и размеру:
Нажмите кнопку Flash, подтвердите действие, введите пароль пользователя и дождитесь завершения записи:
Утилита также выполнит верификацию, чтобы убедиться, что все данные записаны корректно. Поэтому, если что-то пойдет не так, вы получите ошибку. Утилита записывает блок с метаданными только после успешной верификации, поэтому при ошибке флешка будет пустой. Иногда такое может случиться при записи на новую SD-карту, если на ней есть битые сектора. Тогда можно выполнить запись еще раз, пропустить верификацию и после этого перезаписать заново.
В качестве альтернативы можно записать образ с помощью утилиты dd. Образ содержит дамп SD-карты с разделами, поэтому записывать его нужно не в файл раздела, а в файл SD-карты. Например, если SD-карта называется /dev/sde, то команда будет выглядеть так:
sudo dd if=~/Downloads/nixos-image-sd-card-26.05.8111.5880666fd9eb-aarch64-linux.img of=/dev/sde bs=1M conv=fsync status=progress
Вот так выглядят записанные разделы:
fdisk -l /dev/sde
Программа запишет только объем, который занимает образ, но при первом запуске система сама расширит корневой раздел, поэтому ничего дополнительно делать не нужно.
Шаг 4. Создание SSH-ключа
Начиная с версии 20.04, выпущенной в 2020 году, в NixOS сервер OpenSSH включен по умолчанию. Но из соображений безопасности образ не имеет пароля по умолчанию. Однако, чтобы авторизоваться в новой системе по SSH, не подключая Raspberry Pi к монитору и клавиатуре, можно добавить свой SSH-ключ. Сначала сгенерируйте ключ в основной системе:
ssh-keygen
При генерации ключа нужно ввести его имя, в данном случае это будет ~/.ssh/id_raspberry, и два раза нажать Enter, чтобы пропустить создание пароля.
Шаг 5. Копирование SSH-ключа
Теперь нужно смонтировать корневой раздел карты памяти в какой-нибудь каталог, например /mnt, и скопировать туда публичный ключ из ранее созданной пары для авторизации по SSH. Для этого выполните следующую команду:
sudo mount /dev/sde2 /mnt
Ключ нужно добавить для пользователя nixos, поскольку это пользователь, который есть в системе по умолчанию. Первая команда создаст папку пользователя, а вторая скопирует ключ:
sudo mkdir -p /mnt/home/nixos/.ssh
cat ~/.ssh/id_raspberry.pub | sudo tee -a /mnt/home/nixos/.ssh/authorized_keys
После этого можно размонтировать карту памяти, отключить для нее питание и извлечь из компьютера:
sudo umount /dev/sde2
udisksctl power-off -b /dev/sde
Шаг 6. Загрузка Raspberry Pi
Вставьте карту памяти в Raspberry Pi, подключите интернет-кабель и шнур питания. Дождитесь, пока устройство загрузится. Если индикатор питания светится, а индикаторы активности и интернета мигают, скорее всего, всё работает и можно попробовать подключиться по SSH. Но для этого нужно найти устройство. Самый простой способ сделать это - посмотреть список подключенных устройств в вашем роутере:
Или можно просканировать локальную сеть с помощью Nmap:
nmap -sT 192.168.1.1/24
В моём случае Raspberry Pi получил IP-адрес 192.168.1.104.
Шаг 7. Подключение по SSH
Для подключения необходимо выполнить следующую команду. Причём файл ключа шифрования следует указать явно, потому что, если у вас несколько ключей, SSH-клиент может выбрать не тот:
ssh -i ~/.ssh/id_raspberry nixos@192.168.1.104
Если всё было сделано правильно, то вы успешно авторизуетесь и увидите приглашение ввода пользователя nixos:
Шаг 8. Создание конфигурационного файла
На данном этапе, если у вас есть свой конфигурационный файл NixOS, вы уже можете загрузить его и развернуть. Либо можете продолжить читать статью, выполнить минимально необходимые настройки и создать такой файл.
По умолчанию после развертывания системы из SD-образа конфигурационного файла в каталоге /etc/nixos/ не будет. Для того чтобы его сгенерировать, нужно выполнить следующую команду:
sudo nixos-generate-config
Команда создаст два конфигурационных файла: /etc/nixos/configuration.nix с общей конфигурацией и /etc/nixos/hardware-configuration.nix с настройками, специфичными для конкретного устройства. Все изменения нужно вносить в configuration.nix; содержимое файла hardware-configuration.nix генерируется автоматически, и менять его вручную не рекомендуется.
Теперь можно открыть файл и начать настраивать систему:
sudo vi /etc/nixos/configuration.nix
Кратко рассмотрим, что содержится в этом файле и как этим пользоваться. Сам файл написан на языке программирования Nix. Это функциональный язык программирования, разработанный специально для описания пакетов. Каждый конфигурационный файл может содержать только одно выражение. Выражение может содержать обычные переменные или секции (set), которые помещаются в фигурные скобки. Вот примерный синтаксис таких файлов:
{ argument1, argument2, argument3, ... }:
{
parameter1 = value1;
parameter2 = value2;
parameter3 = value3;
}
В начале файла описаны параметры, которые он должен получить от системы, а также перечислены параметры, которые файл возвращает. Например, файл по умолчанию будет выглядеть вот так:
{ config, lib, pkgs, ... }:
{
imports =
[
./hardware-configuration.nix
];
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
Вот основные секции, которые можно настраивать:
- boot.loader - настройки загрузчика
- networking - настройка компонентов, связанных с сетью
- virtualisation - настройка программ для виртуализации и управления контейнерами
- users - управление пользователями
- services - управление сервисами, которые будут работать в фоне
- programs - управление программами
- environment - общая конфигурация среды, переменных, установленных пакетов.
Просмотреть доступные параметры настроек для определённого пути можно с помощью команды nix-option. Например, так можно посмотреть, что доступно в virtualisation:
nix-option virtualisation
Предупреждение: Не пересобирайте систему, пока мы не завершим настройку. Сейчас система работает на конфигурационном файле, на основе которого был собран образ для SD. Именно там был описан пользователь nixos, от имени которого вы сейчас авторизованы, и всё остальное. Если пересобрать систему сейчас, все сервисы и пользователи, которые были настроены в SD image, исчезнут, и вы, как минимум, не сможете получить к ней доступ по SSH.
Шаг 9. Создание пользователя
Найдите секцию users, она может быть закомментирована, и по примеру пользователя alice добавьте своего пользователя. В моем случае serhii:
users.users.serhii = {
isNormalUser = true;
extraGroups = [ "wheel" "docker" ];
packages = with pkgs; [];
initialPassword = "password";
};
В данном случае добавляется обычный пользователь, который входит в группу wheel, чтобы иметь доступ к команде sudo, а также в группу docker для управления контейнерами. Кроме того, для пользователя задан начальный пароль password. Этот пароль будет применен только один раз при создании пользователя, на последующие пересборки системы это не повлияет.
Шаг 10. Установка необходимых программ
Программы в NixOS добавляются либо с помощью секции environment.systemPackages, либо путем включения отдельных секций сервисов в конфигурационном файле. Чтобы понять, какой способ использовать для каждой конкретной программы, стоит посмотреть документацию для нужной программы на https://search.nixos.org/. Например, введите в поиске htop:
А затем перейдите на вкладку Nix Configuration:
Утилита htop устанавливается через systemPackages, потому что это программа, которую запускает пользователь. Сервисы, которые должны быть запущены в фоне, обычно настраиваются с помощью секции services или других отдельных секций. Например, вот так выглядит документация docker:
Также сведения о настройках, доступных для того или иного сервиса, можно найти в официальной Wiki по NixOS.
Для того чтобы установить htop, vim, wget, docker-compose и несколько других полезных утилит:
environment.systemPackages = with pkgs; [
vim
wget
git
docker-compose
libraspberrypi
usbutils
htop
ncdu
];
Но сам Docker необходимо активировать с помощью отдельной опции конфигурации. Для этого добавьте следующую строку в секцию virtualisation:
virtualisation.docker.enable = true;
Шаг 11. Настройка SSH
Далее, чтобы вы снова могли подключиться к системе по SSH после пересборки, необходимо включить SSH в конфигурационном файле:
services.openssh.enable = true;
А также скопировать SSH-ключ для пользователя, которого вы создали ранее:
sudo mkdir -p /home/serhii/.ssh
sudo cp /home/nixos/.ssh/authorized_keys /home/serhii/.ssh/authorized_keys
Шаг 12. Развертывание конфигурационного файла
Сохраните изменения, и можно разворачивать новый конфигурационный файл. Для этого выполните следующую команду:
sudo nixos-rebuild switch
Система будет пересобрана и сразу же переключится на новую версию. Но поскольку имя пользователя теперь отличается, вам придется выйти из системы и подключиться снова:
exit
ssh -i ~/.ssh/id_raspberry serhii@192.168.1.104
После авторизации нужно также изменить пароль пользователя:
passwd serhii
Здесь необходимо ввести начальный пароль, который ранее вы указали в конфиге, и два раза ввести новый пароль:
При следующей пересборке системы пароли новых пользователей будут задаваться из конфигурационного файла, но уже заданные пароли не изменятся. Теперь у вас есть полностью настроенная система, которую вы можете использовать в качестве сервера или продолжить настраивать под свои задачи.
Выводы
В этой статье мы рассмотрели, как установить NixOS на Raspberry Pi 4, а также как выполнить базовую настройку системы. Теперь у вас есть конфигурационный файл, на основе которого вы можете продолжить настраивать свою систему. Кроме того, всё это можно сделать, не подключая монитор и клавиатуру к Raspberry Pi, что довольно удобно.























