From fc9033d89aab5dd5797977816e0f99f80d1a7f3f Mon Sep 17 00:00:00 2001 From: Erik Thiele Date: Sun, 19 Jul 2026 19:11:47 +0200 Subject: [PATCH] Add Proxmox LXC helper-script for automated installation Creates a Debian 12 LXC container and sets up LinkVault as a systemd service inside it, following the tteck/community-scripts pattern. Co-Authored-By: Claude Sonnet 5 --- README.md | 13 +++ scripts/proxmox/install-linkvault.sh | 164 +++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100755 scripts/proxmox/install-linkvault.sh diff --git a/README.md b/README.md index 1423c2b..5c630bb 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,19 @@ app/ templates/ Jinja2 + HTMX Oberfläche ``` +## Proxmox + +Für den Betrieb in einem Proxmox-VE-LXC-Container gibt es ein Helper-Script, +das einen Debian-12-Container anlegt und LinkVault darin als systemd-Service +einrichtet. Auf dem Proxmox-Host ausführen: + +```bash +bash scripts/proxmox/install-linkvault.sh +``` + +Konfiguration (Container-ID, IP, Ressourcen, ...) über Umgebungsvariablen, +siehe Kommentare im Script. + ## Hinweise für den Produktivbetrieb - Einen zufälligen `SECRET_KEY` in `.env` setzen. diff --git a/scripts/proxmox/install-linkvault.sh b/scripts/proxmox/install-linkvault.sh new file mode 100755 index 0000000..d35a35c --- /dev/null +++ b/scripts/proxmox/install-linkvault.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env bash +# +# LinkVault – Proxmox VE Helper-Script +# +# Muss als root auf dem Proxmox-VE-Host ausgeführt werden. Legt einen neuen +# Debian-12-LXC-Container an und installiert darin LinkVault (FastAPI-App) +# als systemd-Service. +# +# Verwendung (auf dem Proxmox-Host): +# bash install-linkvault.sh +# +# Konfiguration über Umgebungsvariablen (optional, siehe Defaults unten), z.B.: +# CTID=150 CT_HOSTNAME=linkvault CT_IP=192.168.1.50/24 CT_GW=192.168.1.1 \ +# bash install-linkvault.sh +# +set -euo pipefail + +# --------------------------------------------------------------------------- +# Konfiguration (per ENV überschreibbar) +# --------------------------------------------------------------------------- +CTID="${CTID:-$(pvesh get /cluster/nextid)}" +CT_HOSTNAME="${CT_HOSTNAME:-linkvault}" +CT_DISK_GB="${CT_DISK_GB:-8}" +CT_MEMORY_MB="${CT_MEMORY_MB:-1024}" +CT_SWAP_MB="${CT_SWAP_MB:-512}" +CT_CORES="${CT_CORES:-2}" +CT_BRIDGE="${CT_BRIDGE:-vmbr0}" +CT_IP="${CT_IP:-dhcp}" # z.B. 192.168.1.50/24, sonst "dhcp" +CT_GW="${CT_GW:-}" # nur nötig bei statischer IP +CT_STORAGE="${CT_STORAGE:-local-lvm}" +TEMPLATE_STORAGE="${TEMPLATE_STORAGE:-local}" +CT_PASSWORD="${CT_PASSWORD:-}" # leer = zufällig generiert +REPO_URL="${REPO_URL:-https://gitea.teamthiele.de/ethiele/linkvault.git}" +APP_PORT="${APP_PORT:-8000}" + +# --------------------------------------------------------------------------- +# Vorbedingungen +# --------------------------------------------------------------------------- +if ! command -v pct &>/dev/null; then + echo "Fehler: 'pct' nicht gefunden – dieses Script muss auf einem Proxmox-VE-Host laufen." >&2 + exit 1 +fi + +if [ -z "$CT_PASSWORD" ]; then + CT_PASSWORD="$(openssl rand -base64 18)" +fi + +echo "==> Container-ID: $CTID" +echo "==> Hostname: $CT_HOSTNAME" +echo "==> Storage (RootFS): $CT_STORAGE" +echo "==> Netzwerk: $CT_BRIDGE / $CT_IP" + +# --------------------------------------------------------------------------- +# Debian-12-Template sicherstellen +# --------------------------------------------------------------------------- +TEMPLATE="debian-12-standard_12.7-1_amd64.tar.zst" +if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then + echo "==> Lade Debian-12-Template herunter..." + pveam update + pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" +fi + +# --------------------------------------------------------------------------- +# LXC-Container anlegen +# --------------------------------------------------------------------------- +if [ "$CT_IP" = "dhcp" ]; then + NET_CONF="name=eth0,bridge=${CT_BRIDGE},ip=dhcp" +else + if [ -z "$CT_GW" ]; then + echo "Fehler: CT_GW (Gateway) muss bei statischer IP gesetzt sein." >&2 + exit 1 + fi + NET_CONF="name=eth0,bridge=${CT_BRIDGE},ip=${CT_IP},gw=${CT_GW}" +fi + +echo "==> Erstelle LXC-Container $CTID..." +pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" \ + --hostname "$CT_HOSTNAME" \ + --cores "$CT_CORES" \ + --memory "$CT_MEMORY_MB" \ + --swap "$CT_SWAP_MB" \ + --rootfs "${CT_STORAGE}:${CT_DISK_GB}" \ + --net0 "$NET_CONF" \ + --password "$CT_PASSWORD" \ + --unprivileged 1 \ + --features nesting=1 \ + --onboot 1 + +echo "==> Starte Container..." +pct start "$CTID" + +echo "==> Warte auf Netzwerk..." +for i in $(seq 1 30); do + if pct exec "$CTID" -- ping -c1 -W2 deb.debian.org &>/dev/null; then + break + fi + sleep 2 +done + +# --------------------------------------------------------------------------- +# Installation innerhalb des Containers +# --------------------------------------------------------------------------- +echo "==> Installiere Abhängigkeiten und LinkVault im Container..." +pct exec "$CTID" -- bash -c " +set -euo pipefail +export DEBIAN_FRONTEND=noninteractive +apt-get update -qq +apt-get install -y -qq git python3 python3-venv python3-pip build-essential curl >/dev/null + +if [ ! -d /opt/linkvault ]; then + git clone --quiet '${REPO_URL}' /opt/linkvault +fi +cd /opt/linkvault + +python3 -m venv .venv +.venv/bin/pip install -q --upgrade pip +.venv/bin/pip install -q -r requirements.txt + +if [ ! -f .env ]; then + cp .env.example .env + SECRET=\$(.venv/bin/python3 -c 'import secrets; print(secrets.token_hex(32))') + sed -i \"s#^SECRET_KEY=.*#SECRET_KEY=\$SECRET#\" .env +fi + +useradd --system --home /opt/linkvault --shell /usr/sbin/nologin linkvault 2>/dev/null || true +chown -R linkvault:linkvault /opt/linkvault + +cat > /etc/systemd/system/linkvault.service <