Skip to content

Latest commit

 

History

History
265 lines (193 loc) · 6.01 KB

File metadata and controls

265 lines (193 loc) · 6.01 KB

Container Deployment Guide

This guide covers deploying the PXE boot server using Docker containers.

Architecture

The deployment consists of two containers:

  • TFTP Server: Serves iPXE bootloaders (undionly.kpxe, ipxe.efi, snponly.efi)
  • HTTP Server: Serves iPXE scripts, boot images, installation scripts, and cloud-init configurations

Directory Structure

/srv/
├── images/
│   └── debian/                     # Debian cloud images
│       ├── debian-13-generic-amd64.qcow2
│       └── debian-12-generic-amd64.qcow2
│
├── boot/                           # HTTP-served content
│   ├── ipxe/                       # iPXE menu scripts
│   ├── alpine/amd64/               # Alpine netboot files
│   ├── debian/                     # Extracted boot files
│   │   ├── 13/amd64/
│   │   └── 12/amd64/
│   ├── images/debian/              # Symlinked cloud images
│   ├── scripts/                    # Installation scripts
│   └── cloud-init/debian/          # Cloud-init configs
│       ├── 13/
│       └── 12/
│
└── tftp/                           # TFTP bootloaders
    ├── undionly.kpxe
    ├── ipxe.efi
    └── snponly.efi

Prerequisites

  • Docker and Docker Compose installed
  • DHCP server that can be configured for PXE boot
  • Server accessible on network (UDP/69 for TFTP, TCP/80 for HTTP)

Quick Start

1. Customize Configuration

All scripts and configuration files are mounted as volumes from your local repository. This allows you to edit files locally and simply restart containers without rebuilding.

Edit configuration files:

# Add SSH keys for Alpine rescue mode
vim config/alpine-rescue/authorized_keys

# Set root password (optional)
echo "yourpassword" > config/alpine-rescue/root_password

# Customize Debian cloud-init
vim cloud-init/debian/13/user-data

# Customize iPXE menu or install scripts
vim ipxe/menu.ipxe
vim scripts/install-debian-cloud-to-disk.sh

Apply changes:

# Just restart the affected container (no rebuild needed!)
docker compose restart http

# Or restart all containers
docker compose restart

2. Start Containers

docker compose up -d
docker compose logs -f

3. Verify Services

# Check HTTP server
curl http://localhost/health
curl http://localhost/boot/ipxe/menu.ipxe

# Check TFTP container
docker compose ps tftp

4. Configure DHCP Server

ISC DHCP:

next-server YOUR_SERVER_IP;
if option architecture-type = 00:00 {
    filename "undionly.kpxe";
} elsif option architecture-type = 00:07 {
    filename "ipxe.efi";
}

dnsmasq:

dhcp-boot=tag:BIOS,undionly.kpxe
dhcp-boot=tag:UEFI,ipxe.efi
tftp-server-name=YOUR_SERVER_IP

5. Test PXE Boot

Boot a machine via network boot and verify the installation completes successfully.

Management

View Logs

docker compose logs -f http
docker compose logs -f tftp

Restart Services

docker compose restart http
docker compose restart tftp

Update Configuration

If using volume mounts for configuration:

# Edit configuration files
vim config/alpine-rescue/authorized_keys

# Restart to regenerate overlay
docker compose restart http

Update Boot Images

Force re-download of boot images:

docker volume rm homelab-boot-server_images-data
docker volume rm homelab-boot-server_boot-data
docker compose restart http

Inspect Images

# View cached images
docker compose exec http ls -lh /srv/images/debian/

# View boot files
docker compose exec http ls -lh /srv/boot/debian/13/amd64/

Adding Debian 12 Support

The structure supports multiple versions. To enable Debian 12:

  1. Customize cloud-init:

    vim cloud-init/debian/12/user-data
  2. Update scripts/download-boot-images.sh to download Debian 12 image

  3. Rebuild:

    docker compose up -d --build

Runtime Customization

The HTTP container generates configuration at startup:

  • Alpine overlay (/srv/boot/alpine/alpine.apkovl.tar.gz) built from:
    • /opt/apkovl/ (source files)
    • /opt/config/alpine-rescue/ (customizations)

To customize:

  1. Edit local files
  2. Ensure volume mount is configured in docker-compose.yml
  3. Restart container: docker compose restart http
  4. Overlay regenerates automatically

No rebuild required.

Troubleshooting

HTTP Container Won't Start

docker compose logs http
docker compose exec http nginx -t

TFTP Container Issues

docker compose logs tftp
docker compose exec tftp ls -lh /srv/tftp/

Images Not Downloading

docker compose exec http tail -f /var/log/download-boot-images.log

Network Boot Fails

  1. Verify DHCP points to correct server IP
  2. Check firewall allows UDP/69 and TCP/80
  3. Test TFTP manually:
    tftp YOUR_SERVER_IP
    get undionly.kpxe

Production Considerations

  • Persistent Volumes: Images cached in Docker volumes for performance
  • Network Mode: TFTP uses host network mode for UDP compatibility
  • Resource Requirements: HTTP container needs ~10GB for image cache
  • Security: Consider HTTPS, authentication, and network isolation
  • Secrets: Use volume mounts to keep credentials out of images

Container Details

TFTP Container

  • Base: debian:13.2-slim
  • Size: ~100MB
  • Purpose: Serves iPXE bootloaders only
  • Network: Host mode (required for TFTP)
  • Volumes: tftp-data:/srv/tftp

HTTP Container

  • Base: nginx:1.29.4-trixie
  • Size: ~500MB + images
  • Purpose: Serves all boot files and installation scripts
  • Network: Bridge mode
  • Ports: 80/TCP
  • Volumes:
    • images-data:/srv/images (persistent)
    • boot-data:/srv/boot (can be regenerated)
  • Health Check: /health endpoint every 30s

See Also