Are you tired of using bootable USB medium every time you want to install Linux based operating system?. Here we present to you a solution that will ease your journey to automated Linux and Unix systems installation on baremetal or Virtualized environments. This will surely save you lots of time and makes the process of OS installation interesting and fast.
The tool that we are talking about in none other than netboot.xyz. This software was created to enable its users to boot into many types of operating systems through its lightweight tooling that gets you up and running in seconds or minutes depending on the speed of your internet. You can explore and test any operating system without the need to download ISO and rewrite media over and over again. netboot.xyz is also usable in rescue operating systems which is key in sysadmin roles.
The netboot.xyz tooling uses iPXE project to provide a user friendly menu within BIOS from where you can choose an operating system to install while customizing boot flags. This is made possible by the Preboot Execution Environment (PXE) available on most systems over the network. We’ve created this article to demonstrate how you can perform the installation, configurations and using netboot.xyz iPXE on Ubuntu or Debian
In our installation we take good advantage of Docker or ansible to setup netboot.xyz iPXE environment on Ubuntu or Debian Linux machine. These methods automates generation of custom templates from default configurations but you can override them. This enables you customize a netboot.xyz environment to suit your specifications.
1. Updating your system
Login to your server where netboot.xyz is to be configured and update it.
sudo apt update && sudo apt upgrade -y
Sometimes a reboot is required after an update.
[ -f /var/run/reboot-required ] && sudo reboot -f
2. Setup netboot.xyz environment
We shall consider two methods to achieve this.
Method 1: Using Docker container (recommended)
To install Docker Engine run the commands below as discussed in the article How To Install Docker Engine on Linux Systems.
Ubuntu:
sudo apt update
sudo apt -y install lsb-release gnupg apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER
newgrp docker
Debian:
sudo apt update
sudo apt install lsb-release gnupg2 apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/debian.gpg
sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER
newgrp docker
Check version of docker to confirm installation was successful.
$ docker --version
Docker version 25.0.0, build e758fe5
Create directory that will have container contents.
mkdir ~/netboot_xyz && ~/netboot_xyz
Create docker compose file
vim docker-compose.yml
Here are the contents you can modify.
---
services:
netbootxyz:
image: ghcr.io/netbootxyz/netbootxyz
container_name: netbootxyz
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
volumes:
- ./config:/config
- ./assets:/assets #optional
ports:
- 3000:3000
- 69:69/udp
- 80:80 #optional
restart: unless-stopped
Parameters used:
Ports (-p
)
Parameter | Function |
---|---|
3000 | Web configuration interface. |
69/udp | TFTP Port. |
80 | NGINX server for hosting assets. |
Environment Variables (-e
)
Env | Function |
---|---|
PUID=1000 | for UserID – see below for explanation |
PGID=1000 | for GroupID – see below for explanation |
TZ=Etc/UTC | specify a timezone to use, see this list. |
Volume Mappings (-v
)
Volume | Function |
---|---|
/config | Storage for boot menu files and web application config |
/assets | Storage for NETBOOT.XYZ bootable assets (live CDs and other files) |
Pull container image.
jkmutai@pxe:~/netboot_xyz$ docker compose pull
[+] Pulling 4/4
✔ netbootxyz 3 layers [⣿⣿⣿] 0B/0B Pulled 31.2s
✔ 661ff4d9561e Pull complete 3.2s
✔ c5bf41c866f3 Pull complete 26.2s
✔ 6bd6a73a9b6f Pull complete 2.3s
Start the containers using the commands below.
$ docker compose up -d
[+] Running 1/2
⠼ Network netboot_xyz_default Created 0.4s
✔ Container netbootxyz Started
You can check the status of the commands as below.
$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
netbootxyz ghcr.io/netbootxyz/netbootxyz "sh /start.sh" netbootxyz About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:69->69/udp, :::69->69/udp, 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
Access Web configuration interface on http://serverIP:3000

Next go to step 3
Method 2: Using Ansible Playbook (just for reference)
Install Python 3 and pip module.
sudo apt install python3 python3-pip
Use pip python package manager to install Ansible.
pip3 install --user ansible
Add ~/.local/bin
to your PATH which is not there by default.
### Bash ###
echo 'export PATH=$PATH:~/.local/bin' >>~/.bashrc
### Zsh ###
echo 'export PATH=$PATH:~/.local/bin' >>~/.zshrc
Source the bash or zsh profile to use installed ansible binary.
### Bash ###
source ~/.bashrc
### Zsh ###
source ~/.zshrc
Test installation success by checking ansible version.
$ ansible --version
ansible [core 2.16.2]
config file = None
configured module search path = ['/home/jkmutai/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/jkmutai/.local/lib/python3.10/site-packages/ansible
ansible collection location = /home/jkmutai/.ansible/collections:/usr/share/ansible/collections
executable location = /home/jkmutai/.local/bin/ansible
python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
jinja version = 3.0.3
libyaml = True
Install git which is used to clone netboot.xyz code from github.
sudo apt install git
Check out the netboot.xyz github repository.
git clone https://github.com/netbootxyz/netboot.xyz.git
Switch your working directory to netboot.xyz.
cd netboot.xyz
Here is the Ansible role structure
The ansible role used to setup netbootxyz environment has the following major components;
- defaults/main.yml – Consists default settings for deployment, OS versions, Utilities, and Bootloaders
- tasks/* – Contains all tasks for rendering templates and compiling iPXE bootloaders
- templates/disks – Templates for iPXE bootloaders
- templates/menus – Templates for netboot.xyz menus
- vars/* – Contain required package lists needed to support the compile and deployment of netboot.xyz
To override the defaults, provide your overrides in user_overrides.yml
. See user_overrides.yml for examples.
# set desired site name
site_name: ipxe.lab.example.com
# set desired boot domain
boot_domain: lab.example.com
bootloader_tftp_enabled: true
bootloader_https_enabled: true
bootloader_http_enabled: true
Setup your netbootxyz environment on Ubuntu or Debian system by running the ansible playbook using the commands below.
### Running as root user ###
ansible-playbook -i inventory site.yml
### Running as normal user with sudo password ###
ansible-playbook -i inventory site.yml --become --ask-become-pass
The executed playbook will do the following;
- Generate menus for netboot.xyz environment using default configuration settings
- Generate iPXE Bootloaders for booting into that environment
- Generate customized menu options for those who have additional options they want to add
A successful installation will have failed=0
in the output.

All generated content will be placed in the default web server root – /var/www/html
ls -lh /var/www/html
Example iPXE file for Ubuntu Linux.
cat /var/www/html/ubuntu.ipxe
You can open http://serverIP and http://serverIP/ipxe/ in your browser to see contents graphically.

Install TFTP Server
A tftp server is needed to host the iPXE files. We can also use dnsmasq
sudo apt -y install dnsmasq
Then edit configuration to /etc/dnsmasq.conf and set as below.
$ sudo vim /etc/dnsmasq.conf
enable-tftp
tftp-root=/var/www/html/
dhcp-boot=netboot.xyz.kpxe
Change systemd-resolved link to avoid conflicting on port 53
sudo ln -fs /run/systemd/resolve/resolv.conf /etc/resolv.conf
Restart both services
sudo systemctl restart dnsmasq systemd-resolved
3. Configure TFTP on DHCP Server
To PXE boot a system you will need an existing DHCP server where you can set this TFTP server as your DHCP boot destination. Our setup only provides a TFTP server hosting with the latest IPXE kernel builds from netboot.xyz.
There is an option of setting up your own DHCP server and configuring next-server parameter in the settings. See example below.
option arch code 93 = unsigned integer 16;
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.34 192.168.0.254; # Change this range as appropriate for your network
next-server 192.168.1.254; # Change this to the address of your netboot.xyz TFTP server
option subnet-mask 255.255.255.0;
option routers 192.168.1.1; # Change this to the address of your router
option broadcast-address 192.168.1.255;
option domain-name "mylab.example.com"; # This is optional
option domain-name-servers 1.1.1.1;
if exists user-class and ( option user-class = "iPXE" ) {
filename "http://boot.netboot.xyz/menu.ipxe";
} elsif option arch = encode-int ( 16, 16 ) {
filename "http://boot.netboot.xyz/ipxe/netboot.xyz.efi";
option vendor-class-identifier "HTTPClient";
} elsif option arch = 00:07 {
filename "netboot.xyz.efi";
} else {
filename "netboot.xyz.kpxe";
}
}
Where 192.168.1.254 is the IP address of netboot.xyz server.
Some router setup examples
Let’s consider some router examples on how to update DHCP server settings to configure next server address pointing to our TFFP server with boot file names.
netboot.xyz boot file types
Below is a list of bootfile names you can set as the boot file in the DHCP configuration.
bootfile name | description |
---|---|
netboot.xyz.kpxe | Legacy DHCP boot image file, uses built-in iPXE NIC drivers |
netboot.xyz-undionly.kpxe | Legacy DHCP boot image file, use if you have NIC issues |
netboot.xyz.efi | UEFI boot image file, uses built-in UEFI NIC drivers |
netboot.xyz-snp.efi | UEFI w/ Simple Network Protocol, attempts to boot all net devices |
netboot.xyz-snponly.efi | UEFI w/ Simple Network Protocol, only boots from device chained from |
netboot.xyz-arm64.efi | DHCP EFI boot image file, uses built-in iPXE NIC drivers |
netboot.xyz-arm64-snp.efi | UEFI w/ Simple Network Protocol, attempts to boot all net devices |
netboot.xyz-arm64-snponly.efi | UEFI w/ Simple Network Protocol, only boots from device chained from |
netboot.xyz-rpi4-snp.efi | UEFI for Raspberry Pi 4, attempts to boot all net devices |
OPNsense
Navigate to Services -> DHCP Server, then choose the network name to change DHCP settings for. Set TFTP server IP

Set IP address of your server under “Network Booting” > Advanced section.

Set as below.
- Tick to enable network booting
- Set next-server IP to your server IP address
- Set Default BIOS file name to
netboot.xyz.kpxe
- Set UEFI 32 and 64 bit filename to
netboot.xyz.efi

PFSense
The settings are similar to OPNsense. See screenshot below.

Unifi Security Gateway (with the controller)
Navigate to Networks -> LAN (or other network you need to boot from) -> ADVANCED DHCP OPTIONS
- Tick to enable network boot
- Server – Set YOURSERVERIP
- Filename-
netboot.xyz.kpxe
4. Install Operating System using netboot.xyz
For baremetal enable network boot in BIOS settings and power on the server.
For Virtual Machine environment, create a VM without an ISO, then change boot order to start with Network boot.

Next start the VM and PXE boot process should begin immediately.

Next you are presented with netboot.xyz menu.

Choose Distribution to install or Tools image if you need to boot into a live image and perform system repair or data recovery.