#!/bin/bash # ============================================ # CT Update Manager - Proxmox LXC Container # Aktualisiert alle laufenden Container # APT + Docker Compose Support # ============================================ # Aufruf: bash ct-update-manager.sh # Cron: 0 4 * * 0 bash /opt/scripts/ct-update-manager.sh # Quelle: sgit.space/downloads # ============================================ set -euo pipefail # --- Konfiguration --- LOG="/var/log/ct-updates.log" TELEGRAM_ENABLED=false # TELEGRAM_BOT_TOKEN="your-token" # TELEGRAM_CHAT_ID="your-chat-id" # --- Farben --- GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' log() { echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"; } send_telegram() { if [ "$TELEGRAM_ENABLED" = true ]; then curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ -d chat_id="${TELEGRAM_CHAT_ID}" \ -d text="$1" \ -d parse_mode="HTML" > /dev/null 2>&1 || true fi } # Nur auf PVE Host ausfuehren if ! command -v pct &> /dev/null; then echo -e "${RED}Fehler: Dieses Script muss auf dem Proxmox VE Host laufen.${NC}" exit 1 fi log "===== CT Update Manager gestartet =====" # Alle laufenden Container ermitteln RUNNING_CTS=$(pct list | awk '/running/ {print $1}' | sort -n) TOTAL=$(echo "$RUNNING_CTS" | wc -w) UPDATED=0 FAILED=0 DOCKER_UPDATED=0 SUMMARY="" log "Gefunden: $TOTAL laufende Container" for CT_ID in $RUNNING_CTS; do CT_NAME=$(pct list | awk -v id="$CT_ID" '$1==id {print $3}') log "--- CT $CT_ID ($CT_NAME) ---" # APT Update if pct exec "$CT_ID" -- bash -c "export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get upgrade -y -qq" >> "$LOG" 2>&1; then UPDATES=$(pct exec "$CT_ID" -- bash -c "apt list --upgradable 2>/dev/null | grep -c upgradable || echo 0") log "${GREEN}CT $CT_ID APT OK${NC} ($UPDATES ausstehend)" UPDATED=$((UPDATED + 1)) else log "${RED}CT $CT_ID APT FEHLER${NC}" FAILED=$((FAILED + 1)) SUMMARY="${SUMMARY}\nFEHLER: CT $CT_ID ($CT_NAME) APT Update fehlgeschlagen" continue fi # Docker Compose Update (falls vorhanden) if pct exec "$CT_ID" -- bash -c "command -v docker > /dev/null 2>&1" 2>/dev/null; then # docker-compose.yml suchen COMPOSE_DIRS=$(pct exec "$CT_ID" -- bash -c "find /opt /srv /home -maxdepth 3 -name 'docker-compose.yml' -o -name 'docker-compose.yaml' -o -name 'compose.yml' 2>/dev/null | xargs -I{} dirname {}" 2>/dev/null || true) for DIR in $COMPOSE_DIRS; do log " Docker Compose in $DIR..." if pct exec "$CT_ID" -- bash -c "cd $DIR && docker compose pull -q 2>/dev/null && docker compose up -d --remove-orphans 2>/dev/null" >> "$LOG" 2>&1; then log " ${GREEN}Docker Update OK${NC}: $DIR" DOCKER_UPDATED=$((DOCKER_UPDATED + 1)) else log " ${YELLOW}Docker Update uebersprungen${NC}: $DIR" fi done # Alte Images aufraeumen pct exec "$CT_ID" -- bash -c "docker image prune -f --filter 'until=48h' > /dev/null 2>&1" || true fi done # Zusammenfassung log "===== Zusammenfassung =====" log "Container gesamt: $TOTAL | APT OK: $UPDATED | Fehler: $FAILED | Docker: $DOCKER_UPDATED" if [ -n "$SUMMARY" ]; then log "Probleme:$SUMMARY" fi # Telegram Benachrichtigung MSG="CT Update Manager Container: $TOTAL APT OK: $UPDATED | Fehler: $FAILED Docker Updates: $DOCKER_UPDATED" [ -n "$SUMMARY" ] && MSG="${MSG} $(echo -e "$SUMMARY")" send_telegram "$MSG" log "===== Fertig ====="