Install Using PXE Boot
Automate bare-metal Garden Linux deployments using iPXE network boot combined with Ignition for first-boot configuration. This guide covers the complete PXE installation workflow, from network boot to disk installation.
For non-network installations using bootable media, see Install Using ISO.
Overview
The PXE installation process boots Garden Linux as a live system over the network, applies configuration via Ignition, and installs the system to disk. The workflow consists of:
- Network boot via iPXE — Client firmware loads iPXE from TFTP, which fetches the kernel, initrd, and squashfs root filesystem over HTTP
- Live system — Garden Linux runs from an OverlayFS with the squashfs image as the lower layer and tmpfs as the upper layer
- Ignition configuration — Applies first-boot configuration (users, files, services)
- Installation — Copies the live system to disk, installs the bootloader, and kexec into the installed system
- Subsequent boots — System boots directly from disk without PXE
First Boot Flow
flowchart TD
A[Power On] --> B[Firmware: BIOS/UEFI]
B --> C[PXE Boot]
C --> D[DHCP: Get IP + TFTP server]
D --> E[TFTP: Download iPXE binary]
E --> F[iPXE: Get boot script URL via DHCP]
F --> G[HTTP: Download boot.ipxe]
G --> H[HTTP: Download kernel + initrd]
H --> I[Boot Kernel]
I --> J[Initramfs: Fetch squashfs via HTTP]
J --> K[Mount OverlayFS: squashfs + tmpfs]
K --> L[Ignition: Fetch config from URL]
L --> M[Ignition: Write files, enable services]
M --> N[install.service: Partition disk]
N --> O[install.service: Copy rootfs to disk]
O --> P[install.service: Install bootloader]
P --> Q[kexec into installed system]
Q --> R[Garden Linux running from disk]Subsequent Boot Flow
flowchart TD
A[Power On] --> B[Firmware: BIOS/UEFI]
B --> C[Boot from Disk]
C --> D[Bootloader: syslinux or systemd-boot]
D --> E[Garden Linux]Network Boot Sequence
sequenceDiagram
participant Client
participant DHCP
participant TFTP
participant HTTP
Client->>DHCP: Request IP address
DHCP-->>Client: IP + TFTP server + filename
Note over Client,DHCP: Filename: ipxe.efi (UEFI) or undionly.kpxe (BIOS)
Client->>TFTP: Download iPXE binary
TFTP-->>Client: iPXE binary
Client->>DHCP: Request boot script URL (iPXE environment)
DHCP-->>Client: HTTP URL to boot.ipxe
Client->>HTTP: GET boot.ipxe
HTTP-->>Client: boot.ipxe script
Client->>HTTP: GET rootfs.vmlinuz
HTTP-->>Client: Kernel image
Client->>HTTP: GET rootfs.initrd
HTTP-->>Client: Initramfs
Client->>Client: Boot kernel
Client->>HTTP: GET root.squashfs
HTTP-->>Client: Root filesystem image
Client->>HTTP: GET ignition.json
HTTP-->>Client: Ignition configuration
Client->>HTTP: GET install.json (via ignition merge)
HTTP-->>Client: Install configuration
Client->>Client: Install to diskPrerequisites
- Target clients — Physical servers or virtual machines with BIOS or UEFI firmware supporting network boot
- Garden Linux build — Image built with
_pxe,metal, andserverfeatures, generating:rootfs.vmlinuz— Kernel imagerootfs.initrd— Initramfs with live boot supportroot.squashfs— Compressed root filesystem
- TFTP server — Serves iPXE binaries for Legacy BIOS and UEFI firmware:
undionly.kpxe— Legacy BIOS iPXE binaryipxe.efi— UEFI iPXE binary
- DHCP server — Provides IP addresses and PXE chainloading configuration
- HTTP server — Hosts Garden Linux images, iPXE boot scripts, and Ignition configuration files
Download iPXE binaries from https://boot.ipxe.org.
Building PXE Images
For detailed build system documentation and building PXE images with custom features, see Building Images.
Disk Layout and Bootloader
The installation creates a GPT partition table with two partitions:
| Partition | Type | Size | Format | Purpose |
|---|---|---|---|---|
| EFI | C12A7328-F81F-11D2-BA4B-00A0C93EC93B (ESP) | 510 MiB | FAT32 | Bootloader storage (Legacy: syslinux stages, UEFI: systemd-boot + UKI) |
| ROOT | 0FC63DAF-8483-4772-8E79-3D69D8477DE4 (Linux filesystem) | Remaining space | ext4 | Garden Linux root filesystem |
Bootloader Installation
The installation script detects the firmware type and installs the appropriate bootloader:
- Legacy BIOS — Installs syslinux. Writes a new MBR to the first sector of the disk and installs syslinux stages 2+ to the EFI partition.
- UEFI — Installs systemd-boot with a Unified Kernel Image (UKI). A UKI is a single EFI PE executable combining an EFI stub loader, kernel image, initramfs, and kernel command line. UKI images can be signed for Secure Boot.
This identical disk layout for both firmware types allows migrating an installation between Legacy and UEFI systems by re-running the appropriate bootloader installation script.
Configure the iPXE Boot Script
Create an iPXE boot script (boot.ipxe) that instructs iPXE to fetch the Garden Linux kernel, initramfs, and root filesystem:
#!ipxe
set base-url http://192.168.1.10:8080
kernel ${base-url}/rootfs.vmlinuz initrd=rootfs.initrd \
gl.ovl=/:tmpfs \
gl.url=${base-url}/root.squashfs \
gl.live=1 \
ip=dhcp \
console=ttyS1,115200n8 console=tty0 \
earlyprintk=ttyS1,115200n8 consoleblank=0 \
ignition.firstboot=1 \
ignition.config.url=${base-url}/ignition.json \
ignition.platform.id=metal
initrd ${base-url}/rootfs.initrd
bootKernel Parameters Explained
gl.ovl=/:tmpfs— Use tmpfs as the upper layer for the OverlayFS root filesystemgl.url=${base-url}/root.squashfs— URL to the compressed root filesystem imagegl.live=1— Enable live boot mode (do not persist changes to disk during live session)ip=dhcp— Configure network interfaces via DHCPconsole=ttyS1,115200n8 console=tty0— Output to serial console (ttyS1) and VGA console (tty0)ignition.firstboot=1— Tell Ignition this is a first boot (Ignition only runs on first boot)ignition.config.url=${base-url}/ignition.json— URL to the Ignition configuration fileignition.platform.id=metal— Platform identifier for Ignition (usemetalfor bare-metal and non-cloud deployments)
Replace http://192.168.1.10:8080 with your HTTP server's address.
Configure Ignition
Ignition configures the system during first boot before the installation begins. Create two Ignition configuration files:
ignition.yaml— Main configuration defining partition layout, target disk, and merging the install configurationinstall.yaml— Installation-specific configuration provided by Garden Linux
Create ignition.yaml
Create the main Ignition configuration in YAML format:
variant: fcos
version: 1.3.0
ignition:
config:
merge:
- source: http://192.168.1.10:8080/install.json
storage:
files:
- path: /opt/onmetal-install/partitions
overwrite: true
mode: 0755
contents:
inline: |
label: gpt
type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name="EFI", size=510MiB
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="ROOT"
- path: /opt/onmetal-install/target
overwrite: true
mode: 0755
contents:
inline: |
disk=/dev/sdaConfiguration Fields
ignition.config.merge— Merges the installation configuration from the specified URL. This must point toinstall.json(the translatedinstall.yamlprovided by Garden Linux)./opt/onmetal-install/partitions— Defines the partition layout. The first two partitions (EFI and ROOT) must match the format shown. Additional partitions can be appended after ROOT if needed./opt/onmetal-install/target— Specifies the target disk for installation (e.g.,/dev/sda,/dev/nvme0n1).
To add users, SSH keys, hostname, systemd units, or other configuration to ignition.yaml, see the Provision with Ignition guide for the full range of Ignition configuration options.
To translate the YAML configuration to JSON, use Butane.
Set Up Network Boot Infrastructure
Configure DHCP Server
Configure your DHCP server to provide PXE chainloading. Example configuration for dnsmasq:
# Enable DHCP
dhcp-range=192.168.1.100,192.168.1.200,12h
# PXE boot configuration
dhcp-match=set:bios,option:client-arch,0
dhcp-match=set:efi64,option:client-arch,7
dhcp-match=set:efi64,option:client-arch,9
# BIOS clients: chainload to iPXE
dhcp-boot=tag:bios,undionly.kpxe,192.168.1.10
# UEFI clients: chainload to iPXE
dhcp-boot=tag:efi64,ipxe.efi,192.168.1.10
# iPXE clients: provide boot script URL
dhcp-match=set:ipxe,175
dhcp-boot=tag:ipxe,http://192.168.1.10:8080/boot.ipxeReplace 192.168.1.10 with your server's IP address.
Configure TFTP Server
Set up a TFTP server to serve iPXE binaries. Example using tftpd-hpa:
# Install TFTP server
apt-get install tftpd-hpa
# Download iPXE binaries
cd /var/lib/tftpboot
curl -O https://boot.ipxe.org/undionly.kpxe
curl -O https://boot.ipxe.org/ipxe.efi
# Restart TFTP service
systemctl restart tftpd-hpaConfigure HTTP Server
Set up an HTTP server to host Garden Linux images and configuration files. Example using nginx:
# Install nginx
apt-get install nginx
# Create directory structure
mkdir -p /var/www/pxe
cd /var/www/pxe
# Copy Garden Linux images
cp /path/to/rootfs.vmlinuz .
cp /path/to/rootfs.initrd .
cp /path/to/root.squashfs .
# Copy configuration files
cp boot.ipxe .
cp ignition.json .
cp install.json .
# Configure nginx
cat > /etc/nginx/sites-available/pxe <<'EOF'
server {
listen 8080;
root /var/www/pxe;
autoindex on;
location / {
try_files $uri $uri/ =404;
}
}
EOF
ln -s /etc/nginx/sites-available/pxe /etc/nginx/sites-enabled/
systemctl reload nginxBoot the Target System
- Configure BIOS/UEFI — Enable network boot in the firmware settings and set network boot as the first boot device
- Power on the system — The system boots via PXE and fetches the iPXE binary from TFTP
- iPXE loads — iPXE fetches
boot.ipxefrom the HTTP server and boots the Garden Linux kernel - Live system starts — The initramfs downloads
root.squashfsand mounts it as an OverlayFS - Ignition runs — Fetches and applies the Ignition configuration
- Installation begins — The
install.servicesystemd unit partitions the disk, copies the live system to disk, and installs the bootloader - System reboots — kexec switches into the installed system running from disk
The installation typically completes in 5-10 minutes depending on network speed and disk performance.
Post-Installation
After installation, the system boots directly from disk without PXE. The dracut module responsible for live booting is disabled, and the installer is removed.
To configure the installed system:
- Enable SSH — SSH is disabled by default. Enable it via Ignition (add
ssh.serviceto systemd units) or manually after installation - Create users — Add users via Ignition or use the recovery procedure described in Post-Install Configuration
- Configure networking — Network configuration can be defined in Ignition using systemd-networkd configuration files
Troubleshooting
System Does Not Boot via PXE
- Verify network boot is enabled — Check BIOS/UEFI settings
- Check DHCP responses — Use
tcpdumpon the DHCP server to verify PXE DHCP responses:bashtcpdump -i eth0 -n port 67 and port 68 - Verify TFTP server accessibility — Test TFTP from another machine:bash
tftp 192.168.1.10 get undionly.kpxe
iPXE Fails to Download Files
- Check HTTP server logs — Verify requests are reaching the server:bash
tail -f /var/log/nginx/access.log - Test HTTP URLs manually — Verify files are accessible:bash
curl http://192.168.1.10:8080/boot.ipxe curl http://192.168.1.10:8080/rootfs.vmlinuz - Verify file permissions — Ensure files are readable by the web server
Ignition Configuration Not Applied
- Check Ignition logs — After booting the live system, check Ignition journal entries:bash
journalctl -u ignition-fetch.service journalctl -u ignition-files.service - Validate Ignition JSON syntax — Use Butane to validate the YAML before translation:bash
./butane --strict ignition.yaml > /dev/null - Verify ignition.config.url is reachable — Ensure the URL in
boot.ipxeis correct and accessible from the target system
Installation Fails or Does Not Start
- Check install.service logs:bash
journalctl -u install.service - Verify target disk exists — Check that the disk specified in
/opt/onmetal-install/targetexists:bashlsblk cat /opt/onmetal-install/target - Check partition layout — Verify
/opt/onmetal-install/partitionssyntax is correct
System Boots Back to PXE After Installation
- UEFI boot order not updated — The installation should update the UEFI boot order. If it does not, manually set the disk as the first boot device in firmware settings
- Bootloader installation failed — Check installation logs for bootloader errors
Reference
- iPXE Documentation
- iPXE Chainloading Guide
- Ignition Documentation
- Butane Documentation
- systemd-boot Documentation
- Syslinux Documentation