docker-lxc.sh hinzugefügt
This commit is contained in:
+251
@@ -0,0 +1,251 @@
|
||||
#!/usr/bin/env bash
|
||||
# ==============================================================================
|
||||
# Proxmox LXC: Debian + Docker + Portainer (optional)
|
||||
# Aufruf auf dem PVE-Host:
|
||||
# bash <(curl -fsSL https://your-host/debian-docker-portainer-lxc.sh)
|
||||
# ==============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ── Farben ─────────────────────────────────────────────────────────────────────
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
|
||||
|
||||
info() { echo -e "${CYAN}[INFO]${NC} $*"; }
|
||||
success() { echo -e "${GREEN}[OK]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
|
||||
|
||||
# ── Voraussetzungen prüfen ─────────────────────────────────────────────────────
|
||||
[[ $EUID -ne 0 ]] && error "Dieses Skript muss als root auf dem Proxmox-Host ausgeführt werden."
|
||||
command -v pct &>/dev/null || error "'pct' nicht gefunden – läuft das Skript auf einem PVE-Host?"
|
||||
command -v pvesh &>/dev/null || error "'pvesh' nicht gefunden – läuft das Skript auf einem PVE-Host?"
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
echo -e "\n${BOLD}╔══════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BOLD}║ Proxmox LXC – Debian + Docker + Portainer Installer ║${NC}"
|
||||
echo -e "${BOLD}╚══════════════════════════════════════════════════════════╝${NC}\n"
|
||||
|
||||
# ── Standardwerte ──────────────────────────────────────────────────────────────
|
||||
DEFAULT_CTID=$(pvesh get /cluster/nextid)
|
||||
DEFAULT_HOSTNAME="debian-docker"
|
||||
DEFAULT_PASSWORD="ChangeMe123!"
|
||||
DEFAULT_STORAGE="local-lvm"
|
||||
DEFAULT_DISK=8 # GB
|
||||
DEFAULT_RAM=2048 # MB
|
||||
DEFAULT_SWAP=512 # MB
|
||||
DEFAULT_CORES=2
|
||||
DEFAULT_BRIDGE="vmbr0"
|
||||
DEFAULT_IP="dhcp" # oder z.B. 192.168.1.100/24
|
||||
DEFAULT_GW="" # Gateway (nur bei statischer IP)
|
||||
|
||||
# ── Interaktive Eingabe ────────────────────────────────────────────────────────
|
||||
ask() {
|
||||
local prompt="$1" default="$2" var_name="$3"
|
||||
echo -ne "${BOLD}${prompt}${NC} [${YELLOW}${default}${NC}]: "
|
||||
read -r input
|
||||
printf -v "$var_name" '%s' "${input:-$default}"
|
||||
}
|
||||
|
||||
ask_yn() {
|
||||
local prompt="$1" default="${2:-y}"
|
||||
echo -ne "${BOLD}${prompt}${NC} [${YELLOW}${default}${NC}]: "
|
||||
read -r yn
|
||||
[[ "${yn:-$default}" =~ ^[Jj1Yy] ]]
|
||||
}
|
||||
|
||||
echo -e "${CYAN}── Container-Grundkonfiguration ────────────────────────────${NC}"
|
||||
ask "Container-ID" "$DEFAULT_CTID" CTID
|
||||
ask "Hostname" "$DEFAULT_HOSTNAME" HOSTNAME
|
||||
ask "Root-Passwort" "$DEFAULT_PASSWORD" PASSWORD
|
||||
ask "Storage" "$DEFAULT_STORAGE" STORAGE
|
||||
ask "Disk-Größe (GB)" "$DEFAULT_DISK" DISK
|
||||
ask "RAM (MB)" "$DEFAULT_RAM" RAM
|
||||
ask "Swap (MB)" "$DEFAULT_SWAP" SWAP
|
||||
ask "CPU-Kerne" "$DEFAULT_CORES" CORES
|
||||
ask "Netzwerk-Bridge" "$DEFAULT_BRIDGE" BRIDGE
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}── Netzwerk ────────────────────────────────────────────────${NC}"
|
||||
echo -e " Für DHCP einfach '${YELLOW}dhcp${NC}' eingeben."
|
||||
echo -e " Für statische IP z.B. '${YELLOW}192.168.1.100/24${NC}'"
|
||||
ask "IP-Adresse" "$DEFAULT_IP" IP_ADDR
|
||||
if [[ "$IP_ADDR" != "dhcp" ]]; then
|
||||
ask "Gateway" "$DEFAULT_GW" GATEWAY
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}── Optionale Komponenten ───────────────────────────────────${NC}"
|
||||
if ask_yn "Portainer CE installieren? (Web-UI für Docker)" "j"; then
|
||||
INSTALL_PORTAINER=true
|
||||
ask "Portainer HTTPS-Port" "9443" PORTAINER_PORT
|
||||
else
|
||||
INSTALL_PORTAINER=false
|
||||
fi
|
||||
|
||||
if ask_yn "SSH-Zugriff für root aktivieren?" "j"; then
|
||||
ENABLE_ROOT_SSH=true
|
||||
else
|
||||
ENABLE_ROOT_SSH=false
|
||||
fi
|
||||
|
||||
if ask_yn "Unprivilegierten Container erstellen? (empfohlen)" "j"; then
|
||||
UNPRIVILEGED=1
|
||||
else
|
||||
UNPRIVILEGED=0
|
||||
fi
|
||||
|
||||
# ── Zusammenfassung ────────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo -e "${BOLD}╔══════════════ Zusammenfassung ════════════════╗${NC}"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "Container-ID:" "$CTID"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "Hostname:" "$HOSTNAME"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "Storage:" "$STORAGE"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "Disk:" "${DISK} GB"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "RAM / Swap:" "${RAM} MB / ${SWAP} MB"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "CPU-Kerne:" "$CORES"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "Netzwerk:" "$IP_ADDR"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "Portainer:" "$( $INSTALL_PORTAINER && echo "Ja (:${PORTAINER_PORT})" || echo "Nein" )"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "Root-SSH:" "$( $ENABLE_ROOT_SSH && echo "Ja" || echo "Nein" )"
|
||||
printf "${BOLD}║${NC} %-22s %-20s ${BOLD}║${NC}\n" "Unprivilegiert:" "$( [[ $UNPRIVILEGED -eq 1 ]] && echo "Ja" || echo "Nein" )"
|
||||
echo -e "${BOLD}╚══════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
ask_yn "Jetzt installieren?" "j" || { echo "Abgebrochen."; exit 0; }
|
||||
|
||||
# ── Debian-Template herunterladen ──────────────────────────────────────────────
|
||||
info "Suche aktuelles Debian-LXC-Template …"
|
||||
TEMPLATE_STORAGE="local"
|
||||
TEMPLATE=$(pveam available --section system | awk '/debian-1[2-9]/ {print $2}' | sort -V | tail -1)
|
||||
[[ -z "$TEMPLATE" ]] && error "Kein Debian-Template in der PVE-Datenbank gefunden. 'pveam update' ausführen!"
|
||||
|
||||
DOWNLOADED=$(pveam list "$TEMPLATE_STORAGE" 2>/dev/null | awk '{print $1}' | grep -F "$TEMPLATE" || true)
|
||||
if [[ -z "$DOWNLOADED" ]]; then
|
||||
info "Lade Template herunter: $TEMPLATE"
|
||||
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
|
||||
success "Template geladen."
|
||||
else
|
||||
success "Template bereits vorhanden: $TEMPLATE"
|
||||
fi
|
||||
|
||||
TEMPLATE_PATH="${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}"
|
||||
|
||||
# ── LXC-Container erstellen ────────────────────────────────────────────────────
|
||||
info "Erstelle LXC-Container $CTID …"
|
||||
|
||||
NET_CONFIG="name=eth0,bridge=${BRIDGE}"
|
||||
if [[ "$IP_ADDR" == "dhcp" ]]; then
|
||||
NET_CONFIG+=",ip=dhcp"
|
||||
else
|
||||
NET_CONFIG+=",ip=${IP_ADDR}"
|
||||
[[ -n "${GATEWAY:-}" ]] && NET_CONFIG+=",gw=${GATEWAY}"
|
||||
fi
|
||||
|
||||
pct create "$CTID" "$TEMPLATE_PATH" \
|
||||
--hostname "$HOSTNAME" \
|
||||
--password "$PASSWORD" \
|
||||
--storage "$STORAGE" \
|
||||
--rootfs "${STORAGE}:${DISK}" \
|
||||
--memory "$RAM" \
|
||||
--swap "$SWAP" \
|
||||
--cores "$CORES" \
|
||||
--net0 "$NET_CONFIG" \
|
||||
--unprivileged "$UNPRIVILEGED" \
|
||||
--features "keyctl=1,nesting=1" \
|
||||
--onboot 1 \
|
||||
--start 0
|
||||
|
||||
success "Container $CTID erstellt."
|
||||
|
||||
# ── Container starten ──────────────────────────────────────────────────────────
|
||||
info "Starte Container …"
|
||||
pct start "$CTID"
|
||||
sleep 5
|
||||
|
||||
# ── Hilfsfunktion: Befehl im Container ausführen ──────────────────────────────
|
||||
lxc_exec() { pct exec "$CTID" -- bash -c "$*"; }
|
||||
|
||||
# ── System aktualisieren ───────────────────────────────────────────────────────
|
||||
info "System aktualisieren (apt update & upgrade) …"
|
||||
lxc_exec "apt-get update -qq && apt-get upgrade -y -qq"
|
||||
lxc_exec "apt-get install -y -qq ca-certificates curl gnupg lsb-release wget"
|
||||
success "System aktuell."
|
||||
|
||||
# ── Docker installieren (offizieller Weg) ─────────────────────────────────────
|
||||
info "Docker Engine installieren …"
|
||||
lxc_exec "
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg \
|
||||
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg --yes
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
|
||||
echo \"deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
||||
https://download.docker.com/linux/debian \
|
||||
\$(. /etc/os-release && echo \"\$VERSION_CODENAME\") stable\" \
|
||||
> /etc/apt/sources.list.d/docker.list
|
||||
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq \
|
||||
docker-ce docker-ce-cli containerd.io \
|
||||
docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
systemctl enable docker --now
|
||||
"
|
||||
success "Docker installiert."
|
||||
|
||||
# ── Docker testen ──────────────────────────────────────────────────────────────
|
||||
info "Docker-Funktionstest …"
|
||||
if lxc_exec "docker run --rm hello-world" &>/dev/null; then
|
||||
success "Docker läuft korrekt."
|
||||
else
|
||||
warn "Docker-Test fehlgeschlagen – bitte manuell prüfen."
|
||||
fi
|
||||
|
||||
# ── Portainer installieren ─────────────────────────────────────────────────────
|
||||
if $INSTALL_PORTAINER; then
|
||||
info "Portainer CE installieren (Port ${PORTAINER_PORT}) …"
|
||||
lxc_exec "
|
||||
docker volume create portainer_data
|
||||
docker run -d \
|
||||
--name portainer \
|
||||
--restart always \
|
||||
-p 8000:8000 \
|
||||
-p ${PORTAINER_PORT}:9443 \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v portainer_data:/data \
|
||||
portainer/portainer-ce:latest
|
||||
"
|
||||
success "Portainer CE gestartet."
|
||||
fi
|
||||
|
||||
# ── SSH konfigurieren ──────────────────────────────────────────────────────────
|
||||
if $ENABLE_ROOT_SSH; then
|
||||
info "Aktiviere Root-SSH-Login …"
|
||||
lxc_exec "
|
||||
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
|
||||
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
||||
systemctl restart ssh
|
||||
"
|
||||
success "Root-SSH aktiviert."
|
||||
fi
|
||||
|
||||
# ── Abschluss ──────────────────────────────────────────────────────────────────
|
||||
CONTAINER_IP=$(pct exec "$CTID" -- hostname -I 2>/dev/null | awk '{print $1}' || echo "unbekannt")
|
||||
|
||||
echo ""
|
||||
echo -e "${BOLD}${GREEN}╔═══════════════════════ Fertig! ═══════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║${NC}"
|
||||
echo -e "${GREEN}║${NC} Container-ID : ${BOLD}${CTID}${NC}"
|
||||
echo -e "${GREEN}║${NC} Hostname : ${BOLD}${HOSTNAME}${NC}"
|
||||
echo -e "${GREEN}║${NC} IP-Adresse : ${BOLD}${CONTAINER_IP}${NC}"
|
||||
echo -e "${GREEN}║${NC}"
|
||||
echo -e "${GREEN}║${NC} Docker : ${BOLD}installiert & aktiv${NC}"
|
||||
if $INSTALL_PORTAINER; then
|
||||
echo -e "${GREEN}║${NC} Portainer : ${BOLD}https://${CONTAINER_IP}:${PORTAINER_PORT}${NC}"
|
||||
fi
|
||||
if $ENABLE_ROOT_SSH; then
|
||||
echo -e "${GREEN}║${NC} SSH : ${BOLD}ssh root@${CONTAINER_IP}${NC}"
|
||||
fi
|
||||
echo -e "${GREEN}║${NC}"
|
||||
echo -e "${GREEN}║${NC} ${YELLOW}Bitte das Root-Passwort nach dem ersten Login ändern!${NC}"
|
||||
echo -e "${GREEN}║${NC}"
|
||||
echo -e "${BOLD}${GREEN}╚═══════════════════════════════════════════════════════╝${NC}\n"
|
||||
Reference in New Issue
Block a user