Bootc Autoinstall Configuration#
The bootc-installer uses a declarative JSON recipe to drive the fisherman Go backend for both guided and unattended installations. The --autoinstall flag skips the GUI wizard entirely, making recipes the primary interface for scripted, live-ISO, and CI deployments.
Source: projectbluefin/bootc-installer
--autoinstall Flag#
Pass a complete recipe path to skip the wizard :
flatpak run org.bootcinstaller.Installer --autoinstall /path/to/recipe.json
In autoinstall mode the application jumps straight to BootcWindow with the recipe pre-loaded — all system-requirement checks (RAM, CPU, UEFI) are bypassed . This is the primary mechanism for live ISO pre-configuration .
For boot-time automation, drop a systemd unit :
[Unit]
Description=Unattended bootc install
After=graphical.target
[Service]
ExecStart=flatpak run org.bootcinstaller.Installer --autoinstall /etc/bootc-installer/autoinstall.json
Recipe Schema#
The wizard or processor.py generates a recipe; you can also write one by hand. The full field reference :
| Field | Type | Description |
|---|---|---|
disk | string | Block device (e.g. "/dev/nvme0n1") |
filesystem | string | "xfs" or "btrfs" |
btrfsSubvolumes | bool | Create @, @home, @snapshots subvolumes (btrfs only) |
encryption.type | string | "none", "luks-passphrase", "tpm2-luks", or "tpm2-luks-passphrase" |
encryption.passphrase | string | Required for luks-passphrase / tpm2-luks-passphrase |
image | string | Source OCI image (pulled by podman or read from local store) |
targetImgref | string | Update-tracking ref written into the deployed OS |
selinuxDisabled | bool | Pass --disable-selinux to bootc |
unifiedStorage | bool | Pass --experimental-unified-storage to bootc (default: true) |
composeFsBackend | bool | Pass --composefs-backend to bootc (required for Dakota) |
bootloader | string | "grub2" (default) or "systemd" (Dakota / systemd-boot) |
hostname | string | Hostname written into the installed OS |
flatpaks | array | Flatpak app IDs to copy from live system into target |
user.username | string | Username to create; leave empty to skip user creation |
user.fullname | string | Display name |
user.password | string | Plain-text password (hashed during install) |
user.groups | array | Additional groups (e.g. ["wheel", "docker"]) |
Additional fields emitted by processor.py when applicable :
| Field | Description |
|---|---|
customMounts | Manual partition layout (array of {partition, target, fstype}) |
imageType | Override image type (default: "bootc") |
flatpakVarPath | Where the installer places Flatpak data on the target |
slurp | Windows data migration config |
slurpWallpapers | Always true — silently rescues Windows wallpapers |
additionalImageStores | Offline OCI store paths (e.g. squashfs VFS store on live ISO) |
varDisk | Separate /var disk config ({disk, keepExisting}) |
Boot Stack Selection#
bootloader and composeFsBackend together determine the partition layout and deployment backend :
| Stack | bootloader | composeFsBackend | Layout | Root FS | Target images |
|---|---|---|---|---|---|
| systemd-boot | "systemd" | true | 2-partition GPT (EFI + root) | btrfs | Dakota |
| GRUB2 | "grub2" | false | 3-partition GPT (EFI + /boot + root) | XFS or btrfs | Bluefin, Bluefin-LTS |
Encryption Options#
encryption.type | Behavior |
|---|---|
"none" | Unencrypted |
"luks-passphrase" | LUKS2 with user-supplied passphrase |
"tpm2-luks" | LUKS2 auto-unlocked by TPM2 at boot |
"tpm2-luks-passphrase" | TPM2 primary + passphrase fallback; recovery key shown on screen |
processor.py resolves the encryption type from use_encryption + encryption_key fields if type is not set explicitly .
Example Recipes#
Bluefin / Bluefin-LTS — minimal, XFS, GRUB2, no encryption #
{
"disk": "/dev/sda",
"filesystem": "xfs",
"btrfsSubvolumes": false,
"encryption": { "type": "none" },
"image": "ghcr.io/projectbluefin/bootcos:latest",
"targetImgref": "ghcr.io/projectbluefin/bootcos:latest",
"selinuxDisabled": false,
"unifiedStorage": true,
"composeFsBackend": false,
"bootloader": "grub2",
"hostname": "bootcos",
"flatpaks": [],
"user": { "username": "alice", "fullname": "Alice", "password": "hunter2", "groups": ["wheel"] }
}
Dakota — systemd-boot + composefs + btrfs #
{
"disk": "/dev/nvme0n1",
"filesystem": "btrfs",
"btrfsSubvolumes": false,
"encryption": { "type": "none" },
"image": "ghcr.io/projectbluefin/dakota:latest",
"targetImgref": "ghcr.io/projectbluefin/dakota:latest",
"selinuxDisabled": false,
"unifiedStorage": true,
"composeFsBackend": true,
"bootloader": "systemd",
"hostname": "bootcos",
"flatpaks": [],
"user": { "username": "", "fullname": "", "password": "", "groups": [] }
}
Dakota skips user creation (
username: ""); first-boot user setup runs via its own onboarding flow .
btrfs + TPM2 LUKS + Flatpaks #
{
"disk": "/dev/nvme0n1",
"filesystem": "btrfs",
"btrfsSubvolumes": true,
"encryption": { "type": "tpm2-luks" },
"image": "ghcr.io/projectbluefin/bootcos:latest",
"targetImgref": "ghcr.io/projectbluefin/bootcos:latest",
"selinuxDisabled": false,
"unifiedStorage": true,
"composeFsBackend": false,
"bootloader": "grub2",
"hostname": "bootcos",
"flatpaks": ["org.mozilla.firefox", "org.gnome.Console"],
"user": { "username": "alice", "fullname": "Alice", "password": "hunter2", "groups": ["wheel"] }
}
System-level Recipe Overrides (/etc/bootc-installer/)#
Distros and live ISOs can pre-configure the installer without using --autoinstall by dropping files into /etc/bootc-installer/ :
| Path | Effect |
|---|---|
/etc/bootc-installer/images.json | Replaces the bundled image catalog |
/etc/bootc-installer/recipe.json | Sys-recipe — partial defaults merged with wizard output |
$XDG_CONFIG_HOME/bootc-installer/images.json | Per-user catalog override (dev/testing) |
A partial sys-recipe sets defaults that users can still override in the wizard. For fully unattended installs, use --autoinstall with a complete recipe instead.
processor.py — Recipe Assembly#
processor.py is the Python module that assembles the fisherman recipe from the UI's collected step outputs (finals). Key logic:
- Disk resolution — handles auto-select and manual partition layouts
- NVIDIA auto-detection — if the image has a
nvidia_imgrefin the catalog, installs the NVIDIA variant when a GPU is present; otherwise installs from the NVIDIA ISO store but setstargetImgrefto the base image sobootc upgraderebases to the lighter variant local_imgref— live ISO offline install override; replacesimagewith acontainers-storage:reference to the pre-embedded VFS store- Flatpak sandbox path — writes the temp recipe to
~/.cache/bootc-installer/soflatpak-spawn --hostcan read it from the host side
Live ISO Integration#
In live ISO mode the installer detects /etc/bootc-installer/live-iso-mode and switches to offline install . The BOOTC_CUSTOM_RECIPE env var points the Flatpak to the host's /run/host/etc/bootc-installer/recipe.json . The fisherman binary can also be invoked directly for CI/scripting :
sudo /usr/local/bin/fisherman /path/to/recipe.json
For offline installs, the additionalImageStores field in the sys-recipe passes the squashfs-embedded VFS store path to fisherman so no network pull is required .