What it does
Keeping servers patched is one of those jobs that’s important, boring and easy to forget. This script does it for you on Ubuntu 24.04. It updates your packages, deals with any that get kept back, and makes sure the server ends up fully up to date. If a reboot is needed afterwards, it does that too. Set it up once and your servers look after themselves.
#!/bin/bash
# Define a file to track progress
PROGRESS_FILE="/var/log/update-script-progress"
# Function to check if a reboot is required
check_reboot() {
if [ -f /var/run/reboot-required ]; then
echo "Reboot required. Rebooting now..."
echo "step1_reboot" > $PROGRESS_FILE
reboot
exit 0
fi
}
# Function to check the progress and continue where left off
check_progress() {
if [ -f $PROGRESS_FILE ]; then
PROGRESS=$(cat $PROGRESS_FILE)
case $PROGRESS in
"step1_reboot")
echo "Continuing after first reboot..."
step2_install_updates
;;
"step2_updates")
echo "Continuing after updates..."
step3_install_kept_back
;;
"step3_kept_back")
echo "Continuing after installing kept-back packages..."
check_reboot_after_updates
;;
*)
echo "Unknown progress state, starting from the beginning."
start_script
;;
esac
else
start_script
fi
}
# Function to start the script
start_script() {
check_reboot
step2_install_updates
}
# Function to perform updates
step2_install_updates() {
echo "Updating package lists..."
sudo apt update
echo "Upgrading installed packages..."
# Set non-interactive frontend to avoid prompts
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y --with-new-pkgs
echo "step2_updates" > $PROGRESS_FILE
step3_install_kept_back
}
# Function to install kept-back packages
step3_install_kept_back() {
echo "Installing kept-back packages..."
# Install kept-back packages by explicitly listing them
KEPT_BACK=$(apt list --upgradable 2>/dev/null | grep -P '^\S+' -o)
if [ -n "$KEPT_BACK" ]; then
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y $KEPT_BACK
fi
echo "step3_kept_back" > $PROGRESS_FILE
check_reboot_after_updates
}
# Function to check if a reboot is required after updates
check_reboot_after_updates() {
check_reboot
cleanup
}
# Function to clean up unnecessary packages
cleanup() {
echo "Cleaning up unnecessary packages..."
sudo apt autoremove -y
sudo apt autoclean
echo "System is up to date. No reboot required."
rm -f $PROGRESS_FILE
}
# Start or continue the script
check_progress
Features
- Automatic updates. It refreshes the package lists, upgrades everything installed, and also installs packages that would normally be kept back during an upgrade.
- Automatic reboots. If an update needs a reboot (a new kernel, for example), the script reboots the server for you.
- Progress tracking. It records how far it’s got in
/var/log/update-script-progress, so if it’s interrupted, by a reboot for instance, it carries on where it left off. - Runs unattended. Everything runs non-interactively, so it’s perfect for cron and never sits waiting for someone to press a key.
How it works
- Checks for a pending reboot. First it looks to see if a previous update already needs a reboot, and reboots if so.
- Updates and upgrades. It refreshes the package lists (
apt update), upgrades installed packages (apt-get upgrade --with-new-pkgs), then installs any held back packages explicitly (apt-get install). - Reboots if needed. Once the updates are done it checks again and reboots if required.
- Tidies up. It removes packages that are no longer needed and clears out the cache (
apt autoremove,apt autoclean) to free up space. - Logs as it goes. Progress is saved at each step so it can always pick up again after an interruption.
Where I use it
I still run this script on some of my own servers, where it patches them every night without anyone touching them. It suits the servers where a nightly reboot doesn’t matter and nothing needs careful timing. For a server other things depend on, it’s safer to patch at a time you choose, with a snapshot or backup taken first so there’s a clean way back.
Setting it up
Save the script to a file on your server, for example /opt/scripts/update-script.sh.
Make it executable:
sudo chmod +x /opt/scripts/update-script.sh
Schedule it with cron. To run it every night at 2am, open your crontab:
sudo crontab -e
Then add:
# Run the script at 2 AM every day to ensure the system is updated
0 2 * * * /opt/scripts/update-script.sh >> /var/log/update-script.log 2>&1
# Run the script at system reboot to continue updates if the system was rebooted during an update
@reboot /opt/scripts/update-script.sh >> /var/log/update-script.log 2>&1
The first line is the nightly 2am run that does the regular updates.
The @reboot line is the important one. If the server reboots part way through an update, whether the script rebooted it or someone did it by hand, this makes sure the script starts again on boot and finishes the job.
Between the two, your server gets updated every night and never gets left half way through.
Running it by hand. You can also run it yourself at any time:
sudo /opt/scripts/update-script.sh
Worth knowing
- Logs. Progress goes to
/var/log/update-script-progressand, with the cron setup above, the output goes to/var/log/update-script.log. It’s worth keeping an eye on these, at least for the first few runs. - Permissions. The script needs to run commands like
apt-getandreboot, so it needs root (orsudo). - Test it first. Run it by hand once before you hand it over to cron, so you know it behaves on your server.
Once that’s in place your server keeps itself patched, which cuts down your exposure to security holes and means you’re always on the latest fixes.
Disclaimer
Before you run any automated update script, make sure you’ve got backups you trust. Regular backups are the thing that gets you out of trouble when something unexpected happens.
This script is designed to apply updates safely and cope with reboots along the way, but automatic updates always carry some risk.
You use this script at your own risk. I can’t take responsibility for any damage, data loss or downtime that comes from running it. Please make sure you have full backups before using this, or any other automation, on your systems.
Related reading
total 1
More projects
total 12