From 27703c437a19a0bcac265dc2dc849f3de12adac9 Mon Sep 17 00:00:00 2001 From: Miles Ward Date: Sun, 14 Jun 2026 08:15:43 -0400 Subject: [PATCH] docs(compose): simplify root docker-compose to one pull-based service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The root compose was scratch-built and carried both a prod and a dev service plus a local build stanza. Replace it with a single deployment-focused service that pulls gitea.milesward.dev/mward4/openpxe:latest (matching the Unraid template and the homelab flow): - drop the openpxe-dev service and the build: context (deploy, not build) - HTTP on 4200 so it clears an Unraid webGUI / reverse proxy on :80 - host networking (DHCPDISCOVER is broadcast — bridges don't forward it) - cap_add NET_BIND_SERVICE instead of privileged; the binary already carries cap_net_bind_service as a file capability - OPENPXE_PUBLIC_IP stays a required, fail-fast variable - isos + work bind mounts (SMB dir omitted — Windows boots via HTTP sanboot since v0.5.8, no SMB server needed) Co-Authored-By: Claude Opus 4.8 (1M context) --- docker-compose.yml | 78 ++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 51 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 14cdc51..462e4b6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,66 +1,42 @@ -# docker-compose for local / homelab deployment. +# OpenPXE — single-host / homelab deployment. # -# Two usage patterns: +# One container: DHCP proxy + TFTP + iPXE chainload + HTTP (web UI, boot +# scripts, and ISO range streaming). # -# 1. Local MVP test — host network, proxy-DHCP off (don't fight your -# existing DHCP server on the LAN), TFTP + HTTP exposed on the host: +# OPENPXE_PUBLIC_IP=192.168.1.49 docker compose up -d # -# docker compose up openpxe-dev +# (or put OPENPXE_PUBLIC_IP in a .env file beside this one). That's this +# host's LAN IP, advertised to PXE clients so the iPXE URLs resolve — +# OpenPXE refuses to start rather than advertise an address clients can't +# reach, so compose errors out below if it's unset. # -# 2. Real PXE deployment — host network, proxy-DHCP on, runs on a box -# plugged into the PXE network: +# Host networking is REQUIRED: DHCPDISCOVER is a broadcast, and Docker +# bridges / CNI overlays don't forward it into containers. In host mode +# the container binds these ports directly on the host: # -# # First set OPENPXE_PUBLIC_IP to this host's LAN address in .env -# docker compose up openpxe +# udp/67 DHCP proxy udp/4011 PXE Boot Server +# udp/69 TFTP tcp/4200 web UI + HTTP boot assets # -# On Linux hosts, `network_mode: host` gives the container direct access to -# the physical NIC — required for DHCP proxy because CNI overlays and Docker -# bridges do not forward DHCPDISCOVER broadcasts into containers. -# -# On macOS / Windows hosts, `network_mode: host` is limited — the daemon -# runs in a Linux VM (Colima/Docker Desktop) so the "host" network is the -# VM, not your Mac. Proxy-DHCP is not feasible on macOS; use `openpxe-dev` -# with published ports and set DHCP-MODE=disabled. +# Web UI: http://:4200/ services: - # Real PXE deployment (Linux hosts). openpxe: - image: openpxe:0.1.0 - build: - context: . - dockerfile: deploy/docker/Dockerfile + image: gitea.milesward.dev/mward4/openpxe:latest + container_name: openpxe restart: unless-stopped network_mode: host + # The binary carries cap_net_bind_service as a file capability, so it + # binds the low DHCP/TFTP ports as a non-root user — no privileged mode. + cap_add: + - NET_BIND_SERVICE environment: - # REQUIRED on multi-homed hosts. Set to this machine's LAN IP so the - # advertised iPXE URLs actually resolve from the PXE clients. Without - # this, OpenPXE will refuse to start rather than advertise a - # loopback address that can't be reached. - OPENPXE_PUBLIC_IP: ${OPENPXE_PUBLIC_IP:?set this to the host LAN IP} + OPENPXE_PUBLIC_IP: ${OPENPXE_PUBLIC_IP:?set this to the host LAN IP, e.g. 192.168.1.49} + # Web UI + HTTP boot assets. 4200 keeps clear of anything on :80 + # (an Unraid webGUI, a reverse proxy, …). + OPENPXE_HTTP_PORT: "4200" + # proxy = coexist with the LAN's existing DHCP server (recommended). OPENPXE_DHCP_MODE: proxy OPENPXE_LOG: info volumes: - - ./data/isos:/var/lib/openpxe/isos - - ./data/work:/var/lib/openpxe/work - - # Dev / MVP container: published ports, DHCP disabled, HTTP on 8080. - # Use this on laptops where you want to curl the API or UI without - # running an actual PXE chain. - openpxe-dev: - image: openpxe:0.1.0 - build: - context: . - dockerfile: deploy/docker/Dockerfile - environment: - OPENPXE_PUBLIC_IP: ${OPENPXE_PUBLIC_IP:-127.0.0.1} - OPENPXE_DHCP_MODE: disabled - OPENPXE_HTTP_PORT: "8080" - OPENPXE_TFTP_PORT: "6969" - OPENPXE_DHCP_PORT: "6767" - OPENPXE_LOG: info,openpxe=debug - ports: - - "8080:8080/tcp" - - "6969:6969/udp" - volumes: - - ./data/isos:/var/lib/openpxe/isos - - ./data/work:/var/lib/openpxe/work + - ./data/isos:/var/lib/openpxe/isos # uploaded / seeded .iso files + - ./data/work:/var/lib/openpxe/work # settings, share state, scratch