Building a ZoiOS Distro
A guide on how to bootstrap and build a ZoiOS distribution (like Parlex Linux) from scratch using Zoi.
Zoi provides a powerful set of tools to act as a "Universal Distro Engine." This allows you to construct an entire, bootable, declarative operating system (ZoiOS) from a standard Linux environment using the zoi system distro build command.
This guide walks you through bootstrapping a ZoiOS system (e.g. Parlex Linux) onto a new disk, assuming the required base packages are available in your configured Zoi registry.
Prerequisites
- A Host Linux System: You need a running Linux environment (like an Ubuntu Live USB or a Fedora host) to perform the initial installation.
- Zoi CLI Installed: The host system must have the Zoi CLI installed.
- Root Privileges: Formatting disks and installing bootloaders requires
sudo. - A Configured Registry: Your Zoi instance must be configured to sync with a registry that provides the essential ZoiOS packages (e.g.
@parlex/linux,@parlex/glibc,@parlex/systemd).
Step 1: Prepare the system.lua Configuration
The entire state of a ZoiOS machine is defined in a system.lua file. This file acts as the blueprint for your new distribution.
Create a file named target-system.lua:
-- target-system.lua
system({
hostname = "my-zoios-machine",
timezone = "UTC",
locale = "en_US.UTF-8",
-- Optional kernel parameters
kernel_params = "quiet splash rw",
})
-- Essential base packages required for a bootable system
packages({
"@parlex/base",
"@parlex/linux",
"@parlex/glibc",
"@parlex/systemd",
"@parlex/bash",
"@parlex/coreutils",
"@parlex/filesystem",
"@parlex/dracut",
"@parlex/grub",
"@parlex/shadow",
"@parlex/sudo",
})
services({
["systemd-journald"] = { enable = true },
["systemd-networkd"] = { enable = true },
["systemd-resolved"] = { enable = true },
})
filesystems({
{
device = "LABEL=ZOIOS_ROOT",
mount = "/",
type = "ext4",
options = "noatime",
},
})Step 2: Partition and Format the Target Disk
Before Zoi can orchestrate the installation, you must partition and format your target disk manually.
Disclaimer: Replace /dev/sdX with your actual target device. Be extremely careful not to format your host machine's drive!
Example Partitioning (UEFI)
Use a tool like parted or fdisk to create:
- EFI Partition (e.g.
/dev/sdX1, 512MB, format asvfat) - Root Partition (e.g.
/dev/sdX2, remainder of disk, format asext4)
# Example formatting
sudo mkfs.vfat -F 32 -n ZOI_BOOT /dev/sdX1
sudo mkfs.ext4 -L ZOIOS_ROOT /dev/sdX2Step 3: Run the Universal Distro Builder
Now, simply run the builder. This command establishes the system marker and installs the base packages.
# We mount the target root temporarily so Zoi knows where to install
sudo mount /dev/sdX2 /mnt
sudo mkdir -p /mnt/boot/efi
sudo mount /dev/sdX1 /mnt/boot/efi
# Orchestrate the entire build
sudo zoi system distro build --target /mnt --config ./target-system.luaWhat happens under the hood?
In this single step, Zoi:
- Initializes Sysroot: Drops the
/etc/os-releasemarker (ID=zoios) so the disk is recognized as ZoiOS. - Bootstrap Installation: Directly installs the entire base package set (
@parlex/linux,@parlex/glibc, etc.) into the target Zoi store and then into the system root. - Builds the First Generation: Creates a lightweight record of the installation and links it to the package transaction.
- Generates fstab: Writes
/etc/fstabbased on yoursystem.luaconfiguration.
Step 4: Finalize the Bootloader and Initramfs
Once the build is complete, you must ensure the bootloader is properly installed and the initramfs (initial ramdisk) is generated. Zoi makes this easy by allowing you to enter an ephemeral shell that is redirected into your new system's root using the --root flag.
1. Generate the Initramfs
ZoiOS systems require an initramfs to handle early boot tasks (like mounting the root partition). You can use any tool you've packaged, such as dracut, mkinitcpio, or booster.
# Example: Generating initramfs using dracut
sudo zoi system distro chroot /mnt
dracut --kver 7.1.4-arch1-1 --force /boot/initramfs-linux.img2. Install the Bootloader
Now install your bootloader (e.g. GRUB) to the disk:
# Finalize the bootloader using Zoi chroot
# This automatically handles mounting /dev, /proc, and /sys into the target
sudo zoi system distro chroot /mnt
grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable
grub-mkconfig -o /boot/grub/grub.cfg3. Post-Build Package Management
Once the OS is bootstrapped, you can continue to manage its package database and configuration from the host using the --root flag. This is useful for installing extra tools or setting up custom registries inside the new OS before first boot.
# Set a custom registry inside the target OS
sudo zoi sync set /path/to/my-registry --root /mnt
# Sync the package database into the target root's system store (/var/lib/zoi)
# Zoi automatically uses --scope system when --root is specified.
sudo zoi sync --root /mnt
# Install additional packages directly into the target OS
sudo zoi install @parlex/neovim @parlex/git --root /mntIsolated State
When using --root, Zoi is fully isolated. Transaction logs, audit history, and local configuration files are stored within the target's /var/lib/zoi and ~/.zoi directories. By default, metadata is synced to the system-wide store (/var/lib/zoi/pkgs/db), ensuring the new OS is ready for use even without a pre-configured user home.
Pro Tip
Using zoi system distro chroot /mnt is preferred over manual chroot because it leverages Zoi's sandbox engine to safely bridge your host's system devices into the target environment automatically.
Step 5: Reboot
Unmount the filesystems and reboot into your newly built ZoiOS system!
sudo umount -R /mnt
sudo rebootCreating a Bootable USB Stick
You can use Zoi to create a fully persistent, declarative ZoiOS USB stick. This is perfect for a portable "Swiss Army Knife" OS or a secure live environment.
1. Prepare the Configuration
Create a usb-system.lua file. It should look like a standard ZoiOS configuration but optimized for USB (e.g. using ext4 or btrfs with noatime).
2. Partition and Format the USB
Assuming your USB is /dev/sdX:
# Create EFI and Root partitions
sudo parted /dev/sdX -- mklabel gpt
sudo parted /dev/sdX -- mkpart ESP fat32 1MiB 512MiB
sudo parted /dev/sdX -- set 1 esp on
sudo parted /dev/sdX -- mkpart primary ext4 512MiB 100%
# Format and Label
sudo mkfs.vfat -F 32 -n ZOI_BOOT /dev/sdX1
sudo mkfs.ext4 -L ZOI_ROOT /dev/sdX23. Mount and Build
sudo mkdir -p /mnt/zoi-usb
sudo mount /dev/sdX2 /mnt/zoi-usb
sudo mkdir -p /mnt/zoi-usb/boot/efi
sudo mount /dev/sdX1 /mnt/zoi-usb/boot/efi
# Bootstrap the OS
sudo zoi system distro build --target /mnt/zoi-usb --config ./usb-system.lua4. Finalize the Bootloader
Use Zoi chroot to install GRUB to the USB's EFI partition in removable mode:
sudo zoi system distro chroot /mnt/zoi-usb
grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable
grub-mkconfig -o /boot/grub/grub.cfg5. Cleanup and Boot
sudo umount -R /mnt/zoi-usb
syncHow It Works: The ZoiOS Guard
You might wonder why you can't run zoi system apply on a standard Ubuntu or macOS host.
Zoi includes a ZoiOS Environment Guard. Commands like zoi system apply, list, and rollback check for specific OS markers (like ID=zoios or ID=parlex in /etc/os-release). If the system is not a recognized ZoiOS distribution, these commands are safely disabled to prevent accidental damage to a standard generic Linux environment.
The zoi system distro build command is explicitly allowed on generic systems so that you can bootstrap new disks, and its primary job is to establish that initial marker so the target disk becomes a valid ZoiOS environment.
2026 © All Rights Reserved.
- All the content is available under CC BY-SA 4.0, expect where otherwise stated.
- Source code is available on GitLab, licensed under Apache 2.0.
Last updated on
