fix(build): add DNS server prompt for static IPs + better network diagnostics

For DHCP setups DNS is delivered with the lease, but with a static IP the
container inherits /etc/resolv.conf from the PVE host - which is often
unreachable from the container's VLAN.

Changes:
- New NAMESERVER prompt (only shown for static IPs, defaults to gateway)
- pct create now passes --nameserver when set
- Network wait loop tests L3 and DNS separately so failures point at the
  actual cause (no route to gateway vs. bad DNS server)
- Refactored pct create args into an array for cleaner conditional flags
This commit is contained in:
2026-05-22 00:11:49 +02:00
parent b93ec8b553
commit 42aad8a117
+54 -19
View File
@@ -34,6 +34,7 @@ DEFAULT_BRIDGE="${DEFAULT_BRIDGE:-vmbr0}"
DEFAULT_TEMPLATE_STORAGE="${DEFAULT_TEMPLATE_STORAGE:-local}"
DEFAULT_ROOTFS_STORAGE="${DEFAULT_ROOTFS_STORAGE:-local-lvm}"
DEFAULT_TEMPLATE_PATTERN="${DEFAULT_TEMPLATE_PATTERN:-debian-12-standard}"
DEFAULT_NAMESERVER="${DEFAULT_NAMESERVER:-}"
# ── error trap ───────────────────────────────────────────────────────────────
_on_error() {
@@ -64,8 +65,8 @@ show_header() {
# ── prompts ──────────────────────────────────────────────────────────────────
# Each prompt is skipped if the corresponding variable is already set in env.
# VLAN_TAG uses ${VLAN_TAG+x} so that explicitly setting it to "" via env
# skips the prompt (= "no VLAN, don't ask").
# VLAN_TAG and NAMESERVER use ${VAR+x} so that explicitly setting them to ""
# via env skips the prompt (= "no VLAN" / "inherit DNS from host").
prompt_lxc_config() {
if [[ -z "${CTID:-}" ]]; then
read -rp "Container ID [auto]: " CTID
@@ -112,6 +113,13 @@ prompt_lxc_config() {
if [[ "$IPCFG" != "dhcp" && -z "$GATEWAY" ]]; then
read -rp "Gateway: " GATEWAY
fi
# DNS: only meaningful for static IPs (DHCP gets DNS from the lease).
# Default suggestion is the gateway, which doubles as DNS in most homelabs.
if [[ "$IPCFG" != "dhcp" && -z "${NAMESERVER+x}" ]]; then
local default_ns="${DEFAULT_NAMESERVER:-$GATEWAY}"
read -rp "DNS server [$default_ns] (empty = inherit from PVE host): " NAMESERVER
NAMESERVER="${NAMESERVER:-$default_ns}"
fi
}
# ── template ─────────────────────────────────────────────────────────────────
@@ -142,36 +150,63 @@ create_lxc() {
net_opts+=",ip=$IPCFG,gw=$GATEWAY"
fi
# Assemble pct args as an array so conditional flags stay clean.
local pct_args=(
"$CTID" "$TEMPLATE_STORAGE:vztmpl/$TEMPLATE"
--hostname "$CT_HOSTNAME"
--cores "$CORES"
--memory "$RAM"
--swap 512
--rootfs "$ROOTFS_STORAGE:$DISK_SIZE"
--net0 "$net_opts"
--features nesting=1
--unprivileged 1
--onboot 1
--ostype debian
--password "$ROOT_PASSWORD"
)
[[ -n "${NAMESERVER:-}" ]] && pct_args+=(--nameserver "$NAMESERVER")
msg_info "Creating unprivileged LXC $CTID ($CT_HOSTNAME)..."
msg_info " net0: $net_opts"
pct create "$CTID" "$TEMPLATE_STORAGE:vztmpl/$TEMPLATE" \
--hostname "$CT_HOSTNAME" \
--cores "$CORES" \
--memory "$RAM" \
--swap 512 \
--rootfs "$ROOTFS_STORAGE:$DISK_SIZE" \
--net0 "$net_opts" \
--features nesting=1 \
--unprivileged 1 \
--onboot 1 \
--ostype debian \
--password "$ROOT_PASSWORD"
[[ -n "${NAMESERVER:-}" ]] && msg_info " dns: $NAMESERVER"
pct create "${pct_args[@]}"
msg_ok "LXC $CTID created"
msg_info "Starting LXC..."
pct start "$CTID"
sleep 5
msg_info "Waiting for network..."
local i
msg_info "Waiting for network + DNS..."
local i ping_ok=0 dns_ok=0
# We test L3 (gateway/internet) and DNS separately so we can give a useful
# error message instead of a generic "network never came up".
for i in {1..30}; do
if [[ $ping_ok -eq 0 ]] && pct exec "$CTID" -- bash -c "ping -c 1 -W 2 1.1.1.1 >/dev/null 2>&1 || ping -c 1 -W 2 ${GATEWAY:-1.1.1.1} >/dev/null 2>&1"; then
ping_ok=1
fi
if pct exec "$CTID" -- getent hosts deb.debian.org >/dev/null 2>&1; then
msg_ok "Network up"
return 0
dns_ok=1
break
fi
sleep 2
done
msg_err "Network never came up. Check bridge/VLAN/gateway settings."
if [[ $dns_ok -eq 1 ]]; then
msg_ok "Network + DNS up"
return 0
fi
if [[ $ping_ok -eq 1 ]]; then
msg_err "L3 connectivity OK but DNS resolution failed."
msg_err "Container can reach the internet but can't resolve names."
msg_err "Re-run with NAMESERVER=<dns-ip> set, or fix /etc/resolv.conf inside the LXC."
else
msg_err "Network never came up. Check bridge/VLAN/gateway settings:"
msg_err " pct exec $CTID -- ip a"
msg_err " pct exec $CTID -- ip r"
msg_err " pct exec $CTID -- ping -c2 ${GATEWAY:-<gateway>}"
fi
exit 1
}