Files
wireguard-ui-multi/scripts/proxmox-install.sh
T
sysopsandClaude Sonnet 5 e5c0a5888f Adapt installers to upstream wireguard-ui build (Go+embed, yarn assets)
Upstream builds a single static binary (main.go at repo root, no
cmd/... subpackage) that go:embeds templates/ and assets/ at compile
time, and uses a relative ./db directory (jsondb) instead of SQLite -
so WorkingDirectory in the systemd unit now matters for the DB path,
not for template/static serving like before.

Frontend assets (admin-lte, jquery plugins) need yarn + prepare_assets.sh
before go build, so all installers now also install nodejs/npm/yarn and
run prepare_assets.sh when assets/dist is missing or package.json changed.

Binary is now literally named "wireguard-ui" (matches upstream), listens
on 0.0.0.0:5000 by default. systemd unit rewritten accordingly with
WorkingDirectory=/var/lib/wireguard-ui-multi.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 18:38:02 +02:00

181 lines
5.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Runs on a Proxmox VE host. Creates a privileged LXC container prepared for
# WireGuard (kernel module + /dev/net/tun + CAP_NET_ADMIN + nftables), copies
# this repo into it, and runs scripts/install.sh inside the container.
#
# Privileged container is required: WireGuard needs CAP_NET_ADMIN and access
# to /dev/net/tun, which unprivileged LXC containers cannot reliably get.
set -euo pipefail
usage() {
cat >&2 <<EOF
Usage: $0 --vmid <id> --hostname <name> [options]
Required:
--vmid <id> numeric LXC container ID (e.g. 200)
--hostname <name> container hostname (e.g. wireguard-ui-multi)
Options:
--storage <name> Proxmox storage for rootfs (default: local-lvm)
--template <path> LXC template volid (default: auto-detect + download newest debian-* template)
--bridge <name> network bridge (default: vmbr0)
--ip <cidr|dhcp> static CIDR (e.g. 10.0.0.50/24) or "dhcp" (default: dhcp)
--gw <ip> gateway IP, required if --ip is a static CIDR
--disk <GB> rootfs size in GB (default: 4)
--memory <MB> RAM in MB (default: 512)
--cores <n> CPU cores (default: 1)
--repo-src <path> path to this repo on the Proxmox host (default: script's own repo root)
--start start the container after creation (default: created but stopped, then started to run the installer, left running)
EOF
exit 1
}
VMID=""
HOSTNAME=""
STORAGE="local-lvm"
TEMPLATE=""
BRIDGE="vmbr0"
IP="dhcp"
GW=""
DISK="4"
MEMORY="512"
CORES="1"
REPO_SRC=""
while [[ $# -gt 0 ]]; do
case "$1" in
--vmid) VMID="$2"; shift 2 ;;
--hostname) HOSTNAME="$2"; shift 2 ;;
--storage) STORAGE="$2"; shift 2 ;;
--template) TEMPLATE="$2"; shift 2 ;;
--bridge) BRIDGE="$2"; shift 2 ;;
--ip) IP="$2"; shift 2 ;;
--gw) GW="$2"; shift 2 ;;
--disk) DISK="$2"; shift 2 ;;
--memory) MEMORY="$2"; shift 2 ;;
--cores) CORES="$2"; shift 2 ;;
--repo-src) REPO_SRC="$2"; shift 2 ;;
-h|--help) usage ;;
*) echo "Unknown option: $1" >&2; usage ;;
esac
done
[[ -z "$VMID" || -z "$HOSTNAME" ]] && usage
if [[ "$(id -u)" -ne 0 ]]; then
echo "Must run as root on the Proxmox host." >&2
exit 1
fi
if ! command -v pct >/dev/null 2>&1; then
echo "pct not found - this script must run on a Proxmox VE host." >&2
exit 1
fi
if [[ -z "$REPO_SRC" ]]; then
REPO_SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
fi
if [[ -z "$TEMPLATE" ]]; then
echo "No --template given, looking up newest debian-* template..."
pveam update >/dev/null
TEMPLATE_FILE="$(pveam available --section system \
| awk '{print $2}' \
| grep -E '^debian-[0-9]+-standard_' \
| sort -V \
| tail -n1)"
if [[ -z "$TEMPLATE_FILE" ]]; then
echo "Could not find any debian-* template via 'pveam available'." >&2
exit 1
fi
if ! pveam list "$STORAGE" | grep -q "$TEMPLATE_FILE"; then
echo "Downloading $TEMPLATE_FILE to storage $STORAGE..."
pveam download "$STORAGE" "$TEMPLATE_FILE"
fi
TEMPLATE="${STORAGE}:vztmpl/${TEMPLATE_FILE}"
echo "Using template: $TEMPLATE"
fi
NET_CONFIG="name=eth0,bridge=${BRIDGE},firewall=1"
if [[ "$IP" == "dhcp" ]]; then
NET_CONFIG="${NET_CONFIG},ip=dhcp"
else
if [[ -z "$GW" ]]; then
echo "--gw is required when --ip is a static CIDR." >&2
exit 1
fi
NET_CONFIG="${NET_CONFIG},ip=${IP},gw=${GW}"
fi
echo "Creating privileged LXC $VMID ($HOSTNAME)..."
pct create "$VMID" "$TEMPLATE" \
--hostname "$HOSTNAME" \
--storage "$STORAGE" \
--rootfs "${STORAGE}:${DISK}" \
--memory "$MEMORY" \
--cores "$CORES" \
--net0 "$NET_CONFIG" \
--unprivileged 0 \
--features "nesting=1,keyctl=1" \
--onboot 1
echo "Enabling /dev/net/tun and WireGuard kernel module passthrough..."
CONF="/etc/pve/lxc/${VMID}.conf"
{
echo "lxc.cgroup2.devices.allow: c 10:200 rwm"
echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file"
} >> "$CONF"
echo "Starting container..."
pct start "$VMID"
sleep 5
echo "Installing base dependencies inside container (Go, Node/yarn, git, wireguard-tools, nftables)..."
pct exec "$VMID" -- bash -c "
set -e
apt-get update
apt-get install -y wireguard-tools nftables curl ca-certificates git nodejs npm
if ! command -v yarn >/dev/null 2>&1; then
npm install -g yarn
fi
if ! command -v go >/dev/null 2>&1; then
ARCH=\$(dpkg --print-architecture)
curl -fsSL https://go.dev/dl/go1.22.5.linux-\${ARCH}.tar.gz -o /tmp/go.tar.gz
tar -C /usr/local -xzf /tmp/go.tar.gz
ln -sf /usr/local/go/bin/go /usr/local/bin/go
rm -f /tmp/go.tar.gz
fi
"
echo "Copying repo into container..."
TMP_TAR="$(mktemp)"
tar -C "$REPO_SRC" -czf "$TMP_TAR" --exclude=.git .
pct push "$VMID" "$TMP_TAR" /tmp/wireguard-ui-multi.tar.gz
rm -f "$TMP_TAR"
pct exec "$VMID" -- bash -c "
set -e
mkdir -p /opt/wireguard-ui-multi-src
tar -C /opt/wireguard-ui-multi-src -xzf /tmp/wireguard-ui-multi.tar.gz
rm -f /tmp/wireguard-ui-multi.tar.gz
"
echo "Running native installer inside container..."
pct exec "$VMID" -- bash -c "
set -e
export PATH=/usr/local/go/bin:/usr/local/bin:\$PATH
cd /opt/wireguard-ui-multi-src
bash scripts/install.sh
"
echo
echo "Container $VMID ($HOSTNAME) is set up. wireguard-ui-multi is installed but not started."
echo "To enable and start it inside the container, run:"
echo
echo " pct exec $VMID -- systemctl enable --now wireguard-ui-multi.service"
echo
echo "Then check status with:"
echo
echo " pct exec $VMID -- systemctl status wireguard-ui-multi.service"
echo " pct exec $VMID -- journalctl -u wireguard-ui-multi.service -f"