.
This commit is contained in:
104
README.md
104
README.md
@@ -16,7 +16,7 @@ Aktualisiert komplette Docker-Compose Stacks strukturiert und kontrolliert
|
||||
Zeigt an, was passieren würde, ohne Änderungen durchzuführen
|
||||
- 📲 ntfy Benachrichtigungen
|
||||
Push-Notifications über ntfy bei Updates, Fehlern oder Status
|
||||
- ⏭️ Exclude-Liste
|
||||
- ⚙️ Service-Modi (per Label steuerbar)
|
||||
Einzelne Container oder komplette Stacks gezielt vom Update ausschließen
|
||||
- 🗑️ Prune Funktion
|
||||
Entfernt nicht mehr benötigte Images/Container automatisch
|
||||
@@ -65,6 +65,91 @@ Entfernt nicht mehr benötigte Images/Container automatisch
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Service-Modi (per Label steuerbar)
|
||||
|
||||
Du kannst das Verhalten einzelner Services oder ganzer Stacks über Labels steuern:
|
||||
|
||||
```yml
|
||||
labels:
|
||||
- composeupdater.mode=update
|
||||
```
|
||||
|
||||
### 📊 Übersicht
|
||||
|
||||
| Mode | Pull | Compare | Update | ntfy |
|
||||
| ----------- | ---- | ------- | ------ | ---- |
|
||||
| update | ✅ | ✅ | ✅ | ✅ |
|
||||
| notify-only | ✅ | ✅ | ❌ | ✅ |
|
||||
| ignore | ❌ | ❌ | ❌ | ❌ |
|
||||
|
||||
|
||||
### 🧠 Erklärung der Modi
|
||||
|
||||
🔄 `update` (**Standard**)
|
||||
- Images werden gepullt
|
||||
- Lokales Image wird mit dem Container verglichen
|
||||
- Bei Änderungen wird der Service bzw. Stack aktualisiert
|
||||
- ntfy-Benachrichtigung wird gesendet
|
||||
|
||||
|
||||
🔔 `notify-only`
|
||||
- Image wird gepullt (für Vergleich notwendig)
|
||||
- Es wird geprüft, ob ein Update verfügbar ist
|
||||
- Kein Container-Update / kein Restart
|
||||
- ntfy informiert über verfügbare Updates
|
||||
|
||||
|
||||
🚫 `ignore`
|
||||
- Service wird komplett ignoriert
|
||||
- Kein Pull
|
||||
- Kein Vergleich
|
||||
- Kein Update
|
||||
- Keine Benachrichtigung
|
||||
|
||||
|
||||
### 🧩 Beispiele
|
||||
|
||||
#### Service ausschließen (komplett ignorieren)
|
||||
|
||||
```yml
|
||||
services:
|
||||
db:
|
||||
image: postgres:15
|
||||
labels:
|
||||
- composeupdater.mode=ignore
|
||||
```
|
||||
|
||||
#### Nur Benachrichtigung, kein automatisches Update
|
||||
|
||||
```yml
|
||||
services:
|
||||
app:
|
||||
image: myapp:latest
|
||||
labels:
|
||||
- composeupdater.mode=notify-only
|
||||
```
|
||||
|
||||
#### Explizit Standardverhalten setzen
|
||||
|
||||
```yml
|
||||
services:
|
||||
web:
|
||||
image: nginx:latest
|
||||
labels:
|
||||
- composeupdater.mode=update
|
||||
```
|
||||
|
||||
#### 📦 Stack-Level Label (optional)
|
||||
|
||||
Du kannst das Verhalten auch für den gesamten Stack setzen:
|
||||
|
||||
```yml
|
||||
labels:
|
||||
- composeupdater.mode=ignore
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗑️ Prune / Cleanup
|
||||
|
||||
Nach Abschluss der Updates kann optional ein Docker Cleanup durchgeführt werden.
|
||||
@@ -161,23 +246,6 @@ REDEPLOY_WAIT_HEALTHY=true
|
||||
REDEPLOY_WAIT_HEALTHY_TIMEOUT=60
|
||||
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# EXCLUDES
|
||||
# ----------------------------------------------------------
|
||||
|
||||
# Stacks vom Update ausschließen [ Array ]
|
||||
EXCLUDE_STACKS=(
|
||||
"example_stack_1"
|
||||
"example_stack_2"
|
||||
)
|
||||
|
||||
# Services vom Update ausschließen [ Array ]
|
||||
EXCLUDE_SERVICES=(
|
||||
"example_container_1"
|
||||
"example_container_2"
|
||||
)
|
||||
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# NTFY SETTINGS
|
||||
# ----------------------------------------------------------
|
||||
|
||||
17
config.conf
17
config.conf
@@ -53,23 +53,6 @@ REDEPLOY_WAIT_HEALTHY=true
|
||||
REDEPLOY_WAIT_HEALTHY_TIMEOUT=60
|
||||
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# EXCLUDES
|
||||
# ----------------------------------------------------------
|
||||
|
||||
# Stacks vom Update ausschließen [ Array ]
|
||||
EXCLUDE_STACKS=(
|
||||
"example_stack_1"
|
||||
"example_stack_2"
|
||||
)
|
||||
|
||||
# Services vom Update ausschließen [ Array ]
|
||||
EXCLUDE_SERVICES=(
|
||||
"example_container_1"
|
||||
"example_container_2"
|
||||
)
|
||||
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# NTFY SETTINGS
|
||||
# ----------------------------------------------------------
|
||||
|
||||
@@ -42,6 +42,30 @@ fi
|
||||
# Helper
|
||||
# =============================
|
||||
|
||||
|
||||
get_service_mode() {
|
||||
local svc="$1"
|
||||
|
||||
echo "$compose_json" \
|
||||
| jq -r --arg svc "$svc" '
|
||||
.services[$svc].labels // []
|
||||
| map(select(startswith("composeupdater.mode=")))
|
||||
| .[0] // "composeupdater.mode=update"
|
||||
| split("=")[1]
|
||||
'
|
||||
}
|
||||
|
||||
|
||||
get_stack_mode() {
|
||||
echo "$compose_json" \
|
||||
| jq -r '
|
||||
.labels // []
|
||||
| map(select(startswith("composeupdater.mode=")))
|
||||
| .[0] // "composeupdater.mode=update"
|
||||
| split("=")[1]
|
||||
'
|
||||
}
|
||||
|
||||
is_excluded() {
|
||||
local svc="$1"
|
||||
for ex in "${EXCLUDE_SERVICES[@]}"; do
|
||||
@@ -58,6 +82,21 @@ is_stack_excluded() {
|
||||
return 1
|
||||
}
|
||||
|
||||
is_label_excluded() {
|
||||
local svc="$1"
|
||||
|
||||
echo "$compose_json" \
|
||||
| jq -r --arg svc "$svc" '
|
||||
.services[$svc].labels // {}
|
||||
| (if type=="array"
|
||||
then map(split("=") | {(.[0]): .[1]}) | add
|
||||
else .
|
||||
end)
|
||||
| .["composeupdater.enable"] // empty
|
||||
' \
|
||||
| grep -qi "^false$"
|
||||
}
|
||||
|
||||
get_image() {
|
||||
local svc="$1"
|
||||
|
||||
@@ -241,7 +280,6 @@ stack_tree=()
|
||||
|
||||
cd "$PATH_COMPOSE_DIR"
|
||||
|
||||
|
||||
while IFS= read -r -d '' file; do
|
||||
|
||||
declare -A pulled_images
|
||||
@@ -249,11 +287,6 @@ while IFS= read -r -d '' file; do
|
||||
dir=$(dirname "$file")
|
||||
stack=$(basename "$dir")
|
||||
|
||||
if is_stack_excluded "$stack"; then
|
||||
log INFO "→ Stack $stack übersprungen (excluded)"
|
||||
continue
|
||||
fi
|
||||
|
||||
log INFO ""
|
||||
log INFO "→ Prüfe Stack: $stack"
|
||||
|
||||
@@ -263,6 +296,14 @@ while IFS= read -r -d '' file; do
|
||||
|
||||
compose_json=$(docker compose config --format json)
|
||||
|
||||
stack_mode=$(get_stack_mode)
|
||||
|
||||
if [ "$stack_mode" = "ignore" ]; then
|
||||
log INFO "→ Stack $stack übersprungen (label=ignore)"
|
||||
cd "$PATH_COMPOSE_DIR"
|
||||
continue
|
||||
fi
|
||||
|
||||
mapfile -t services < <(docker compose config --services)
|
||||
total_services=${#services[@]}
|
||||
current_index=0
|
||||
@@ -280,7 +321,6 @@ while IFS= read -r -d '' file; do
|
||||
for svc in "${services[@]}"; do
|
||||
|
||||
update_needed=false
|
||||
|
||||
current_index=$((current_index + 1))
|
||||
|
||||
if [ "$current_index" -eq "$total_services" ]; then
|
||||
@@ -296,13 +336,48 @@ while IFS= read -r -d '' file; do
|
||||
continue
|
||||
fi
|
||||
|
||||
if is_excluded "$svc"; then
|
||||
pull_with_retry "$image" || true
|
||||
notify_excluded_updates+=("$stack/$svc")
|
||||
log INFO " $prefix $svc (excluded)"
|
||||
mode=$(get_service_mode "$svc")
|
||||
|
||||
case "$mode" in
|
||||
|
||||
ignore)
|
||||
log INFO " $prefix $svc (ignore)"
|
||||
continue
|
||||
;;
|
||||
|
||||
notify-only)
|
||||
log INFO " $prefix $svc (notify-only)"
|
||||
|
||||
before_id=$(get_container_image_id "$svc")
|
||||
|
||||
# 👉 ohne Container kein Vergleich sinnvoll
|
||||
if [ -z "$before_id" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -z "${pulled_images[$image]:-}" ]; then
|
||||
pull_with_retry "$image" || true
|
||||
pulled_images[$image]=1
|
||||
fi
|
||||
|
||||
after_id=$(get_local_image_id "$image")
|
||||
|
||||
if [ "$before_id" != "$after_id" ]; then
|
||||
notify_excluded_updates+=("$stack/$svc")
|
||||
fi
|
||||
|
||||
continue
|
||||
;;
|
||||
|
||||
update)
|
||||
# normal weiterlaufen lassen
|
||||
;;
|
||||
|
||||
*)
|
||||
log WARN " $prefix $svc (unbekannter mode: $mode → fallback=update)"
|
||||
;;
|
||||
esac
|
||||
|
||||
log INFO " $prefix $svc ($image)"
|
||||
|
||||
before_id=$(get_container_image_id "$svc")
|
||||
@@ -314,7 +389,7 @@ while IFS= read -r -d '' file; do
|
||||
fi
|
||||
|
||||
# =============================
|
||||
# Pull + Vergleich (NEU)
|
||||
# Pull + Vergleich
|
||||
# =============================
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user