Установка Arch Linux на ZFS всегда была не очень тривиальным делом: нужно знать много тонкостей, прочитать кучу статей и различные вики, разобраться с флагами создания датасетов и пула, с конфигурацией initramfs и с тем, какие systemd сервисы стоит включать, с параметрами командной строки ядра и правильными конфигами. Если ставить вручную, то установка занимает целый вечер, с вдумчивым раскуриванием мануалов перед черной консолью. (Небольшой лайфхак: если у вас есть второй компьютер, гораздо приятнее ставить арч с него, подключившись к таргету по ssh, именно из‑за возможности копипастинга команд).
Несколько лет назад я начал работать над автоматизацией этого процесса: написал несколько скриптов на bash, которые делают всё за меня. Это было не очень стабильно: они периодически ломались, гибкостью настройки там и не пахло: скрипт был жёстко прибит к моей конфигурации, и когда кто‑то из друзей просил помочь с установкой Arch Linux на ZFS, обычно я просто делал новую ветку репозитория, подстраивая скрипт под нужную конфигурацию. Всё изменилось зимой прошлого года, когда мне захотелось в очередной раз поставить чистую систему для экспериментов на новый SSD. Я всерьез задумался о новом установщике, который предоставлял бы гибкое меню с конфигурацией в виде TUI. У меня была идея написать инструмент с нуля на Rust, используя ratatui, но масштаб работы для написания гибкого и надёжного проекта, сравнимого по функционалу с archinstall, начал меня немного пугать. Следующей мыслью было попробовать форкнуть archinstall. В процессе чтения его исходного кода и документации я понял: мне не нужно его форкать, я могу использовать его как библиотеку.
Так и родился archinstall_zfs — установщик, который использует archinstall как библиотеку, но при этом переопределяет ключевые компоненты. Я взял от archinstall то, что работает хорошо: TUI компоненты (SelectMenu, EditMenu), систему конфигурации, установку пакетов. Но разметку диска пришлось делать с нуля — archinstall просто не умеет работать с ZFS. Поэтому я написал свой DiskManager, который через sgdisk создаёт нужные разделы, а также GlobalConfigMenu — полностью кастомное меню вместо стандартного. А для самой установки создал ZFSInstaller, который наследует от archinstall.Installer, но умеет работать с ZFS‑специфичными пакетами и конфигурацией.

Получилось именно то, что я хотел: гибкий TUI‑интерфейс, где можно выбрать нужные параметры, а всю грязную работу инструмент сделает сам. Теперь установка Arch на ZFS занимает не вечер с мануалами, а 15–20 минут с чашкой чая.
Но прежде чем рассказывать о возможностях установщика, давайте разберёмся, почему вообще стоит заморачиваться с ZFS.
Почему ZFS?
ZFS — это не просто файловая система, это целая философия управления данными. Представьте, что вы обновили систему, что‑то сломалось, и теперь не загружается графическая оболочка. С обычной файловой системой вы бы лезли за LiveUSB, arch‑chroot, диагностика, исправление неполадок. Либо, если вы новичок, то дело может дойти до переустановки. С ZFS, снэпшотами и ZFSBootMenu вы просто перезагружаетесь, выбираете предыдущее состояние системы из меню и продолжаете работать. А потом спокойно разбираетесь, что пошло не так.
Или другой пример: хотите попробовать Wayland вместо X11? Создаёте клон текущего датасета, загружаетесь в него, экспериментируете. Не понравилось — откатились за секунду. Никаких «ой, а как же вернуть как было».
Кроме того, если у вас есть домашний сервер с ZFS, вы можете отправлять туда инкрементальные снепшоты время от времени
Три режима установки
Я долго думал, какие сценарии установки нужно поддержать. В итоге получилось три основных режима:
1. Full Disk — для тех, кто хочет отдать весь диск под ZFS. Тут я реализовал полную автоматизацию разметки через sgdisk. Установщик сначала очищает GPT и MBR сигнатуры (привет, проблемы с остатками старых разделов!), затем создаёт свежую GPT таблицу и нарезает разделы: EFI‑раздел на 500MB, опционально swap‑раздел в конце диска, а всё остальное — под ZFS.
2. New Pool — для dual‑boot сценариев. У вас уже есть Windows на первой половине диска? Не проблема! Укажите свободный раздел, установщик создаст на нём ZFS pool и установит туда систему. EFI‑раздел можно использовать существующий или создать новый.
3. Existing Pool — моя любимая фича! У вас уже есть ZFS pool с данными или другими системами? Установщик создаст новый boot environment и установит туда свежий Arch, не трогая существующие данные. Идеально для экспериментов и мультибута разных дистрибутивов.

Кто такие эти ваши Boot Environments?
Boot Environments (BE) — это способ держать несколько независимых систем на одном ZFS‑пуле. Каждая система размещается в своём корневом датасете и выбирается при загрузке через ZFSBootMenu. Для мультибута вы можете поставить несколько дистрибутивов в один пул — каждый станет отдельным BE.
Реальный пример с моего ноутбука (с комментариями):
❯ zfs list
NAME USED AVAIL REFER MOUNTPOINT
novafs 1.09T 361G 192K none
# Текущий активный BE "arch0" (контейнер, сам не монтируется)
novafs/arch0 609G 361G 192K none
novafs/arch0/data 421G 361G 192K none
novafs/arch0/data/home 421G 361G 344G /home # /home датасет для arch0
novafs/arch0/data/root 120M 361G 45.3M /root # данные пользователя root текущего BE
novafs/arch0/root 170G 361G 142G / # корневая ФС активного BE
novafs/arch0/vm 18.8G 361G 18.8G /vm # отдельный датасет для VM
# Предыдущий BE "archold" (не активен, но готов к загрузке)
novafs/archold 227G 361G 192K none
novafs/archold/data 143G 361G 192K none
novafs/archold/data/home 141G 361G 119G /home # /home датасет для archold
novafs/archold/data/root 1.81G 361G 1.81G /root # данные root второго BE
novafs/archold/root 83.7G 361G 83.7G / # корень второго BE
# Глобальные датасеты (вне BE, монтируются всеми boot environments)
novafs/tmp_zfs 7.08G 361G 7.08G /tmp_zfs # временные данные
ZFSBootMenu — загрузчик, который понимает ZFS
Забудьте про GRUB с его костылями для ZFS. ZFSBootMenu — это загрузчик, созданный специально для ZFS. В отличие от традиционных загрузчиков, он нативно понимает структуру ZFS и может показывать список boot environments в красивом ncurses‑меню, делать снапшоты и клонировать boot environments прямо при загрузке. Нужно откатиться на снапшот недельной давности? Просто выбираете его из меню, и система загружается именно в том состоянии. Хотите поэкспериментировать, не ломая текущую систему? Клонируете boot environment прямо из загрузчика и загружаетесь в копию. Интересный факт: на самом деле этот загрузчик — это полноценный Linux, который при загрузке загружает вашу систему использую системный вызов kexec.
Нативное шифрование ZFS
Поддерживается нативное шифрование ZFS без необходимости в LUKS‑контейнерах — ZFS шифрует данные сам. При этом доступны следующие варианты:
Без шифрования.
Шифрование всего пула (зашифрованы все датасеты включая корневую систему)
Шифрование отдельного boot environment
В текущей версии поддерживаются только plain text ключи (пароли), без более сложных схем аутентификации. За расшифровку отвечает хук zfs в initramfs, который запрашивает пароль на ранней стадии загрузки.
Dracut vs mkinitcpio — выбор за вами
Arch традиционно использует mkinitcpio для создания initramfs. Но я предпочитаю dracut — его хук zfs лучше работает с нативным шифрованием ZFS. Установщик поддерживает оба варианта, и тут есть интересные технические детали.
Для mkinitcpio я добавляю хук zfs в нужное место (после keyboard, но до filesystems), прописываю правильные модули. А вот с dracut пришлось повозиться больше: нужно было написать собственные pacman хуки, которые автоматически пересобирают initramfs при обновлении ядра. Стандартные хуки пакмана не подходят — они не знают про dracut.
Загрузка и boot environments: ZFSBootMenu, zfs‑mount‑generator и кастомный ZED‑хук
Коротко о том, как устроена загрузка:
В качестве загрузчика используется ZFSBootMenu: при выборе boot environment он запускает ядро Linux через системный вызов kexec и передаёт параметры командной строки ядра.
Корневая ФС монтируется хуком zfs в initramfs, согласно параметру командной строки: с dracut это
root=ZFS=...
, с mkinitcpio — черезzfs=...
Остальные датасеты монтируются уже systemd»ом через
zfs-mount-generator
, который читает/etc/zfs/zfs-list.cache/<pool>
и на лету генерирует unit‑файлы. Примечание: использованиеzpool.cache
считается устаревшим и не рекомендуется Arch Wiki, поэтому был выбран подход сzfs-mount-generator
Проблема BE в том, что «по умолчанию» ZFS видит все датасеты пула, из‑за чего systemd может попытаться примонтировать чужие файловые системы (например, /home
из соседнего boot environment). Это решает мой кастомный ZED‑хук history_event-zfs-list-cacher.sh
: он отслеживает события ZFS, определяет активный boot environment, фильтрует датасеты (оставляя только датасеты, принадлежащие текущему BE и общие вроде pool/tmp_zfs
) и атомарно обновляет кеш. Скрипт сделан иммутабельным (chattr +i
), чтобы обновления не затирали его.
Swap, ZRAM и ZSWAP
Можно вовсе обойтись без swap, можно включить ZRAM — это сжатый swap в RAM через systemd-zram-generator
, и в этом режиме я специально отключаю zswap. По умолчанию используется zram-size = min(ram / 2, 4096)
в /etc/systemd/zram-generator.conf
.
Если нужен классический swap на диске — выбирайте режим «ZSWAP + swap‑раздел»: zswap включается, а сам swap живёт на отдельном разделе. При полном стирании диска задаёте размер раздела под swap; в остальных сценариях просто выбираете существующий раздел в TUI. Для незашифрованного варианта установщик делает mkswap
и явно добавляет строку с UUID=
в /etc/fstab
(genfstab не включает неактивный swap). Для шифрованного — прописывает cryptswap
через PARTUUID
в /etc/crypttab
и монтирует /dev/mapper/cryptswap
в fstab
.
Примечание: swap на ZFS (zvol/swapfile) не поддерживается — см. раздел ArchWiki «ZFS → Swap volume». Гибернация в текущем релизе тоже не поддерживается.
Валидация совместимости ядра и ZFS
Одна из ключевых проблем при работе с ZFS на Arch — совместимость версий ядра и модулей ZFS. Precompiled модули ZFS в репозитории archzfs часто отстают от последних версий ядра, а DKMS может не компилироваться с bleeding‑edge ядрами.
Для решения этой проблемы я написал систему валидации, которая определяет диапазон совместимых ядер для текущей версии ZFS. Система работает следующим образом:
Парсит release notes на https://github.com/openzfs/zfs/releases для определения поддерживаемых версий ядра
Сопоставляет эти данные с актуальными версиями ядер (linux, linux‑lts, linux‑zen) в репозиториях Arch
Проверяет доступность precompiled ZFS модулей для каждого ядра
Анализирует возможность DKMS‑сборки с конкретными версиями ядра
Предупреждает о потенциальных проблемах и предлагает альтернативы
Эта валидация используется в двух местах:
1. В установщике — при выборе ядра показываются только совместимые варианты
2. При сборке ISO — скрипт iso_builder.py
автоматически проверяет совместимость перед созданием образов
Как это выглядит на практике?
Процесс установки сводится к нескольким простым шагам — выберите удобный способ запуска установщика:
Вариант A: готовый ISO (рекомендуется)
Скачать последний ISO из релизов проекта, ( https://github.com/okhsunrog/archinstall_zfs/releases ) загрузиться в режиме UEFI. Примечание: если вы используете Ventoy, при выборе образа нужно выбрать GRUB2 режим загрузки.
Подключить сеть.
Запустить установщик:
./installer
# или
cd /root/archinstall_zfs && python -m archinstall_zfs
Вариант B: официальный Arch ISO (Этот вариант занимает больше времени из‑за установки ZFS модулей в ISO.)
# 1) Загрузитесь с официального Arch ISO и подключите сеть
pacman -Sy git
# 2) Получите установщик
git clone --depth 1 https://github.com/okhsunrog/archinstall_zfs
cd archinstall_zfs
python -m archinstall_zfs
Далее в TUI пройдите короткий визард: выберите режим установки → диски → имя пула → параметры системы. После подтверждения установщик автоматически настроит ZFSBootMenu, подберёт совместимую связку ядро/ZFS, соберёт initramfs (dracut или mkinitcpio) и включит необходимые сервисы ZFS. В конце — предложение зайти в chroot и перезагрузка в свежий Arch на ZFS.
Подробнее о коде
Всё написано на Python 3.13+ с использованием archinstall как библиотеки, но архитектуру пришлось делать с нуля. Стандартные меню archinstall не подошли — сделал своё, чтобы контролировать весь процесс установки. Для разметки диска тоже реализовал отдельный класс, потому что archinstall не умеет работать с ZFS.
Установка ZFS идёт через собственный класс (наследник archinstall.Installer): он добавляет нужные пакеты, правильно собирает initramfs (dracut или mkinitcpio) и учитывает все нюансы ZFS. Валидация совместимости ядра и ZFS вынесена в отдельный модуль — он парсит репозитории, релизы ZFS и проверяет, что всё совместимо. Для конфигов используется Pydantic, чтобы не было магии с dict'ами.
Профиль для ISO собирается через шаблоны Jinja2 — так проще поддерживать разные варианты (DKMS или precompiled модули, разные хуки и сервисы, разные наборы пакетов включаются условно). Всё максимально типизировано, чтобы не ловить баги на ровном месте.
Сборка ISO: just, Justfile и Jinja2
Сборочные сценарии полностью оркестрируются через just
(рецепты описаны в justfile
). Это позволяет быстро собирать разные варианты ISO и управлять параметрами сборки.
# Посмотреть доступные команды:
just --list
# Релизные ISO (полный набор пакетов)
just build-main pre # Precompiled ZFS + linux-lts (рекомендуется)
just build-main dkms linux # DKMS + linux
just build-main dkms linux-lts # DKMS + linux+lts (самый надёжный вариант, если версии пакетов zfs и ядер рассинхронизированы)
# Ускоренные сборки для разработки (минимальный набор пакетов)
just build-test pre # Минимальный пакетный набор + precompiled ZFS
just build-test dkms linux-zen # Минимальный пакетный набор + DKMS + linux-zen
just list-isos # Показать собранные ISO
Ключевые различия между build-main
и build-test
:
build-main
— создаёт релизные ISO с полным набором пакетов (включая диагностические инструменты, сетевые утилиты, редакторы и т. д.). Используетsquashfs
для сжатия, что даёт меньший размер ISO.build-test
— создаёт тестовые ISO с минимальным набором пакетов (только базовые утилиты и установщик). Используетerofs
для более быстрого сжатия, отключает таймауты загрузки и включает вывов в serial console для удобства загрузки в qemu, автоматически поднимает ssh и разрешает логин от рута. Идеально подходит для быстрого тестирования изменений в установщике в qemu.
Профиль archiso
генерируется из шаблонов на Jinja2, что даёт гибкую конфигурацию без копипасты:
Переменные шаблонов:
kernel
— целевой вариант ядраuse_precompiled_zfs
/use_dkms
— способ установки ZFSinclude_headers
— включать ли headers для ядра—
fast_build
— минимальный пакетный набор для быстрых тестов
Ключевые шаблоны:
packages.x86_64.j2
— список пакетовprofiledef.sh.j2
— метаданные ISO, флаги сборки, разрешения файловpacman.conf.j2
— конфигурация репозиториев
Скрипт iso_builder.py
формирует профиль ISO на основе этих шаблонов и параметров, а результаты складываются в gen_iso/out/
. Сами профильные файлы, сервисы и хуки лежат в gen_iso/profile/
.
Дополнительные возможности установщика
Сжатие ZFS (настраиваемо): выбор алгоритма в TUI —
off
,lz4
(по умолчанию),zstd
,zstd-5
,zstd-10
. Выбранное значение применяется на уровне пула/датасетов и наследуется, а в initramfs отключается лишняя компрессия, чтобы избежать двойного сжатия.zrepl: генерация
/etc/zrepl/zrepl.yml
с снапшотами каждые 15 минут и ретеншеном4×15m (keep=all) | 24×1h | 3×1d
.AUR‑интеграция: установка пакетов из AUR через временного пользователя (
aurinstall
), установка хелпераyay-bin
. В меню доступен пункт, где можно указать список своих AUR‑пакетов, которые будут автоматически установлены.
Что ожидать в следующем релизе?
Поддержка Secure Boot (подпись ZFSBootMenu, управление ключами)
Локальная сборка ZFSBootMenu, используя системное ядро и dracut / mkinitcpio, вместо готовых EFI‑файлов, для большей кастомизации
Более умная генерация hostid (на основе имени хоста)
Возможно, добавлю русскую локализацию, если будет интерес
Пара слов о CI
За сборку отвечает GitHub Actions: раз в месяц он автоматически собирает свежие образы, а ещё он запускается при пуше нового тега и формирует релиз с ISO‑образами в качестве артифактов. Перед сборкой пайплайн проверяет совместимость: сначала пробует предсобранные ZFS‑модули, и если версии не совпадают, автоматически переключается на DKMS. Благодаря этому образ с linux-lts
получается практически всегда, а linux
в редких случаях, если текущая версия ядра ещё не поддерживается проектом OpenZFS, просто пропускается.
ZFS — это мощный инструмент, но сложность её настройки отпугивает многих. Я надеюсь, что archinstall_zfs сделает эту файловую систему доступнее для обычных пользователей Arch Linux. Больше не нужно быть гуру, чтобы получить все преимущества ZFS — снапшоты, boot environments, компрессию и надёжность.
Проект активно развивается, поэтому баги возможны. Но я сам использую его для всех своих установок и пока полёт нормальный:)
Если у вас есть идеи по улучшению или вы нашли баг — welcome в issues на GitHub! А если проект оказался полезным — поставьте звёздочку, это мотивирует развивать его дальше.
Так же приглашаю заглянуть в мой телеграм‑канал Okhsunrog's Logs: никакой рекламы, только технические заметки про Rust, Linux, Embedded, отчёты про прогресс моих текущих опенсорсных проектов, и конечно же, мемы.