
September 11, 2026
12 min read
By Kokil Thapa | Last reviewed: September 2026
Provisioning ten identical web servers by hand wastes hours and drifts configuration. PXE Boot for Automated OS Installs solves that by letting bare-metal machines fetch a boot loader over the network, pull a kernel and installer, and apply an unattended answer file. On production Linux system administration work—shared EC2 sister sites and client racks alike—the pattern mirrors what you already do with Git and Deployer: define the target state once, then repeat it reliably. This guide walks through a practical Ubuntu 24.04 LTS stack using dnsmasq, TFTP, and HTTP preseed files you can run on a single management host.
What is PXE boot and how does automated OS installation work?
PXE—Preboot eXecution Environment—extends the firmware boot path. The NIC broadcasts a DHCP discover packet. The DHCP server replies with an IP lease plus boot server and boot file names. The client downloads that file over TFTP, executes it, loads a Linux kernel and initrd, and starts the distribution installer.
The automation layer sits in the answer file. Debian and Ubuntu use preseed. Red Hat family uses kickstart. You declare locale, disk layout, packages, users, and post-install scripts. The installer never prompts. Every machine lands in the same baseline state.
That matters when you refresh hardware, rebuild a staging rack, or onboard a new VPS host colocated in Kathmandu next to your primary stack. Manual installs invite typos. PXE removes variance. It also pairs well with post-install tools like Ansible or cloud-init for application layers—topics adjacent to CI/CD caching for fast Composer and npm installs once PHP 8.3+ and Laravel 13.x runtimes are in place.
Core protocols you must understand
- DHCP — assigns IPv4 and tells the client where to fetch boot files via options 66 (next-server) and 67 (filename).
- TFTP — small, UDP-based transfer for boot loaders; keep payloads tiny.
- HTTP or NFS — serves large kernel, initrd, and ISO contents; HTTP is simpler on firewalled LANs.
- Preseed / kickstart — declarative install answers consumed by the installer.
The original PXE spec builds on BOOTP, documented in RFC 951. Modern shops often chain into iPXE for HTTPS and scriptable menus. That flexibility beats legacy pxelinux when you juggle multiple Ubuntu LTS tracks.
How do you set up a PXE server on Ubuntu for automated installs?
A single management VM on your LAN can host every role. I prefer dnsmasq because it combines DHCP and TFTP in one daemon with a small config surface. Separate nginx or Apache serves HTTP assets. Isolate this host on a dedicated VLAN when possible.
Before you start, mirror the target release. For Ubuntu 24.04 LTS, sync the netboot mini.iso tree or extract linux and initrd.gz from the installer. Store checksums. Pin versions the same way you pin PHP 8.3 on application servers.
Step 1 — Install packages and create directory layout
- Install dnsmasq, nginx, and syslinux-common on Ubuntu 24.04.
- Create
/srv/pxe/tftpfor boot loaders and/srv/pxe/httpfor kernels, initrd, and preseed files. - Copy
pxelinux.0,ldlinux.c32, and menu modules from syslinux into the TFTP root.
sudo apt update
sudo apt install dnsmasq nginx syslinux-common pxelinux
sudo mkdir -p /srv/pxe/tftp/pxelinux.cfg
sudo mkdir -p /srv/pxe/http/ubuntu/noble/{amd64,preseed}
sudo cp /usr/lib/PXELINUX/pxelinux.0 /srv/pxe/tftp/
sudo cp /usr/lib/syslinux/modules/bios/ldlinux.c32 /srv/pxe/tftp/
sudo cp /usr/lib/syslinux/modules/bios/{menu.c32,libutil.c32} /srv/pxe/tftp/ Step 2 — Configure dnsmasq DHCP and TFTP
Bind dnsmasq only to your provisioning interface. Never run two DHCP servers on the same broadcast domain. That mistake blackholes laptops and printers.
# /etc/dnsmasq.d/pxe.conf
interface=eno1
bind-interfaces
dhcp-range=192.168.50.100,192.168.50.200,255.255.255.0,12h
dhcp-option=option:router,192.168.50.1
dhcp-boot=pxelinux.0,pxeserver,192.168.50.10
enable-tftp
tftp-root=/srv/pxe/tftp
log-dhcp Restart and watch logs during a test boot:
sudo systemctl restart dnsmasq
sudo journalctl -u dnsmasq -f Step 3 — Write pxelinux menu and nginx location
The default menu entry points the installer at your preseed URL. Use the auto=true kernel parameter for fully unattended mode.
# /srv/pxe/tftp/pxelinux.cfg/default
DEFAULT menu.c32
PROMPT 0
TIMEOUT 50
ONTIMEOUT ubuntu-noble-auto
LABEL ubuntu-noble-auto
MENU LABEL Ubuntu 24.04 Unattended
KERNEL http://192.168.50.10/ubuntu/noble/amd64/linux
APPEND initrd=http://192.168.50.10/ubuntu/noble/amd64/initrd.gz \
auto=true priority=critical \
url=http://192.168.50.10/ubuntu/noble/preseed/noble.seed \
netcfg/choose_method=auto \
debian-installer/locale=en_US.UTF-8 Expose HTTP under nginx with directory listing disabled:
# /etc/nginx/sites-available/pxe
server {
listen 80;
server_name pxeserver.internal;
root /srv/pxe/http;
location / {
autoindex off;
}
} Enable the site, test config, reload nginx—the same discipline as installing Nginx on Ubuntu for Laravel apps. Then place kernel artifacts under /srv/pxe/http/ubuntu/noble/amd64/.
Which preseed or kickstart configuration drives unattended installation?
Preseed files are plain text debconf answers. Order matters for early directives like locale and keyboard. Late commands run chrooted scripts—ideal for injecting SSH keys, disabling root login, or registering the host with your monitoring stack.
Minimal Ubuntu 24.04 preseed example
# /srv/pxe/http/ubuntu/noble/preseed/noble.seed
d-i debian-installer/locale string en_US.UTF-8
d-i keyboard-configuration/xkb-keymap select us
d-i netcfg/choose_interface select auto
d-i mirror/http/hostname string archive.ubuntu.com
d-i mirror/http/directory string /ubuntu
d-i partman-auto/method string regular
d-i partman-auto/choose_recipe select atomic
d-i partman/confirm_write_new_label boolean true
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i pkgsel/include string openssh-server curl git ufw
d-i pkgsel/upgrade select full-upgrade
d-i grub-installer/only_debian boolean true
d-i user-setup/allow-password-weak boolean false
d-i passwd/user-fullname string Deploy User
d-i passwd/username string deploy
d-i passwd/user-password-crypted password $6$rounds=4096$...
d-i preseed/late_command string \
in-target ufw --force enable; \
in-target mkdir -p /home/deploy/.ssh; \
in-target sh -c 'echo "ssh-ed25519 AAAA..." >> /home/deploy/.ssh/authorized_keys' Generate password hashes with mkpasswd -m sha-512. Never store cleartext passwords in Git. For stronger secrets at scale, fetch short-lived tokens from your vault during late_command. The same hygiene applies when you rotate database credentials on MySQL servers on Ubuntu.
Official reference material lives in the Debian preseed documentation. Ubuntu inherits most directives unchanged.
Kickstart on RHEL-family hosts
If you standardise on Rocky or AlmaLinux, swap preseed for kickstart. Place inst.ks=http://pxeserver/kickstart/host.cfg on the kernel line. Partition with autopart or explicit part lines. %post scripts mirror late_command.
Post-install alignment with application stacks
After the OS lands, layer runtimes. Install PHP 8.3, Composer 2.10, and MySQL 8.4 LTS using your existing playbooks. Sites on shared Deployer pipelines—like the legal-tech sister properties described in my Translation Nepal portfolio case—benefit from identical PHP-FPM pools across nodes. PXE gives you that parity on day zero.
How does PXE compare to USB installs, cloud images, and MAAS?
PXE is not the only automation path. Pick based on hardware access, cloud mix, and team skill. The table below summarises trade-offs I use when scoping enterprise application deployments.
| Method | Best for | Pros | Cons |
|---|---|---|---|
| USB / manual | 1–2 machines, laptops | Simple, no infra | Slow, inconsistent |
| PXE + preseed | On-prem racks, colo | Fast repeat, low cost | Needs VLAN discipline |
| Cloud vendor images | AWS, GCP, Azure VMs | API-driven, elastic | Vendor lock-in facets |
| Canonical MAAS | Large bare-metal fleets | Inventory, IPAM, UI | Heavier ops overhead |
| Immutable images (Packer) | Hybrid cloud + metal | Golden AMI QCOW2 | Build pipeline required |
For Nepali SMB clients with a single Dell tower running WooCommerce 11.1, USB still wins. For a three-node cluster serving Laravel queues and Redis 8.10, PXE pays back after the second rebuild. Hybrid shops boot PXE on metal and cloud-init on VMs—both feed the same Ansible roles.
Cloud-init overlaps conceptually but targets hypervisor metadata services, not legacy BIOS PXE ROMs. Treat them as complementary layers in a support and maintenance playbook rather than competing religions.
What are common PXE boot failures and how do you fix them?
Most PXE outages are DHCP scope collisions, wrong boot filenames, or firmware mode mismatches. Work top-down: link light, DHCP log, TFTP transfer, then HTTP 200 on kernel URLs.
Failure checklist
- No DHCP offer — second DHCP server on VLAN; bind dnsmasq to one interface; disable rogue router DHCP.
- TFTP timeout — file permissions on
/srv/pxe/tftp; SELinux/AppArmor denials; firewall blocking UDP 69. - Boot hangs after menu — BIOS vs UEFI mismatch; use syslinux for BIOS and grub EFI binaries for UEFI.
- Installer cannot fetch preseed — nginx root path typo; client lacks route to HTTP server during early netboot.
- Disk not found — missing storage drivers in initrd; switch to full installer initrd or HWE kernel.
UEFI systems often need a separate DHCP filename such as ipxe.efi or grubx64.efi. Maintain parallel trees under /srv/pxe/tftp/efi/. Document which profile each rack slot uses—same rigour as tracking PHP-FPM socket paths after PHP installs on Ubuntu.
When a host boots the wrong OS version, checksum your HTTP artifacts weekly. Store SHA256 manifests beside ISOs. If a nightly sync corrupts initrd.gz, every downstream install fails identically—that is hard to debug without version pins.
Security hardening on the PXE host itself
The PXE server is high trust. Restrict SSH. Allow TFTP and HTTP only from the provisioning subnet. Sign iPXE scripts when you graduate beyond lab setups. Audit late_command snippets— they run as root inside the installer context.
Segmentation beats clever crypto on a flat LAN. I have seen office DHCP pools accidentally serve production pxelinux paths. The fix was VLAN 50 for staging only, documented in runbooks beside automated server backup procedures.
Scaling beyond one site
Replicate HTTP mirrors regionally if bandwidth to Kathmandu uplinks is tight. Use rsync cron jobs from a golden mirror. For international clients—flower eCommerce stacks like Petals Agro Nepal—keep PXE assets versioned in Git with tagged releases, identical to application deploy tags.
Generate random root passwords during install if humans never log in locally. Store them in your team vault generated via a proper secret workflow; a password generator tool helps draft policy-compliant lengths before you automate vault writes.
Key Takeaways
- PXE chains DHCP, TFTP, and HTTP to boot an unattended installer with preseed or kickstart—define once, replay on every bare-metal node.
- Run dnsmasq and nginx on an isolated provisioning VLAN so you never fight office DHCP or production traffic.
- Pin kernel, initrd, and preseed URLs with checksums; drift in one file breaks every parallel install simultaneously.
- Split BIOS and UEFI boot artifacts; most “PXE broken” tickets are firmware mode mismatches, not mystery gremlins.
- Treat post-install hardening—SSH, UFW, SSL, backups—as part of the same pipeline, not a separate weekend chore.
- PXE complements cloud-init and golden AMI workflows; use PXE on metal, cloud metadata on VMs, one Ansible layer above both.
People Also Ask
Do I need special hardware for PXE boot?
Most server and desktop NICs ship with a PXE ROM enabled in firmware. Toggle network boot in BIOS or UEFI boot order. USB Ethernet adapters often lack PXE support—use onboard NICs for racks. Wi-Fi PXE exists but is rare in data centres; stick to wired gigabit for reliability.
Can PXE install Windows as well as Linux?
Yes. Windows Deployment Services and Microsoft Deployment Toolkit use PXE with boot.wim images. Linux-focused teams still use PXE for Ubuntu and Debian while SCCM or WDS handles Windows clients. Mixed fleets can share one DHCP server with per-MAC filenames pointing at different boot loaders.
Is PXE secure enough for production networks?
PXE alone is not encrypted; anyone on the VLAN can sniff TFTP transfers. Mitigate with isolated provisioning networks, short-lived VLANs, signed iPXE binaries, and HTTPS for stage-two payloads. Never expose the PXE HTTP mirror to the public internet without authentication.
How long does an automated PXE install take?
Ubuntu minimal installs over gigabit LAN typically finish in ten to twenty minutes depending on mirror speed, disk type, and package list. Full desktop metapackages take longer. Parallel installs scale linearly until HTTP or disk mirror throughput saturates—watch nginx access logs during batch builds.
Build repeatable infrastructure from day one
PXE Boot for Automated OS Installs turns rack provisioning from a hands-on chore into a versioned workflow you can audit and replay. Start with one dnsmasq host, one preseed file, and two test machines before you touch production. Layer PHP, Nginx, and your Deployer pipeline only after SSH and backups verify clean. If you want help designing provisioning VLANs, golden images, or the Laravel stack that sits on top, contact us or review domain and hosting services for colocated hardware planning. Related reading: Docker on Ubuntu, SSL on Ubuntu, and the home page for broader DevOps notes. Strong infrastructure starts before the first git push.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

