Name update
This commit is contained in:
+19
-19
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
#
|
||||
# PXEForge — multi-stage build.
|
||||
# OpenPXE — multi-stage build.
|
||||
#
|
||||
# Design:
|
||||
# - stage `fetch`: runs scripts/fetch-ipxe.sh to pull official iPXE binaries
|
||||
@@ -8,7 +8,7 @@
|
||||
# - stage `build`: compiles the workspace with cargo in release mode.
|
||||
# - stage `runtime`: Debian slim image with setcap for NET_BIND_SERVICE,
|
||||
# running as a non-root UID. No shell in PATH for the service user;
|
||||
# attacker surface is just the pxeforge binary + libc.
|
||||
# attacker surface is just the openpxe binary + libc.
|
||||
#
|
||||
# Why not distroless? We want setcap support and easy debug (`oc rsh`).
|
||||
# Debian slim at ~75 MB + binary ~25 MB is fine for a PXE server that
|
||||
@@ -24,7 +24,7 @@ WORKDIR /src
|
||||
COPY scripts/fetch-ipxe.sh scripts/fetch-ipxe.sh
|
||||
RUN mkdir -p assets/ipxe && bash scripts/fetch-ipxe.sh
|
||||
|
||||
########## build pxeforge ##########
|
||||
########## build openpxe ##########
|
||||
FROM rust:${RUST_VERSION}-bookworm AS build
|
||||
WORKDIR /src
|
||||
|
||||
@@ -43,9 +43,9 @@ COPY --from=fetch /src/assets/ipxe /src/assets/ipxe
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/src/target,sharing=locked \
|
||||
find crates -name '*.rs' -exec touch {} + && \
|
||||
cargo build --release --bin pxeforge && \
|
||||
cp target/release/pxeforge /pxeforge && \
|
||||
ls -l /pxeforge
|
||||
cargo build --release --bin openpxe && \
|
||||
cp target/release/openpxe /openpxe && \
|
||||
ls -l /openpxe
|
||||
|
||||
########## runtime ##########
|
||||
FROM debian:12-slim AS runtime
|
||||
@@ -54,13 +54,13 @@ RUN apt-get update \
|
||||
ca-certificates libcap2-bin tini gosu iproute2 \
|
||||
wimtools samba nfs-common \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& useradd --system --uid 10001 --home-dir /var/lib/pxeforge --shell /usr/sbin/nologin pxeforge \
|
||||
&& mkdir -p /var/lib/pxeforge/isos /var/lib/pxeforge/work /var/lib/pxeforge/smb \
|
||||
&& chown -R pxeforge:pxeforge /var/lib/pxeforge
|
||||
&& useradd --system --uid 10001 --home-dir /var/lib/openpxe --shell /usr/sbin/nologin openpxe \
|
||||
&& mkdir -p /var/lib/openpxe/isos /var/lib/openpxe/work /var/lib/openpxe/smb \
|
||||
&& chown -R openpxe:openpxe /var/lib/openpxe
|
||||
# Runtime deps explained:
|
||||
# wimtools - provides `wimlib-imagex`, used to inject startnet.cmd into boot.wim.
|
||||
# samba - `smbd` serves extracted Windows install media on :445 for WinPE
|
||||
# to `net use`. Guest read-only, scoped to /var/lib/pxeforge/smb.
|
||||
# to `net use`. Guest read-only, scoped to /var/lib/openpxe/smb.
|
||||
# nfs-common - provides `mount.nfs` / `mount.nfs4` for the Storage tab's
|
||||
# NFS share manager. Mount also requires the container to run
|
||||
# with CAP_SYS_ADMIN — without it, mount(2) returns EPERM and
|
||||
@@ -74,23 +74,23 @@ RUN apt-get update \
|
||||
# bind-mount ownership (common OpenShift/Docker UX issue).
|
||||
# Windows-specific tools only activate when the WebUI toggle is on.
|
||||
|
||||
COPY --from=build /pxeforge /usr/local/bin/pxeforge
|
||||
COPY --from=build /openpxe /usr/local/bin/openpxe
|
||||
COPY deploy/docker/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
# Grant the binary the ability to bind <1024 ports as a non-root user.
|
||||
# This is the only capability PXEForge needs for proxy-mode DHCP + TFTP + HTTP.
|
||||
RUN setcap cap_net_bind_service=+ep /usr/local/bin/pxeforge
|
||||
# This is the only capability OpenPXE needs for proxy-mode DHCP + TFTP + HTTP.
|
||||
RUN setcap cap_net_bind_service=+ep /usr/local/bin/openpxe
|
||||
|
||||
# IMPORTANT: we do NOT `USER pxeforge` here. The entrypoint runs as root,
|
||||
# chowns the mounted data dirs, then execs the binary via gosu as pxeforge.
|
||||
# IMPORTANT: we do NOT `USER openpxe` here. The entrypoint runs as root,
|
||||
# chowns the mounted data dirs, then execs the binary via gosu as openpxe.
|
||||
# OpenShift ignores USER directives anyway (it injects its own uid), and
|
||||
# there entrypoint.sh's non-root branch just execs directly.
|
||||
WORKDIR /var/lib/pxeforge
|
||||
WORKDIR /var/lib/openpxe
|
||||
|
||||
ENV PXEFORGE_ISO_DIR=/var/lib/pxeforge/isos \
|
||||
PXEFORGE_WORK_DIR=/var/lib/pxeforge/work \
|
||||
PXEFORGE_LOG=info,pxeforge=info
|
||||
ENV OPENPXE_ISO_DIR=/var/lib/openpxe/isos \
|
||||
OPENPXE_WORK_DIR=/var/lib/openpxe/work \
|
||||
OPENPXE_LOG=info,openpxe=info
|
||||
|
||||
EXPOSE 67/udp 69/udp 4011/udp 80/tcp 445/tcp
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
# Container entrypoint that handles the common bind-mount-as-root case.
|
||||
#
|
||||
# When volumes are bind-mounted into the container (e.g. `-v ./data/isos:...`),
|
||||
# they come up owned by the host uid:gid — often root:root. The pxeforge
|
||||
# they come up owned by the host uid:gid — often root:root. The openpxe
|
||||
# binary runs as uid 10001 and can't write there. This script, when started
|
||||
# as root, chowns the two state dirs to the pxeforge user, then drops
|
||||
# as root, chowns the two state dirs to the openpxe user, then drops
|
||||
# privileges via gosu before execing the binary.
|
||||
#
|
||||
# If the container is already running as non-root (OpenShift does this via
|
||||
@@ -13,20 +13,20 @@
|
||||
# or the operator is on their own for permissions.
|
||||
set -e
|
||||
|
||||
PXEFORGE_UID=${PXEFORGE_UID:-10001}
|
||||
PXEFORGE_GID=${PXEFORGE_GID:-10001}
|
||||
DATA_DIRS="/var/lib/pxeforge/isos /var/lib/pxeforge/work /var/lib/pxeforge/smb"
|
||||
OPENPXE_UID=${OPENPXE_UID:-10001}
|
||||
OPENPXE_GID=${OPENPXE_GID:-10001}
|
||||
DATA_DIRS="/var/lib/openpxe/isos /var/lib/openpxe/work /var/lib/openpxe/smb"
|
||||
|
||||
if [ "$(id -u)" = "0" ]; then
|
||||
for d in $DATA_DIRS; do
|
||||
if [ -d "$d" ]; then
|
||||
chown -R "${PXEFORGE_UID}:${PXEFORGE_GID}" "$d" 2>/dev/null || true
|
||||
chown -R "${OPENPXE_UID}:${OPENPXE_GID}" "$d" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
# Re-exec ourselves under the pxeforge user so the binary inherits a
|
||||
# Re-exec ourselves under the openpxe user so the binary inherits a
|
||||
# clean process environment and a predictable umask.
|
||||
exec gosu "${PXEFORGE_UID}:${PXEFORGE_GID}" /usr/local/bin/pxeforge "$@"
|
||||
exec gosu "${OPENPXE_UID}:${OPENPXE_GID}" /usr/local/bin/openpxe "$@"
|
||||
fi
|
||||
|
||||
# Non-root: straight exec, no chown attempt.
|
||||
exec /usr/local/bin/pxeforge "$@"
|
||||
exec /usr/local/bin/openpxe "$@"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: pxeforge
|
||||
name: openpxe
|
||||
labels:
|
||||
# Allow privileged pods (host-network) in this namespace only. The pod
|
||||
# itself still runs non-root with only NET_BIND_SERVICE — privileged
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
# Custom SCC for PXEForge.
|
||||
# Custom SCC for OpenPXE.
|
||||
#
|
||||
# The default `restricted-v2` SCC blocks host network and all capabilities,
|
||||
# which PXE cannot tolerate: DHCPDISCOVER is an L2 broadcast that CNI overlays
|
||||
@@ -19,10 +19,10 @@
|
||||
apiVersion: security.openshift.io/v1
|
||||
kind: SecurityContextConstraints
|
||||
metadata:
|
||||
name: pxeforge-scc
|
||||
name: openpxe-scc
|
||||
annotations:
|
||||
kubernetes.io/description: >-
|
||||
Minimal SCC for PXEForge: host network + NET_BIND_SERVICE only, no raw
|
||||
Minimal SCC for OpenPXE: host network + NET_BIND_SERVICE only, no raw
|
||||
sockets, no privileged mode.
|
||||
allowPrivilegedContainer: false
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -54,27 +54,27 @@ volumes:
|
||||
users: []
|
||||
groups: []
|
||||
---
|
||||
# Bind the SCC to the pxeforge service account.
|
||||
# Bind the SCC to the openpxe service account.
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: pxeforge-scc-use
|
||||
name: openpxe-scc-use
|
||||
rules:
|
||||
- apiGroups: ["security.openshift.io"]
|
||||
resources: ["securitycontextconstraints"]
|
||||
resourceNames: ["pxeforge-scc"]
|
||||
resourceNames: ["openpxe-scc"]
|
||||
verbs: ["use"]
|
||||
---
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: pxeforge-scc-use
|
||||
namespace: pxeforge
|
||||
name: openpxe-scc-use
|
||||
namespace: openpxe
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: pxeforge-scc-use
|
||||
name: openpxe-scc-use
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: pxeforge
|
||||
namespace: pxeforge
|
||||
name: openpxe
|
||||
namespace: openpxe
|
||||
|
||||
@@ -2,29 +2,29 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: pxeforge
|
||||
namespace: pxeforge
|
||||
name: openpxe
|
||||
namespace: openpxe
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: pxeforge-config
|
||||
namespace: pxeforge
|
||||
name: openpxe-config
|
||||
namespace: openpxe
|
||||
data:
|
||||
# Toggle DHCP proxy on or off. "proxy" = answer PXE clients alongside an
|
||||
# existing DHCP server. "disabled" = require operator to point an external
|
||||
# DHCP at us via next-server/filename.
|
||||
PXEFORGE_DHCP_MODE: "proxy"
|
||||
OPENPXE_DHCP_MODE: "proxy"
|
||||
# Override if auto-detection picks the wrong NIC in multi-homed pods.
|
||||
# Leave unset to auto-detect from the node's primary IPv4.
|
||||
# PXEFORGE_PUBLIC_IP: "10.0.0.5"
|
||||
PXEFORGE_LOG: "info,pxeforge=info"
|
||||
# OPENPXE_PUBLIC_IP: "10.0.0.5"
|
||||
OPENPXE_LOG: "info,openpxe=info"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: pxeforge-isos
|
||||
namespace: pxeforge
|
||||
name: openpxe-isos
|
||||
namespace: openpxe
|
||||
spec:
|
||||
# ReadWriteOnce is fine — we deploy as a single replica since DHCP proxy
|
||||
# coordination across replicas is not useful (clients hit whichever node
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: pxeforge
|
||||
namespace: pxeforge
|
||||
name: openpxe
|
||||
namespace: openpxe
|
||||
labels:
|
||||
app.kubernetes.io/name: pxeforge
|
||||
app.kubernetes.io/name: openpxe
|
||||
spec:
|
||||
# Single replica by design (see PVC comment). If HA is needed later, split
|
||||
# the HTTP/web plane (scalable, stateless) from the DHCP-proxy/TFTP plane
|
||||
@@ -15,13 +15,13 @@ spec:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pxeforge
|
||||
app.kubernetes.io/name: openpxe
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: pxeforge
|
||||
app.kubernetes.io/name: openpxe
|
||||
spec:
|
||||
serviceAccountName: pxeforge
|
||||
serviceAccountName: openpxe
|
||||
# L2 broadcast (DHCPDISCOVER) does not cross most CNI overlays into
|
||||
# pod netns. Host network is the working path.
|
||||
hostNetwork: true
|
||||
@@ -33,8 +33,8 @@ spec:
|
||||
runAsUser: 10001
|
||||
fsGroup: 10001
|
||||
containers:
|
||||
- name: pxeforge
|
||||
image: ghcr.io/casperadmin/pxeforge:0.1.0
|
||||
- name: openpxe
|
||||
image: ghcr.io/casperadmin/openpxe:0.1.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: dhcp
|
||||
@@ -59,7 +59,7 @@ spec:
|
||||
protocol: TCP
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: pxeforge-config
|
||||
name: openpxe-config
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
@@ -70,9 +70,9 @@ spec:
|
||||
add: ["NET_BIND_SERVICE"]
|
||||
volumeMounts:
|
||||
- name: isos
|
||||
mountPath: /var/lib/pxeforge/isos
|
||||
mountPath: /var/lib/openpxe/isos
|
||||
- name: work
|
||||
mountPath: /var/lib/pxeforge/work
|
||||
mountPath: /var/lib/openpxe/work
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
readinessProbe:
|
||||
@@ -97,7 +97,7 @@ spec:
|
||||
volumes:
|
||||
- name: isos
|
||||
persistentVolumeClaim:
|
||||
claimName: pxeforge-isos
|
||||
claimName: openpxe-isos
|
||||
- name: work
|
||||
emptyDir: {}
|
||||
- name: tmp
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: pxeforge
|
||||
namespace: pxeforge
|
||||
name: openpxe
|
||||
namespace: openpxe
|
||||
labels:
|
||||
app.kubernetes.io/name: pxeforge
|
||||
app.kubernetes.io/name: openpxe
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: pxeforge
|
||||
app.kubernetes.io/name: openpxe
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
@@ -29,12 +29,12 @@ spec:
|
||||
apiVersion: route.openshift.io/v1
|
||||
kind: Route
|
||||
metadata:
|
||||
name: pxeforge
|
||||
namespace: pxeforge
|
||||
name: openpxe
|
||||
namespace: openpxe
|
||||
spec:
|
||||
to:
|
||||
kind: Service
|
||||
name: pxeforge
|
||||
name: openpxe
|
||||
weight: 100
|
||||
port:
|
||||
targetPort: http
|
||||
|
||||
+23
-23
@@ -1,12 +1,12 @@
|
||||
# PXEForge on Unraid
|
||||
# OpenPXE on Unraid
|
||||
|
||||
Three paths from "I have an Unraid box with Gitea on it" to "PXE clients
|
||||
boot from PXEForge". Pick the one that matches what you have.
|
||||
boot from OpenPXE". Pick the one that matches what you have.
|
||||
|
||||
## Path A — build on Unraid, push to Gitea registry, pull by tag
|
||||
|
||||
Recommended once you've done it once. Image is published to
|
||||
`gitea.milesward.dev/mward4/pxeforge:0.1.0` (or your equivalent) and
|
||||
`gitea.milesward.dev/mward4/openpxe:0.1.0` (or your equivalent) and
|
||||
every Unraid template / docker-compose just references the tag.
|
||||
|
||||
Pre-flight:
|
||||
@@ -24,12 +24,12 @@ Run on the Unraid host (Settings → Terminal, or `ssh root@unraid`):
|
||||
GITEA_TOKEN=<your-token>
|
||||
curl -fsSL \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
http://localhost:3000/mward4/PXEForge/raw/branch/main/scripts/build-and-publish-unraid.sh \
|
||||
-o /tmp/pxeforge-publish.sh
|
||||
http://localhost:3000/mward4/OpenPXE/raw/branch/main/scripts/build-and-publish-unraid.sh \
|
||||
-o /tmp/openpxe-publish.sh
|
||||
|
||||
# Run it. ~6 min on Unraid hardware (native amd64, no QEMU).
|
||||
chmod +x /tmp/pxeforge-publish.sh
|
||||
GITEA_TOKEN=$GITEA_TOKEN /tmp/pxeforge-publish.sh
|
||||
chmod +x /tmp/openpxe-publish.sh
|
||||
GITEA_TOKEN=$GITEA_TOKEN /tmp/openpxe-publish.sh
|
||||
```
|
||||
|
||||
What it does:
|
||||
@@ -47,17 +47,17 @@ After it finishes, in Unraid → Docker → Add Container, set:
|
||||
|
||||
| Field | Value |
|
||||
|------------|-------------------------------------------------|
|
||||
| Repository | `gitea.milesward.dev/mward4/pxeforge:0.1.0` |
|
||||
| Repository | `gitea.milesward.dev/mward4/openpxe:0.1.0` |
|
||||
| Network | `host` |
|
||||
| Extra args | `--cap-add=NET_BIND_SERVICE` |
|
||||
|
||||
Volume mounts (paths inside container in **bold**):
|
||||
|
||||
- **`/var/lib/pxeforge/isos`** ↔ `/mnt/user/appdata/pxeforge/isos`
|
||||
- **`/var/lib/pxeforge/work`** ↔ `/mnt/user/appdata/pxeforge/work`
|
||||
- **`/var/lib/pxeforge/smb`** ↔ `/mnt/user/appdata/pxeforge/smb`
|
||||
- **`/var/lib/openpxe/isos`** ↔ `/mnt/user/appdata/openpxe/isos`
|
||||
- **`/var/lib/openpxe/work`** ↔ `/mnt/user/appdata/openpxe/work`
|
||||
- **`/var/lib/openpxe/smb`** ↔ `/mnt/user/appdata/openpxe/smb`
|
||||
|
||||
Or skip the manual UI by dropping `pxeforge.xml` (in this directory)
|
||||
Or skip the manual UI by dropping `openpxe.xml` (in this directory)
|
||||
into `/boot/config/plugins/dockerMan/templates-user/` and Unraid will
|
||||
list it as a one-click template.
|
||||
|
||||
@@ -70,15 +70,15 @@ Skip the registry entirely. Useful for "hack on it locally" iterations.
|
||||
```bash
|
||||
ssh root@unraid
|
||||
cd /mnt/user/appdata
|
||||
git clone http://localhost:3000/mward4/PXEForge.git pxeforge-src
|
||||
cd pxeforge-src
|
||||
git clone http://localhost:3000/mward4/OpenPXE.git openpxe-src
|
||||
cd openpxe-src
|
||||
bash scripts/fetch-ipxe.sh
|
||||
docker compose -f docker-compose.yml up -d --build pxeforge
|
||||
docker compose -f docker-compose.yml up -d --build openpxe
|
||||
```
|
||||
|
||||
The bundled `docker-compose.yml` already wires host networking, the
|
||||
right cap_add, and bind-mounts to `./data/`. Edit those bind-mount
|
||||
paths if you want them under `/mnt/user/appdata/pxeforge/`.
|
||||
paths if you want them under `/mnt/user/appdata/openpxe/`.
|
||||
|
||||
## Path C — `docker load` from a tarball I built off-box
|
||||
|
||||
@@ -88,14 +88,14 @@ then:
|
||||
|
||||
```bash
|
||||
# On the build host
|
||||
docker save pxeforge:0.1.0 | gzip > pxeforge-0.1.0.tar.gz
|
||||
docker save openpxe:0.1.0 | gzip > openpxe-0.1.0.tar.gz
|
||||
|
||||
# Transfer (rsync / scp / SMB / ZFS-replicate / sneakernet)
|
||||
scp pxeforge-0.1.0.tar.gz root@unraid:/tmp/
|
||||
scp openpxe-0.1.0.tar.gz root@unraid:/tmp/
|
||||
|
||||
# On Unraid
|
||||
gunzip -c /tmp/pxeforge-0.1.0.tar.gz | docker load
|
||||
docker tag pxeforge:0.1.0 gitea.milesward.dev/mward4/pxeforge:0.1.0
|
||||
gunzip -c /tmp/openpxe-0.1.0.tar.gz | docker load
|
||||
docker tag openpxe:0.1.0 gitea.milesward.dev/mward4/openpxe:0.1.0
|
||||
```
|
||||
|
||||
If you want it pullable by tag from other Unraid templates, push to
|
||||
@@ -119,16 +119,16 @@ show up in the Dashboard's "Recent connections" table within seconds.
|
||||
## Common gotchas
|
||||
|
||||
- **DHCP collision.** Don't run two PXE _proxies_ on the same broadcast
|
||||
domain. PXEForge runs in proxy mode and never offers IP leases, so
|
||||
domain. OpenPXE runs in proxy mode and never offers IP leases, so
|
||||
it coexists with whatever DHCP server is already on the network —
|
||||
but two proxies racing each other will whichever-wins at random.
|
||||
- **Host networking only.** Bridge mode containers don't see broadcast
|
||||
DHCP. There's no working bridge-mode config for a PXE server.
|
||||
- **Permissions on `/mnt/user/appdata/pxeforge`.** The container runs
|
||||
- **Permissions on `/mnt/user/appdata/openpxe`.** The container runs
|
||||
as uid 10001 by default. The entrypoint chowns the bind mounts to
|
||||
10001 on first start, but only if the container itself has root —
|
||||
`--user=root` isn't needed; the multi-stage Dockerfile starts as
|
||||
root, fixes perms, then drops to pxeforge via gosu.
|
||||
root, fixes perms, then drops to openpxe via gosu.
|
||||
- **NFS mounts in the Storage tab.** Mounting NFS inside the container
|
||||
needs `CAP_SYS_ADMIN`. To enable, add `--cap-add=SYS_ADMIN` to the
|
||||
Unraid template's "Extra args" — but understand that's a meaningful
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Unraid Docker template for PXEForge.
|
||||
Unraid Docker template for OpenPXE.
|
||||
|
||||
Drop this file into /boot/config/plugins/dockerMan/templates-user/
|
||||
on your Unraid box (or import via the Docker tab → "Add Container" →
|
||||
"Template Repositories" if you publish it on a Gitea raw URL).
|
||||
|
||||
IMPORTANT: PXEForge needs host networking for DHCP/TFTP raw broadcasts.
|
||||
IMPORTANT: OpenPXE needs host networking for DHCP/TFTP raw broadcasts.
|
||||
Bridge mode will NOT work — clients can't see broadcast DHCP from a
|
||||
bridged container. The template forces NetworkType=host below.
|
||||
|
||||
@@ -21,20 +21,20 @@
|
||||
Web UI: http://<unraid-ip>/ (port 80)
|
||||
-->
|
||||
<Container version="2">
|
||||
<Name>PXEForge</Name>
|
||||
<Repository>gitea.milesward.dev/mward4/pxeforge:latest</Repository>
|
||||
<Registry>https://gitea.milesward.dev/mward4/-/packages/container/pxeforge</Registry>
|
||||
<Name>OpenPXE</Name>
|
||||
<Repository>gitea.milesward.dev/mward4/openpxe:latest</Repository>
|
||||
<Registry>https://gitea.milesward.dev/mward4/-/packages/container/openpxe</Registry>
|
||||
<Network>host</Network>
|
||||
<MyIP/>
|
||||
<Shell>sh</Shell>
|
||||
<Privileged>false</Privileged>
|
||||
<Support>https://gitea.milesward.dev/mward4/PXEForge/issues</Support>
|
||||
<Project>https://gitea.milesward.dev/mward4/PXEForge</Project>
|
||||
<Support>https://gitea.milesward.dev/mward4/OpenPXE/issues</Support>
|
||||
<Project>https://gitea.milesward.dev/mward4/OpenPXE</Project>
|
||||
<Overview>
|
||||
Air-gapped network PXE boot server. Container-native Rust
|
||||
implementation — DHCP proxy + TFTP + iPXE chainload + HTTP ISO
|
||||
streaming, all in one process. Web UI for ISO upload, NFS share
|
||||
mounting, and Gated Deployment ("horse-race" simultaneous launch
|
||||
mounting, and Queued Deployment ("horse-race" simultaneous launch
|
||||
of one ISO across many waiting clients).
|
||||
|
||||
NEVER touches the client OS trust store: no test-signed drivers,
|
||||
@@ -44,7 +44,7 @@
|
||||
<Category>Network:Other Network:Management</Category>
|
||||
<WebUI>http://[IP]/</WebUI>
|
||||
<TemplateURL/>
|
||||
<Icon>https://gitea.milesward.dev/mward4/PXEForge/raw/branch/main/crates/webui/src/logo.svg</Icon>
|
||||
<Icon>https://gitea.milesward.dev/mward4/OpenPXE/raw/branch/main/crates/webui/src/logo.svg</Icon>
|
||||
<ExtraParams>--cap-add=NET_BIND_SERVICE</ExtraParams>
|
||||
<PostArgs/>
|
||||
<CPUset/>
|
||||
@@ -53,23 +53,23 @@
|
||||
<DonateLink/>
|
||||
<Requires>
|
||||
Host networking. Unraid's built-in DHCP server (if any) must
|
||||
not collide with a network that already has DHCP — PXEForge runs
|
||||
not collide with a network that already has DHCP — OpenPXE runs
|
||||
in proxy mode and coexists, but only one DHCP _proxy_ should reply
|
||||
per broadcast domain.
|
||||
</Requires>
|
||||
<Config Name="ISOs" Target="/var/lib/pxeforge/isos" Default="/mnt/user/appdata/pxeforge/isos"
|
||||
<Config Name="ISOs" Target="/var/lib/openpxe/isos" Default="/mnt/user/appdata/openpxe/isos"
|
||||
Mode="rw" Description="Where uploaded and seeded .iso files live."
|
||||
Type="Path" Display="always" Required="true" Mask="false">/mnt/user/appdata/pxeforge/isos</Config>
|
||||
<Config Name="Work dir" Target="/var/lib/pxeforge/work" Default="/mnt/user/appdata/pxeforge/work"
|
||||
Type="Path" Display="always" Required="true" Mask="false">/mnt/user/appdata/openpxe/isos</Config>
|
||||
<Config Name="Work dir" Target="/var/lib/openpxe/work" Default="/mnt/user/appdata/openpxe/work"
|
||||
Mode="rw" Description="Settings, NFS state, and runtime scratch. Persisted across restarts."
|
||||
Type="Path" Display="always" Required="true" Mask="false">/mnt/user/appdata/pxeforge/work</Config>
|
||||
<Config Name="SMB share root" Target="/var/lib/pxeforge/smb" Default="/mnt/user/appdata/pxeforge/smb"
|
||||
Type="Path" Display="always" Required="true" Mask="false">/mnt/user/appdata/openpxe/work</Config>
|
||||
<Config Name="SMB share root" Target="/var/lib/openpxe/smb" Default="/mnt/user/appdata/openpxe/smb"
|
||||
Mode="rw" Description="Where extracted Windows install media lives. Only used when Windows toggle is on."
|
||||
Type="Path" Display="advanced" Required="false" Mask="false">/mnt/user/appdata/pxeforge/smb</Config>
|
||||
<Config Name="Public IP" Target="PXEFORGE_PUBLIC_IP" Default=""
|
||||
Type="Path" Display="advanced" Required="false" Mask="false">/mnt/user/appdata/openpxe/smb</Config>
|
||||
<Config Name="Public IP" Target="OPENPXE_PUBLIC_IP" Default=""
|
||||
Mode="" Description="IP advertised to PXE clients. Leave blank to auto-detect; set explicitly on multi-homed Unraid hosts."
|
||||
Type="Variable" Display="always" Required="false" Mask="false"></Config>
|
||||
<Config Name="Log filter" Target="PXEFORGE_LOG" Default="info,pxeforge=debug"
|
||||
<Config Name="Log filter" Target="OPENPXE_LOG" Default="info,openpxe=debug"
|
||||
Mode="" Description="tracing-subscriber EnvFilter expression."
|
||||
Type="Variable" Display="advanced" Required="false" Mask="false">info,pxeforge=debug</Config>
|
||||
Type="Variable" Display="advanced" Required="false" Mask="false">info,openpxe=debug</Config>
|
||||
</Container>
|
||||
Reference in New Issue
Block a user