🧰 PXE Boot & Install Ubuntu Desktop 25.10 (HTTP ISO, No NFS)
- 🪜 1. Install prerequisites
- 🧩 2. Find your PXE server IP and interface
- 🏗️ 3. Download and expose the Ubuntu Desktop ISO
- ⚙️ 4. Prepare TFTP root and signed EFI bootloaders
- 🧱 5. (Optional) Copy kernel & initrd from the ISO
- 📄 6. Configure GRUB menu
- 📡 7. Configure dnsmasq DHCP/TFTP
- 🚀 8. Boot the client PC
- 🌐 9. Fix networking after PXE boot
- 🧹 10. Cleanup PXE server when done
- ⚙️ 11. Disable Cloud-Init inside PXE-booted Ubuntu Desktop
- 🕒 Boot Performance (reference)
- ✅ Working Setup Summary
- 🧠 Notes & Troubleshooting
- 🏁 Example Successful Boot Sequence
This guide explains how to set up a minimal PXE environment to boot Ubuntu Desktop Live ISOs (24.04–25.10) entirely over HTTP, without NFS or IP forwarding.
It works using only dnsmasq (for DHCP+TFTP) and apache2 (for HTTP), and supports both Ethernet and Wi-Fi PXE servers.
✅ Tested on:
-
Ubuntu 24.04, 25.04 and 25.10 Desktop & Server
-
Both Wi-Fi (
wlp0s20f3) and USB-C Ethernet (enx0…) as PXE servers;
NOTE: You must use Ethernet as PXE client! -
Clients booting via UEFI Secure Boot
-
NVIDIA RTX 4090 and other GPUs
🪜 1. Install prerequisites
sudo apt update
sudo apt install dnsmasq apache2
🧩 2. Find your PXE server IP and interface
List your active connections:
nmcli connection show
ip -4 a
Pick your serving interface:
-
Wi-Fi → usually
wlp0s20f3 -
Wired →
enx0…oreno1
Find its IP (e.g. 192.168.8.117) — this will be PXE_SERVER_IP in the config below.
🏗️ 3. Download and expose the Ubuntu Desktop ISO
sudo mkdir -p /srv/http/ubuntu
cd /srv/http/ubuntu
wget https://releases.ubuntu.com/25.10/ubuntu-25.10-desktop-amd64.iso
Link for Apache (no restart required):
sudo ln -sv /srv/http/ubuntu /var/www/html/ubuntu
Confirm:
curl -I http://192.168.8.117/ubuntu/ubuntu-25.10-desktop-amd64.iso
⚙️ 4. Prepare TFTP root and signed EFI bootloaders
sudo mkdir -p /srv/tftp/amd64/grub
cd ~/signed-efi
apt download shim-signed grub-efi-amd64-signed
dpkg-deb --fsys-tarfile shim-signed_*_amd64.deb | tar -x ./usr/lib/shim/shimx64.efi.signed.latest
dpkg-deb --fsys-tarfile grub-efi-amd64-signed_*_amd64.deb | tar -x ./usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed
sudo cp usr/lib/shim/shimx64.efi.signed.latest /srv/tftp/amd64/shimx64.efi
sudo cp usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /srv/tftp/amd64/grubx64.efi
🧱 5. (Optional) Copy kernel & initrd from the ISO
This makes booting faster since the kernel/initrd don’t need to be downloaded each time.
sudo mkdir -p /srv/tftp/amd64/desktop /mnt/iso
sudo mount -o loop /srv/http/ubuntu/ubuntu-25.10-desktop-amd64.iso /mnt/iso
sudo cp /mnt/iso/casper/{vmlinuz,initrd} /srv/tftp/amd64/desktop/
sudo umount /mnt/iso
sudo chmod 644 /srv/tftp/amd64/desktop/{vmlinuz,initrd}
📄 6. Configure GRUB menu
/srv/tftp/amd64/grub/grub.cfg
set default=0
set timeout=5
# Use the Desktop ISO's kernel+initrd you copied to /srv/tftp/amd64/desktop/
# Pure-HTTP boot like 24.04 guides (no NFS)
menuentry "Ubuntu 25.10 Desktop (HTTP ISO, casper)" {
linux /desktop/vmlinuz boot=casper rd.neednet=1 ip=dhcp url=http://192.168.8.117/ubuntu/ubuntu-25.10-desktop-amd64.iso live-media-path=/casper rootfs_name=minimal.squashfs maybe-ubiquity ---
initrd /desktop/initrd
}
# Fallback: same idea but with the netboot kernel/initrd from the tarball
menuentry "Ubuntu 25.10 Desktop (HTTP ISO via netboot kernel)" {
linux /linux boot=casper rd.neednet=1 ip=dhcp url=http://192.168.8.117/ubuntu/ubuntu-25.10-desktop-amd64.iso live-media-path=/casper rootfs_name=minimal.squashfs toram ---
initrd /initrd
}
This works too:
# cat /srv/tftp/amd64/grub/grub.cfg
set default=0
set timeout=5
menuentry "Ubuntu 25.10 Desktop (HTTP ISO, casper)" {
linux /linux ip=dhcp boot=casper iso-url=http://192.168.8.129/ubuntu/ubuntu-25.10-desktop-amd64.iso toram ---
initrd /initrd
}
(Replace 192.168.8.117 with your own PXE_SERVER_IP.)
📡 7. Configure dnsmasq DHCP/TFTP
/etc/dnsmasq.d/pxe.conf
interface=wlp0s20f3 # or your Ethernet NIC
bind-interfaces
dhcp-range=192.168.8.100,192.168.8.150,12h
dhcp-boot=shimx64.efi,,192.168.8.117 # PXE server IP (next-server)
enable-tftp
tftp-root=/srv/tftp/amd64
tftp-no-blocksize # fixes buggy PXE stacks (no blksize OACK)
log-dhcp
dhcp-authoritative
Restart dnsmasq:
sudo systemctl restart dnsmasq
🚀 8. Boot the client PC
-
Enter BIOS/UEFI → enable PXE Boot (UEFI IPv4).
-
Use F12/F8 to open boot menu → select PXE IPv4.
-
You should see:
Fetching shimx64.efi Fetching grubx64.efithen the GRUB menu.
Select Ubuntu 25.10 Desktop (HTTP ISO, casper).
It will:
-
Load kernel/initrd over TFTP (~7 min on Wi-Fi)
-
Download ISO via HTTP (~2–3 min)
-
Boot to the full Ubuntu Desktop Live session
🌐 9. Fix networking after PXE boot
A) If PXE server is on Wi-Fi (and client has Wi-Fi)
List your connections and prioritize Wi-Fi:
nmcli connection show
nmcli connection modify "Wi-Fi connection" ipv4.route-metric 100
nmcli connection down "Wi-Fi connection"
nmcli connection up "Wi-Fi connection"
This ensures Internet uses Wi-Fi, not the PXE Ethernet.
B) If client is Ethernet-only
The PXE server’s DHCP assigns itself as the gateway (e.g. 192.168.8.117).
Remove that route so your router takes over (e.g. 192.168.8.1):
ip route
ip route delete default via 192.168.8.117 dev eno1
ip route show default
# should now show: default via 192.168.8.1 dev eno1
Now the installer has Internet connectivity while keeping PXE active.
🧹 10. Cleanup PXE server when done
When you no longer need PXE boot:
sudo systemctl stop dnsmasq apache2
sudo apt remove dnsmasq apache2
sudo rm -rf /root/signed-efi /srv/tftp /srv/http /var/www/html/ubuntu /etc/dnsmasq.d/pxe.conf
⚙️ 11. Disable Cloud-Init inside PXE-booted Ubuntu Desktop
When Ubuntu Desktop is booted via PXE, cloud-init may run automatically even though this is a local live session.
This can cause:
-
Slow boot or stuck splash screen
-
Network reconfiguration that breaks connectivity
-
Extra cloud metadata lookups
To disable and remove it cleanly:
sudo systemctl disable --now cloud-config.service cloud-final.service cloud-init-local.service cloud-init-main.service cloud-init-network.service
sudo systemctl mask cloud-init.service
sudo systemctl reset-failed
sudo apt purge -y cloud-init
sudo rm -rf /etc/cloud /var/lib/cloud
Reboot once after this if you plan to keep using the PXE-booted session long-term.
🕒 Boot Performance (reference)
| Phase | Typical Duration |
|---|---|
| PXE kernel/initrd transfer | ~6–8 min (over Wi-Fi) |
| ISO download over HTTP | ~2–3 min |
| GUI live session ready | ~10 min total |
✅ Working Setup Summary
| Component | Example |
|---|---|
| PXE Server Interface | wlp0s20f3 (Wi-Fi) or enx0… (USB-C NIC) |
| PXE Server IP | 192.168.8.117 |
| Client IP (DHCP) | 192.168.8.100–150 |
| HTTP ISO URL | http://192.168.8.117/ubuntu/ubuntu-25.10-desktop-amd64.iso |
| RootFS | minimal.squashfs |
| Bootloader | Secure Boot shimx64.efi → grubx64.efi |
| Protocols | DHCP, TFTP, HTTP only |
| Works with | Ubuntu 22.04 → 25.10 Desktop Live ISOs |
🧠 Notes & Troubleshooting
-
tftp-no-blocksizeis essential for buggy UEFI PXE stacks that choke on OACK. -
If you get a black screen on NVIDIA GPUs → it’s loading; framebuffer may take ~1–2 min.
-
To show progress messages, append to the
linuxline:splash=off debug=1 --- -
Apache access log (
/var/log/apache2/access.log) confirms ISO download progress. -
PXE Desktop tip: disable cloud-init using Section 11 to prevent unwanted background reconfiguration.
🏁 Example Successful Boot Sequence
Fetching shimx64.efi
Fetching grubx64.efi
GRUB menu appears
Loading vmlinuz and initrd…
Downloading ubuntu-25.10-desktop-amd64.iso via HTTP…
Loopback detected capacity change
Starting casper (live session)...
Welcome to Ubuntu 25.10 Live!
Write a comment