How to keep a Linux server patched
Updating a VPS safely, handling the reboots that kernel updates require, and automating security patches so this stops being a manual chore.
An unpatched Linux server is not a ticking time bomb from any single vulnerability — it is a slow accumulation of known, already-fixed issues that a determined or automated attacker does not need any skill to exploit, only patience. Keeping a VPS updated is one of the highest-value, lowest-effort things you can do for it.
Updating on Ubuntu and Debian
sudo apt update
sudo apt upgrade -y
apt update refreshes the local list of what versions are available — it changes nothing on the system itself. apt upgrade then installs newer versions of already-installed packages, but will not remove a package or install a new one to satisfy a dependency change, which is what makes it safe to run routinely without surprises.
For upgrades that do need to add or remove packages to proceed — a distribution-provided kernel update, for instance — use:
sudo apt full-upgrade -y
This is more thorough and occasionally more disruptive, so it is worth reading the list of changes apt proposes before confirming on a production server, rather than always passing -y blindly.
Updating on RHEL, Rocky Linux and AlmaLinux
sudo dnf check-update
sudo dnf upgrade -y
dnf check-update lists what is available without installing anything; dnf upgrade (equivalent to the older dnf update) installs it, resolving dependencies as needed.
Reboot when a kernel update says to
A kernel update does not take effect until the server reboots into it — until then, the running system continues on the old kernel even though the new one is installed. Both package managers will tell you when this is the case:
# Debian / Ubuntu — presence of this file means a reboot is pending
ls /var/run/reboot-required
# RHEL family
sudo dnf needs-restarting -r
sudo reboot
A reboot briefly takes the server, and everything running on it, offline. Do it at a quiet time, and confirm beforehand that every service you rely on is set to start automatically — systemctl enable — rather than something you started manually and would otherwise have to remember to start again by hand.
Automating security updates
Manual updates get forgotten, especially on a server you only log into occasionally. Automating security patches specifically — leaving feature updates for you to review manually — closes most of the practical risk without any ongoing effort.
On Ubuntu and Debian:
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
Answer yes when asked whether to enable automatic updates. By default this applies security updates only, which is the sensible setting for a server you are not watching daily — review /etc/apt/apt.conf.d/50unattended-upgrades if you want to widen or narrow what it covers.
On RHEL, Rocky Linux and AlmaLinux, the equivalent is dnf-automatic:
sudo dnf install dnf-automatic -y
Edit /etc/dnf/automatic.conf and set apply_updates = yes under [commands] (it downloads but does not install by default), then enable the timer:
sudo systemctl enable --now dnf-automatic.timer
Checking what is scheduled and what already ran
systemctl list-timers | grep -E "apt|dnf"
And review what unattended-upgrades has actually done, rather than assuming silence means success:
cat /var/log/unattended-upgrades/unattended-upgrades.log # Debian / Ubuntu
journalctl -u dnf-automatic # RHEL family
Fully automatic updates of everything, including major version bumps of a database or a language runtime, can break an application without warning. The common, sensible middle ground is automating security patches only and reviewing anything larger manually, on your own schedule — which is what both tools above default to.
Major version upgrades are a separate, bigger job
Everything above keeps you current within the same distribution release — regular package updates, not a jump from one major version to the next (Ubuntu 22.04 to 24.04, for example). A major version upgrade can change default configurations, drop support for older packages, and occasionally requires application changes to match. Treat it as its own planned task with a backup taken immediately beforehand, rather than something to run casually alongside routine patching. Check your distribution's own upgrade guidance for the specific release before starting one.
A distribution upgrade changes configuration files and package versions in ways that are not always easy to reverse individually. Confirm a recent backup exists and that you know how to restore from it — see setting up automatic backups on a VPS — before starting anything larger than routine patching.
Troubleshooting: when an update does not go cleanly
| What you see | Likely cause | What to do |
|---|---|---|
Could not get lock /var/lib/dpkg/lock-frontend | Another package manager process is already running, or a previous one did not exit cleanly | Wait for any running apt or unattended-upgrades process to finish; only remove the lock file manually if you have confirmed nothing is genuinely still running |
| Upgrade stops with unmet dependencies | A partially completed previous upgrade, or a package held back deliberately | Run sudo apt --fix-broken install, then retry the upgrade |
| A service fails to start after updating | A configuration file format changed between versions, or the update replaced a config file you had customised | Check the service's status and logs with systemctl status and journalctl -u <service>, and compare against the .dpkg-old or .rpmsave backup of your previous config, which the package manager keeps automatically |
| Server does not come back after a reboot | A kernel or boot configuration issue introduced by the update, rare but not impossible | Use your provider's console or rescue access rather than only retrying SSH, since SSH itself may not have started if the boot failed earlier in the process |
dnf reports a GPG key or repository error | An expired or missing signing key for one of the configured repositories | Update the repository's key following that repository's own documentation rather than disabling signature checks, which removes an important protection |
A routine worth keeping
- Set up automatic security updates once, as above, and confirm the log shows it actually ran within the last week.
- Log in periodically and run a manual
apt upgrade/dnf upgradeyourself, to catch anything the automated job intentionally leaves for review. - Reboot promptly once a kernel update flags that it is pending, rather than leaving a server running an old kernel indefinitely.
Patching is only half of keeping a server healthy day to day — pair it with monitoring server resources so you notice a problem building before an update alone would have caught it.
Frequently asked questions
Will updating break my website?
A routine apt upgrade or dnf upgrade rarely does, since it only replaces existing packages with newer versions of the same software. The bigger risk is a major version jump in something your site depends on directly, such as PHP or a database engine, which is why it is worth reading what a full or distribution upgrade proposes to change before confirming it on a server running something live.
What if a package upgrade fails partway through?
Run sudo apt --fix-broken install (Debian and Ubuntu) or sudo dnf history to inspect and, if needed, sudo dnf history undo <id> to roll back the specific transaction (RHEL family). Do this before trying the upgrade again rather than repeating the same command and hoping it clears itself.
How do I know if a reboot is safe to do right now?
Check who and what is currently active with who and systemctl list-units --failed, and confirm every service you rely on is enabled to start automatically with systemctl is-enabled <service>. If everything is enabled and nothing else depends on the server being up at that exact moment, a reboot is safe to run.
How often should I check for updates manually?
Weekly is a reasonable habit for most small VPS setups, on top of automated security patching running in the background. It gives you a regular point to review anything the automated job intentionally left for manual approval, without turning patching into a daily task.
Related reading
The five-field crontab syntax explained properly, plus the logging habit that stops a failed scheduled job from failing silently.
How to secure a new Linux serverThe concrete steps that actually matter for securing a fresh Linux server, in the order that keeps you from locking yourself out.
How to restart services safelyThe right systemctl commands to restart or reload a Linux service, and why checking its status straight afterwards is not optional.
How to set up automatic backups on a VPSA simple, scripted backup covering files and databases, scheduled with cron and copied off the server, plus how to actually test it.