README.md
This project provides a declarative method for running the official linuxserver/netbootxyz container using Podman and systemd. It uses a quadlet file, which allows systemd
to natively manage the container's lifecycle, including auto-starting on boot, automatic restarts, and health checks.
- Declarative Setup: All container configuration is defined in a single
.container
file. - Systemd Integration: Manage the container like any other system service (
systemctl start
,stop
,status
). - Automatic Startup: The service is enabled to start automatically on system boot.
- Automatic Health Checks: The container's internal web server is checked periodically to ensure it's healthy. If it fails, systemd will restart it according to the policy.
- Persistent Storage: Maps host directories for persistent configuration and read-only access to custom assets (like ISOs).
- SELinux Aware: The quadlet automatically handles SELinux labeling for volume mounts when run as a system service.
- A Linux distribution with
systemd
. podman
installed (version 4.4.0 or newer is recommended for full quadlet support).
These instructions assume you are setting this up as a system-wide service that runs as root. This is the recommended approach for services that need to bind to privileged ports (like port 69).
The container requires two directories on the host system: one for configuration and another for your boot assets (e.g., custom ISOs).
# Create the directory for persistent configuration
sudo mkdir -p /srv/netbootxyz/config
# Create the directory for boot assets (e.g., ISOs)
sudo mkdir -p /mnt/iso
Note: You can change these paths, but you must update the
netbootxyz.container
file to match.
Create the following file at /etc/containers/systemd/netbootxyz.container
.
[Unit]
Description=netboot.xyz Container
After=network-online.target
Wants=network-online.target
[Container]
Image=docker.io/linuxserver/netbootxyz:latest
ContainerName=netbootxyz
# Map the necessary ports
PublishPort=69:69/udp
PublishPort=3080:80/tcp
PublishPort=4011:4011/udp
# Mount the volumes with correct flags
# The ":z" for SELinux is handled automatically for system units
Volume=/srv/netbootxyz/config:/config
Volume=/mnt/iso:/assets:ro
# Set environment variables for rootful operation
Environment=PUID=0
Environment=PGID=0
# --- Health-Check Configuration ---
# The command to run inside the container to check its health.
HealthCmd=curl -f http://localhost:80/ || exit 1
HealthInterval=30s
HealthTimeout=10s
HealthRetries=3
HealthStartPeriod=60s
[Service]
TimeoutStartSec=300
Restart=always
[Install]
WantedBy=default.target
Tell systemd to re-read its configuration files and generate the netbootxyz.service
unit. Then, enable and start the service.
# Reload the systemd daemon to recognize the new quadlet file
sudo systemctl daemon-reload
# Enable the service to start on boot and start it now
sudo systemctl enable --now netbootxyz.service
You can check that the container is running and healthy.
-
Check the systemd service status:
sudo systemctl status netbootxyz.service
You should see an
active (running)
status. -
Check the Podman container status:
sudo podman ps
After about a minute (the
HealthStartPeriod
), the status should change to(healthy)
.CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES abcdef123456 docker.io/linuxserver/netbootxyz:latest ... 30 seconds ago Up 29 seconds (healthy) 0.0.0.0:69->69/udp, 0.0.0.0:3080->80/tcp, ... netbootxyz
-
Access the Web UI: Open a web browser and navigate to
http://<your-server-ip>:3080
.
- Configuration: All
netboot.xyz
configuration will be stored in/srv/netbootxyz/config
on the host. - Custom Assets: Place any custom ISOs or other assets you want to serve into
/mnt/iso
on the host. The container will have read-only access to them at/assets
.
Use standard systemctl
commands to manage the service:
- Stop the service:
sudo systemctl stop netbootxyz.service
- Start the service:
sudo systemctl start netbootxyz.service
- Restart the service:
sudo systemctl restart netbootxyz.service
- View logs:
sudo journalctl -u netbootxyz.service -f
This project is licensed under the MIT License. See the LICENSE file for details.