Arrêt automatique Proxmox (VM, LXC et hôte)
pve01 s’allume via Wake-on-LAN quand j’en ai besoin. Le soir, je veux l’éteindre sans avoir à me connecter à la main — mais surtout sans couper le courant pendant qu’une VM écrit sur disque ou qu’un LXC termine une opération. Un hard power-off « pour aller plus vite » finit toujours par coûter plus cher en restauration ou en doute sur l’intégrité des données. D’où ce guide : un script qui demande un arrêt gracieux aux VM et aux conteneurs, attend, force ce qui reste bloqué, puis coupe l’hôte ; un cron le déclenche à heure fixe (22h10 chez moi).
1. Le script d’arrêt
Section titled “1. Le script d’arrêt”Le script vit en /usr/local/bin/full_shutdown.sh. Il parcourt d’abord les VM (qm) et les LXC (pct), lance un shutdown avec timeout en parallèle, patiente quatre-vingt-dix secondes pour laisser les systèmes d’invités finir proprement, puis repasse en stop forcé sur ce qui tourne encore. Seulement ensuite il appelle shutdown -h now sur l’hôte Proxmox. Ce n’est pas élégant, mais c’est prévisible — et c’est ce que je veux à 22h quand je ne suis plus devant l’écran.
#!/bin/bash# Arrêt complet Proxmox : VM + LXC + hôte# Arrêt propre avec délai, puis forcé si besoin
echo "=== [$(date)] Début de la séquence d'arrêt complet ==="
echo "--- Arrêt des machines virtuelles ---"for vmid in $(qm list | awk 'NR>1 {print $1}'); do echo "Arrêt VM $vmid ..." qm shutdown "$vmid" --timeout 60 &done
echo "--- Arrêt des conteneurs LXC ---"for ctid in $(pct list | awk 'NR>1 {print $1}'); do echo "Arrêt LXC $ctid ..." pct shutdown "$ctid" --timeout 60 &done
echo "--- Pause de 90 secondes pour arrêt propre ---"sleep 90
echo "--- Arrêt forcé des VM restantes ---"for vmid in $(qm list | awk 'NR>1 {print $1}'); do status=$(qm status "$vmid" | awk '{print $2}') if [ "$status" = "running" ]; then echo "Arrêt forcé VM $vmid" qm stop "$vmid" fidone
echo "--- Arrêt forcé des LXC restants ---"for ctid in $(pct list | awk 'NR>1 {print $1}'); do status=$(pct status "$ctid" | awk '{print $2}') if [ "$status" = "running" ]; then echo "Arrêt forcé LXC $ctid" pct stop "$ctid" fidone
echo "=== Toutes les VM et LXC sont arrêtées ==="echo "--- Extinction du serveur ---"shutdown -h nowOn le rend exécutable, puis on le teste une fois à la main en acceptant que la machine s’éteigne pour de bon. Ce n’est qu’après ce test que je fais confiance au cron : un script jamais exécuté « parce que ça a l’air bon » est exactement le genre de surprise du dimanche soir.
chmod +x /usr/local/bin/full_shutdown.sh/usr/local/bin/full_shutdown.sh2. Planifier avec cron
Section titled “2. Planifier avec cron”Sous root, crontab -e, une ligne suffit pour lancer le script tous les soirs à 22h10 :
10 22 * * * /usr/local/bin/full_shutdown.shJe vérifie que le service cron est actif et que la crontab contient bien la ligne (systemctl enable --now cron, crontab -l). L’heure se déplace selon l’usage — l’important, c’est le couple avec le WoL : allumer pve01 quand le lab k3s sert, l’éteindre proprement quand il ne sert plus. Sur un cluster qu’on laisse 24h/24, ce script n’a pas d’intérêt ; sur un nœud on-demand, c’est ce qui rend le schéma tenable sans y penser chaque soir.