This Bash script automates the update process for all nodes in a Proxmox cluster. It sequentially performs a complete system update on each node and sends an email notification with the status.
- β Automatic sequential updates of all cluster nodes
- β Automatic SSH key setup between nodes (optional with password)
- β Lock mechanism prevents concurrent executions
- β
Automatic installation of
needrestartif not present - β
Complete system update:
apt update,full-upgrade,autoremove,clean - β
Reboot status check using two methods:
needs-restarting -r(needrestart package)/var/run/reboot-required(Debian standard)
- β Detailed logging of all actions
- β Email notification with summary
- β No automatic reboot - administrator maintains manual control
apt-get install -y flock mailutilsOptional (for automatic SSH key setup with password):
apt-get install -y sshpass- Proxmox VE installed (Postfix is already included)
- Root SSH access between nodes
- Debian-based system (tested with Debian 13)
cd /root
git clone https://github.com/MrMasterbay/proxmox-auto-update.git
chmod +x proxmox-auto-update.shOr create manually:
nano /root/proxmox-auto-update.sh
# Paste script content
chmod +x /root/proxmox-auto-update.shOpen the script and modify the variables in the configuration section:
nano /root/proxmox-auto-update.shImportant configuration options:
# Email recipient
MAIL_TO="root@localhost" # Change to your email
# SSH password (optional - only if SSH keys are not yet configured)
SSH_PASSWORD="" # Leave empty or enter password
# Manual node list (only if no cluster is configured)
MANUAL_NODES="" # Example: "node2.domain.com node3.domain.com"Option A: Automatic setup with password
Set in the script:
SSH_PASSWORD="your_root_password"The script will automatically set up SSH keys on first run.
Option B: Manual setup
# Generate SSH key (if not present)
ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N ""
# Copy key to all other nodes
ssh-copy-id root@node2.domain.com
ssh-copy-id root@node3.domain.comRun the script manually:
/root/proxmox-auto-update.shCheck the log:
cat /var/log/proxmox-cluster-auto-update.logcrontab -eAdd:
0 3 * * * /root/proxmox-auto-update.sh0 3 * * 0 /root/proxmox-auto-update.sh0 3 1 * * /root/proxmox-auto-update.shProxmox VE comes with Postfix pre-installed and configured. You only need to verify the configuration.
# Check Postfix status
systemctl status postfix
# View main configuration
postconf -n
# Test email delivery
echo "Test message" | mail -s "Test Mail" your@email.comEdit the main configuration:
nano /etc/postfix/main.cfFor internet delivery, ensure these settings:
myhostname = node1.yourdomain.com
mydestination = $myhostname, localhost.$mydomain, localhost
relayhost =
inet_interfaces = all
Restart Postfix:
systemctl restart postfixIf your ISP blocks port 25, use an SMTP relay:
nano /etc/postfix/main.cfAdd:
relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
Create credentials file:
nano /etc/postfix/sasl_passwdContent:
[smtp.gmail.com]:587 your@gmail.com:your-app-password
Secure and activate:
chmod 600 /etc/postfix/sasl_passwd
postmap /etc/postfix/sasl_passwd
systemctl restart postfixecho "Test from Proxmox" | mail -s "Test Subject" your@email.com
# Check mail logs
tail -f /var/log/mail.log
# Check mail queue
mailq/var/log/proxmox-cluster-auto-update.logContains:
- Timestamps of all actions
- Update progress per node
- Errors and warnings
- Reboot status
- Summary
# Full log
cat /var/log/proxmox-cluster-auto-update.log
# Last 50 lines
tail -n 50 /var/log/proxmox-cluster-auto-update.log
# Live view while script is running
tail -f /var/log/proxmox-cluster-auto-update.log
# Search for errors
grep -i error /var/log/proxmox-cluster-auto-update.lognano /etc/logrotate.d/proxmox-auto-updateContent:
/var/log/proxmox-cluster-auto-update.log {
weekly
rotate 12
compress
delaycompress
missingok
notifempty
}
The script automatically detects cluster nodes using three methods:
Preferred method for Proxmox clusters:
pvecm nodesFallback method:
ls /etc/pve/nodesFor non-cluster setups or as override:
MANUAL_NODES="node2.domain.com node3.domain.com"====================================================================
Proxmox Cluster Auto-Update started: 2025-10-05 03:00:01
Coordinating Node: node1.domain.com
====================================================================
[03:00:01] Updating LOCAL node: node1.domain.com
[03:00:01] apt update β¦
[03:00:03] apt full-upgrade -y β¦
[03:00:25] apt autoremove -y β¦
[03:00:26] apt clean β¦
[03:00:26] Local node update completed
β οΈ /var/run/reboot-required exists β reboot required
[03:00:27] Found cluster nodes: node2.domain.com node3.domain.com
[03:00:27] Starting updates on remote nodes...
====================================================================
[03:00:27] Updating REMOTE node: node2.domain.com
====================================================================
[03:00:28] ========== Update starting on node2.domain.com ==========
[03:00:45] ========== Update completed on node2.domain.com ==========
β
/var/run/reboot-required absent β no reboot needed
====================================================================
[03:01:15] Updating REMOTE node: node3.domain.com
====================================================================
[03:01:16] ========== Update starting on node3.domain.com ==========
[03:01:33] ========== Update completed on node3.domain.com ==========
β οΈ /var/run/reboot-required exists β reboot required
--------------------------------------------------------------------
Proxmox Cluster Auto-Update finished: 2025-10-05 03:01:35
Cluster Update Summary:
β’ node1.domain.com: SUCCESS - Reboot required
β’ node2.domain.com: SUCCESS - No reboot needed
β’ node3.domain.com: SUCCESS - Reboot required
====================================================================
Subject: [PROXMOX CLUSTER] Auto-Update completed on all nodes
Content:
The scheduled Proxmox cluster update finished on all nodes.
Cluster Update Summary:
β’ node1.domain.com: SUCCESS - Reboot required
β’ node2.domain.com: SUCCESS - No reboot needed
β’ node3.domain.com: SUCCESS - Reboot required
For full details, see the log file at /var/log/proxmox-cluster-auto-update.log on node1.domain.com.
Solution 1: Set up SSH keys manually
ssh-copy-id root@node2.domain.comSolution 2: Set SSH_PASSWORD in script
SSH_PASSWORD="your_password"Solution 3: Test SSH connection
ssh -v root@node2.domain.comSymptom: Error message "another instance is already running"
Solution:
# Check if process is still running
ps aux | grep proxmox-cluster-auto-update
# If no process is running, remove lock file
rm /var/run/proxmox-auto-update.lockSolution 1: Test mail configuration
echo "Test" | mail -s "Test" your@email.com
tail -f /var/log/mail.logSolution 2: Check Postfix status
systemctl status postfix
journalctl -u postfix -n 50Solution 3: Check mail queue
mailq
postqueue -pSolution 4: Check if emails are being blocked
# Check if port 25 is blocked by ISP
telnet smtp.gmail.com 25
# If blocked, configure SMTP relay (see Email Configuration section)Symptom: "No cluster nodes detected"
Solution 1: Check cluster status
pvecm status
pvecm nodesSolution 2: Use manual node list
# Set in script:
MANUAL_NODES="node2.domain.com node3.domain.com"Symptom: "apt full-upgrade" error
Solution 1: Check repository issues
apt-get update
cat /etc/apt/sources.listSolution 2: Check disk space
df -h
apt-get clean
apt-get autoremoveSolution 3: Check held packages
apt-mark showhold- SSH Keys: Use SSH keys instead of passwords when possible
- Password in script: If
SSH_PASSWORDis set, protect the script:chmod 700 /root/proxmox-auto-update.sh
- Log files: Do not contain passwords, but do contain system information
- Root access: Script must run as root
- Backups: Make backups before major updates
# Cron for Sunday 3:00 AM (low load)
0 3 * * 0 /root/proxmox-auto-update.sh# Nagios/Icinga check
/usr/lib/nagios/plugins/check_file_age -f /var/log/proxmox-cluster-auto-update.log -w 86400 -c 172800Test updates in a test environment before applying to production.
For large clusters: Update nodes in groups
# Group 1: Mondays
MANUAL_NODES="node2 node3"
# Group 2: Wednesdays
MANUAL_NODES="node4 node5"# Proxmox backup before cron job
0 2 * * 0 vzdump --all --storage backup-storage
0 3 * * 0 /root/proxmox-auto-update.sh# In script:
MANUAL_NODES="node2.domain.com node3.domain.com"
# Ignore nodes from pvecm - only use MANUAL_NODES
# Comment out pvecm detection (lines 165-190)Create multiple script variants:
# Script 1: Only nodes 1+2
cp proxmox-auto-update.sh update-group1.sh
# Set: MANUAL_NODES="node1 node2"
# Script 2: Only nodes 3+4
cp proxmox-auto-update.sh update-group2.sh
# Set: MANUAL_NODES="node3 node4"
# Crontab:
0 3 * * 1 /root/update-group1.sh # Monday
0 3 * * 3 /root/update-group2.sh # WednesdayModify in script:
# Change line 31:
APTCMD="/usr/bin/apt-get -o Dpkg::Options::='--force-confold'"Add custom commands:
# Before update (line 330):
echo "[$(date '+%H:%M:%S')] Running pre-update hook β¦"
/root/pre-update-hook.sh
# After update (line 375):
echo "[$(date '+%H:%M:%S')] Running post-update hook β¦"
/root/post-update-hook.shsystemctl status postfix
systemctl enable postfix
systemctl start postfixecho "Test local" | mail -s "Test" root
cat /var/mail/rootpostconf -n | grep -E 'myhostname|mydestination|relayhost'tail -f /var/log/mail.logmailq
postqueue -p
postcat -q QUEUE_ID # Replace QUEUE_ID with actual ID from mailqpostqueue -fFix 1: Set proper hostname
hostnamectl set-hostname node1.yourdomain.com
postconf -e "myhostname = node1.yourdomain.com"
systemctl restart postfixFix 2: Allow localhost relay
postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128"
systemctl restart postfixFix 3: Fix email aliases
echo "root: your@email.com" >> /etc/aliases
newaliases
systemctl restart postfix- Proxmox Forum: https://forum.proxmox.com
- Proxmox Documentation: https://pve.proxmox.com/wiki/Main_Page
- Debian Wiki: https://wiki.debian.org
This script is freely available and can be modified and used as desired.
- Initial version
- Automatic cluster node detection
- SSH key management
- Email notifications
- Detailed logging
- Reboot status detection
# Check reboot status
cat /var/run/reboot-required
# Restart node
reboot