# Docker Compose Auto-Updater
---
> đź”§ Automatisches Update von Docker-Compose-Stacks mit feingranularer Steuerung per Labels
## 🚀 Features
- 🔄 **Stack-basiertes Update**
Aktualisiert komplette Docker-Compose Stacks strukturiert und kontrolliert
- đź§Ş **Dry-Run Modus**
Zeigt an, was passieren würde, ohne Änderungen durchzuführen
- 📲 **ntfy Benachrichtigungen**
Push-Notifications ĂĽber ntfy bei Updates, Fehlern oder Status
- ⚙️ **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
---
## đź“‚ Voraussetzungen
- Docker + Docker Compose (v2)
- Bash
- jq
- Optional: ntfy Server
---
## đź§ Funktionsweise
1. Alle `*compose*.yml` Dateien werden rekursiv gefunden
2. Verarbeitung erfolgt alphabetisch (deterministische Reihenfolge)
3. FĂĽr jeden Stack:
- Compose-Konfiguration wird ausgewertet (`docker compose config`)
- Services und deren Images werden ermittelt
- FĂĽr jedes Image:
- Image wird bei Bedarf gepullt (maximal einmal pro Image und Stack, Cache-basiert)
- Lokale Image-ID wird ermittelt
- Image-ID des vorhandenen Containers wird ermittelt (auch fĂĽr gestoppte Container)
4. Entscheidungslogik:
- ❌ Container existiert nicht → kein Update (nur Definition vorhanden)
- ❌ Image-ID unverändert → kein Update
- ✅ Image-ID hat sich geändert → Update erkannt
5. Wenn mindestens ein Service ein Update hat:
- **Einzelcontainer:**
- gezieltes Update nur dieses Services (`docker compose up -d `)
- **Mehrere Services:**
- kompletter Stack wird neu deployed (`docker compose up -d`)
- **Optional**
- feste Wartezeit nach dem Deploy (`REDEPLOY_WAIT`)
- anschlieĂźendes Warten auf erfolgreiche Healthchecks (`REDEPLOY_WAIT_HEALTHY`)
6. Sonderverhalten:
- Gestoppte Container werden ebenfalls geprĂĽft und bei Updates berĂĽcksichtigt
- Gestoppte Container werden nach dem Update optional wieder gestoppt
- Service-Verhalten wird vollständig über Labels gesteuert (`composeupdater.mode`)
- Je nach Modus werden Services:
- komplett ignoriert (`ignore`)
- nur ĂĽberwacht (`notify-only`)
- oder automatisch aktualisiert (`update`)
---
## ⚙️ 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
```
---
## 🗑️ Prune / Cleanup
Nach Abschluss der Updates kann optional ein Docker Cleanup durchgefĂĽhrt werden.
Dabei werden ungenutzte Ressourcen entfernt:
- `docker image prune`
→ entfernt ungenutzte („dangling“) Images
- `docker image prune -a`
→ entfernt alle Images, die von keinem Container verwendet werden
- `docker container prune`
→ entfernt gestoppte Container
- `docker volume prune`
→ entfernt ungenutzte Volumes
- `docker network prune`
→ entfernt ungenutzte Netzwerke
---
## đź”” ntfy
| Zustand | Priorität |
|----------------------|----------|
| ✔️ Keine Updates | 1 |
| 🔄 Updates vorhanden | 3 |
| ❌ Fehler | 5 |
### Anzeigebeispiel
---
## ⚙️ Konfiguration (`config.conf`)
```bash
# ==========================================================
# DOCKER COMPOSE UPDATER - CONFIG
# ==========================================================
# ----------------------------------------------------------
# PATH
# ----------------------------------------------------------
# Basisverzeichnis der Stacks [ String ]
PATH_COMPOSE_DIR="/pfad/zu/deinen/stacks"
# Compose-Dateiname [ String ]
PATH_COMPOSE_PATTERN="*compose*.yml"
# ----------------------------------------------------------
# LOG
# ----------------------------------------------------------
# Log-Datei [ String ]
LOG_FILE="/pfad/zum/log/update.log"
# Log-Level [ DEBUG | INFO | WARN | ERROR ]
LOG_LEVEL="INFO"
# ----------------------------------------------------------
# UPDATE
# ----------------------------------------------------------
# Nur Simulation, keine Änderungen [ true | false ]
UPDATE_DRY_RUN_ENABLED=false
# Gestoppte Container updaten [ true | false ]
UPDATE_INCLUDE_STOPPED=true
# Danach wieder starten [ true | false ]
UPDATE_START_STOPPED=false
# ----------------------------------------------------------
# REDEPLOY
# ----------------------------------------------------------
# Feste Wartezeit nach Redeploy [ Number ]
REDEPLOY_WAIT=45
# Warten bis Container healthy sind [ true | false ]
REDEPLOY_WAIT_HEALTHY=true
# Timeout in Sekunden fĂĽr healthy Check [ Number ]
REDEPLOY_WAIT_HEALTHY_TIMEOUT=60
# ----------------------------------------------------------
# NTFY SETTINGS
# ----------------------------------------------------------
# NTFY Zusammenfassung senden [ true | false ]
NTFY_ENABLED=true
# Server URL [ String ]
NTFY_URL="https://ntfy.example.com/topic"
# Token [ String ]
NTFY_TOKEN="DEIN_TOKEN"
# Titel mitsenden (optional) [ String ]
NTFY_TITLE="Autoupdate Report ($(hostname))"
# Tags mitsenden (optional) [ String ]
NTFY_TAGS="docker,update"
# Icon mitsenden (optional) [ String ]
NTFY_IMAGE_URL="http://dein-server/host-icon.png"
# Nur senden wenn Updates vorhanden [ true | false ]
NTFY_ONLY_ON_CHANGES=false
# Versionsnummern anzeigen [ true | false ]
NTFY_SHOW_VERSIONS=true
# ----------------------------------------------------------
# DOCKER CLEANUP
# ----------------------------------------------------------
# Prune Befehle ausfĂĽhren [ true | false ]
CLEANUP_ENABLED=true
# Nur nach erfolgten Updates ausfĂĽhren [ true | false ]
CLEANUP_ONLY_ON_UPDATE=true
# Images löschen [ true | false ]
CLEANUP_IMAGES_ENABLED=true
# Image-Prune Modus [ dangling | unused ]
CLEANUP_IMAGES_MODE="unused"
# Container löschen [ true | false ]
CLEANUP_CONTAINERS_ENABLED=true
# Volumes löschen [ true | false ]
CLEANUP_VOLUMES_ENABLED=false
# Networks löschen [ true | false ]
CLEANUP_NETWORKS_ENABLED=true
```
---
## ▶️ Nutzung
```bash
chmod +x script.sh
./script.sh
```
---
## đź“„ Beispiel Ausgabe
```
🔍 Prüfe Stack: rss
├─ read (phpdockerio/readability-js-server) [Mode: 🔄 update]
├─ merc (wangqiru/mercury-parser-api) [Mode: 🔄 update]
├─ full-text-rss (heussd/fivefilters-full-text-rss:latest) [Mode: 🔄 update]
├─ rss-bridge (rssbridge/rss-bridge:latest) [Mode: 🔄 update]
⬆ UPDATE
alt: rssbridge/rss-bridge:latest@sha256:55215923cf81b2fa6fbb7ecc1bd2555405f4fc06029ae9876e91164a735c7b9d
neu: rssbridge/rss-bridge:latest@sha256:f3f0218c8b075cbc7c559c8e6852888e95fa6d68258436da6195efc5ab98b025
└─ freshrss (freshrss/freshrss:latest) [Mode: 🔄 update]
♻️ Stack wird neu deployt (Trigger: rss-bridge)
⏳ Deploy läuft...
âś… Stack erfolgreich aktualisiert
đź’¤ Warte 60s nach Deploy
ℹ️ Keine Healthchecks definiert → überspringe warten
đź•’ Dauer: 18s
→ Prüfe Stack: tinymediamanager
└─ tinymediamanager [Mode: 🚫 ignore]
đź•’ Dauer: 1s
```
---
## ⚠️ Hinweise
Wird in einem Stack ein Container aktualisiert, wird anschließend der gesamte Stack neu gestartet, sofern er mehr als einen Container enthält. Dadurch wird sichergestellt, dass alle Abhängigkeiten wieder gemäß der `docker-compose.yml` ausgeführt werden.