Cup¶
Monitoring des mises à jour d'images Docker sur l'ensemble de l'infrastructure.
Informations¶
| Paramètre | Valeur |
|---|---|
| URL | https://updates.ncls.ltd (Authelia one_factor) |
| URL locale | http://192.168.1.101:8000 |
| Port | 8000 |
| Image | ghcr.io/sergi0g/cup:latest |
| LXC | LXC 101 – Management (serveur) + agents sur tous LXC |
| Config | /opt/docker/cup/cup.json |
| API | http://192.168.1.101:8000/api/v3/json |
Architecture¶
Cup utilise un modèle serveur + agents pour couvrir tous les LXC :
| Rôle | LXC | IP:Port | Containers surveillés |
|---|---|---|---|
| Serveur | 101 | 192.168.1.101:8000 | Web UI, agrège locaux + tous les agents |
| Agent | 100 | 192.168.1.100:8000 | jellyfin, sonarr, radarr, bazarr, sabnzbd… |
| Agent | 103 | 192.168.1.103:8000 | caddy, authelia, wireguard, portainer-agent |
| Agent | 104 | 192.168.1.104:8000 | endurain, freshrss, romm, gramps, portainer-agent |
| Agent | 105 | 192.168.1.105:8000 | sites wordpress (asc, lmdp, nliautaud) |
| Agent | 106 | 192.168.1.106:8000 | sftpgo |
Configuration Docker¶
Serveur (LXC 101, dans docker-compose.yaml) :
cup:
container_name: cup
image: ghcr.io/sergi0g/cup:latest
restart: unless-stopped
command: -c /config/cup.json serve -p 8000
ports:
- "8000:8000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /opt/docker/cup/cup.json:/config/cup.json:ro
environment:
- TZ=Europe/Paris
Agent (chaque autre LXC, dans leur docker-compose.yml) :
cup:
container_name: cup
image: ghcr.io/sergi0g/cup:latest
restart: unless-stopped
command: serve -p 8000
ports:
- "8000:8000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CUP_AGENT=true
- TZ=Europe/Paris
Important (bug #157) : L'agent Cup LXC 103 n'a intentionnellement aucun
networks:. Rejoindre le réseauproxydu LXC 103 provoque un crash au démarrage.
Configuration cup.json¶
Path : /opt/docker/cup/cup.json
{
"$schema": "https://raw.githubusercontent.com/sergi0g/cup/main/cup.schema.json",
"version": 3,
"refresh_interval": "0 0 */6 * * *",
"servers": {
"LXC 100 - Médias": "http://192.168.1.100:8000",
"LXC 103 - Réseau": "http://192.168.1.103:8000",
"LXC 104 - Services": "http://192.168.1.104:8000",
"LXC 105 - Web": "http://192.168.1.105:8000",
"LXC 106 - Stockage": "http://192.168.1.106:8000"
}
}
Le refresh automatique s'exécute toutes les 6h (cron 6 champs avec secondes obligatoires).
Homepage Widget¶
Widget customapi dans services.yaml :
widget:
type: customapi
url: http://192.168.1.101:8000/api/v3/json
refreshInterval: 30000
method: GET
mappings:
- field: metrics.monitored_images
label: Monitored
format: number
- field: metrics.up_to_date
label: Up to date
format: number
- field: metrics.updates_available
label: Updates
format: number
Cup et Renovate — coexistence¶
Depuis mai 2026, l'infrastructure utilise Renovate pour les mises à jour GitOps. Cup reste complémentaire mais leurs périmètres diffèrent :
| Cup | Renovate | |
|---|---|---|
| Source | Containers en cours d'exécution (docker.sock) | Fichiers docker-compose.yml dans le monorepo git |
Images :latest, :lts |
✅ Détecte les changements de digest | ❌ Ignoré intentionnellement |
| Images semver épinglées | ✅ Détecte la nouvelle version | ✅ Ouvre une PR automatiquement |
zensical/zensical |
✅ Visible | ⚠️ PR créée, label needs-review |
| Action | Information uniquement (UI) | PR + merge + deploy automatisé |
En pratique : Cup peut afficher beaucoup d'"updates" que Renovate n'ouvre pas en PR. C'est normal. Les mises à jour de digest sur :latest sont exclues du pipeline GitOps par design — elles n'ont pas de version sémantique à bumper.
Pour les images hors pipeline GitOps (:latest, services hors monorepo), la mise à jour reste manuelle si nécessaire.
Pour l'explication complète, voir Mise à jour Docker.
Maintenance¶
# Voir les updates disponibles (API JSON)
pct exec 101 -- curl -s http://localhost:8000/api/v3/json | \
python3 -c "
import json, sys
d = json.load(sys.stdin)
for img in d['images']:
r = img.get('result', {})
if r.get('has_update'):
print(f' [{img.get(\"server\") or \"local\"}] {img[\"reference\"]} → {r[\"info\"]}')"
# Métriques globales
pct exec 101 -- curl -s http://localhost:8000/api/v3/json | \
python3 -c "import json,sys; print(json.load(sys.stdin)['metrics'])"
# Logs serveur
pct exec 101 -- docker logs cup --tail 30
# Forcer un refresh (redémarrer le serveur)
pct exec 101 -- docker restart cup
# Mettre à jour Cup lui-même
pct exec 101 -- bash -c "cd /opt/docker && docker compose pull cup && docker compose up -d cup"
# Status agents
for lxc in 100 103 104 105 106; do
echo -n "LXC $lxc: "
pct exec $lxc -- docker ps --filter name=cup --format "{{.Status}}" 2>/dev/null
done
Notes¶
- LXC 103 utilise l'image Cup depuis Zot :
192.168.1.107:5000/ghcr/sergi0g/cup:3.5.1— pas d'export/import manuel nécessaire depuis la mise en place de Zot.