Patching a server means updating the software running on it to fix security holes before attackers find them. If you've never done it, the process feels risky—what if an update breaks your site at midnight? I've seen that happen. But leaving a server unpatched is worse: automated bots scan the internet 24/7 for known vulnerabilities, and they move fast.
This guide walks you through the entire patching workflow from scratch. You'll learn what a patch is, why timing matters, how to test updates safely, and what to do when something goes wrong.
What a patch actually is
A patch is a piece of code that fixes a bug or closes a security vulnerability in existing software. When researchers discover a flaw in Apache, PHP, OpenSSH, or the Linux kernel itself, the maintainers release a patch. Your job is to apply it before attackers exploit it.
Patches come in two flavors:
- Security patches fix vulnerabilities that could let someone break in, steal data, or crash your server.
- Bug fixes and feature updates improve stability or add functionality but don't directly address security.
You care most about the first kind. The second kind can wait if you're short on time.
A vulnerability is a weakness in software that attackers can abuse. Each one gets a CVE identifier when disclosed publicly. Once a CVE is published, attackers write scripts to exploit it automatically. That's why unpatched servers get compromised hours after a vulnerability becomes public.
Why patching feels scary (and how to fix that)
I've talked to dozens of admins who avoid patching because they're afraid an update will break their production environment. That fear is rational. Poorly planned updates do cause outages.
But attackers don't wait for you to feel ready.
The solution is process, not procrastination. Test patches in a staging environment first, schedule updates during low-traffic windows, and keep a rollback plan ready. That turns patching from a gamble into a routine task.
Check what you're running first
Before you patch anything, you need to know what's installed. Log into your server via SSH and run these commands.
For Debian and Ubuntu
apt list --installed
This dumps every package on the system. To see only packages with available updates:
apt list --upgradable
For CentOS, AlmaLinux, Rocky Linux
yum list installed
Check for updates:
yum check-update
Or if you're on a newer system using DNF:
dnf check-update
You'll see a list of package names and version numbers. Security updates usually have "security" in the changelog or are flagged explicitly by the package manager.
Subscribe to security mailing lists
You can't patch vulnerabilities if you don't know they exist. Most distributions publish security announcements:
- Debian: debian-security-announce mailing list
- Ubuntu: ubuntu-security-announce
- Red Hat / CentOS / Alma / Rocky: RHSA (Red Hat Security Advisory) feed
Sign up for these. When a critical patch drops, you'll get an email explaining what's broken and which package fixes it.
If you run cPanel, check the cPanel blog and changelogs—they bundle patches for Apache, PHP, and other components.
Set up a staging server
Never test patches on production first. A staging server is a copy of your live environment where you can break things safely.
If you're on a budget, spin up a small VPS for twenty dollars a month. Install the same OS version, the same software stack, and restore a recent backup of your production database and config files. It doesn't need to handle real traffic—it just needs to prove that updates won't explode.
Apply patches to staging first, then run your application. Click through the site, test API endpoints, check logs for errors. If everything works, you're clear to patch production.
How to patch step by step
Here's the workflow I use on every server I manage.
1. Back up everything
Before touching the system, take snapshots. If your host offers snapshot backups (most cloud providers do), take one now. If not, use rsync or tar to copy critical files:
tar -czf /backup/server-backup-$(date +%F).tar.gz /etc /var/www /home
Back up databases separately:
mysqldump --all-databases > /backup/all-databases-$(date +%F).sql
Store backups somewhere other than the server itself. If the server dies, backups on the same disk won't help.
2. Read the changelog
Before running update commands, check what's about to change. For Debian/Ubuntu:
apt-changelog <package-name>
For RHEL-based systems:
yum updateinfo list security
Look for breaking changes. Did the update change default config file locations? Does it require a service restart? Does it drop support for an older PHP version your app depends on? Flag anything suspicious.
3. Apply the updates
On Debian/Ubuntu, update the package list first:
apt update
Then upgrade packages:
apt upgrade -y
For security-only updates:
apt install unattended-upgrades
unattended-upgrade -d
On RHEL/CentOS/Alma/Rocky:
yum update -y
Or for security patches only:
yum update --security -y
The -y flag auto-confirms prompts. Remove it if you want to review each package manually.
4. Restart services
Most patches don't take effect until you restart the affected service. If you patched Apache:
systemctl restart apache2
For Nginx:
systemctl restart nginx
For PHP-FPM:
systemctl restart php-fpm
Kernel updates require a full reboot:
reboot
Schedule reboots during maintenance windows, not during peak traffic.
5. Verify everything works
After restarting services, test the application. Load the homepage, log in, place a test order, check that cron jobs ran. Tail the error logs:
tail -f /var/log/apache2/error.log
tail -f /var/log/nginx/error.log
If you see new errors, investigate before moving on.
6. Monitor for 24 hours
Some issues don't surface immediately. A memory leak might take hours to crash PHP-FPM. A broken cron job might not run until 3 AM. Keep an eye on logs and resource usage for a day after patching.
Automate security updates (carefully)
Manually patching every week burns time. Automatic updates can handle routine security patches without your input—but only if you configure them correctly.
Debian and Ubuntu: unattended-upgrades
Install the package:
apt install unattended-upgrades
Edit /etc/apt/apt.conf.d/50unattended-upgrades to control what gets updated. By default, it applies security patches only. You can enable automatic reboots if a kernel update requires it:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
Test it:
unattended-upgrade --dry-run --debug
CentOS, Alma, Rocky: yum-cron or dnf-automatic
For yum:
yum install yum-cron
systemctl enable yum-cron
systemctl start yum-cron
Edit /etc/yum/yum-cron.conf and set:
apply_updates = yes
For DNF:
dnf install dnf-automatic
systemctl enable dnf-automatic.timer
systemctl start dnf-automatic.timer
Configure /etc/dnf/automatic.conf:
apply_updates = yes
Warning: Automatic updates are safe for most packages but risky for database servers, complex applications, or production systems where downtime costs money. Use them on staging first.
What if an update breaks something?
Rollbacks are why you took snapshots.
Roll back a single package
On Debian/Ubuntu, downgrade to the previous version:
apt install <package-name>=<old-version>
On RHEL-based systems:
yum downgrade <package-name>
Hold the package so it doesn't auto-update again:
apt-mark hold <package-name>
Or:
yum versionlock <package-name>
Restore from snapshot
If multiple packages broke or the system won't boot, restore the snapshot you took in step one. Every hosting provider has a different process—DigitalOcean, Vultr, and Linode all let you restore from the control panel in under a minute.
Kernel patching and live patching
Kernel updates fix the deepest security holes but require a reboot. That's a problem for servers that need 24/7 uptime.
Live patching applies kernel security fixes without rebooting. Ubuntu offers Livepatch (requires a free Ubuntu One account), and Red Hat has kpatch. If you can't afford downtime, these tools are worth setting up.
For Ubuntu Livepatch:
sudo snap install canonical-livepatch
sudo canonical-livepatch enable <your-token>
Get a token from the Ubuntu Livepatch portal. Free tier covers up to three machines.
Patch third-party software too
Operating system patches cover the base system, but most servers run additional software: WordPress, Node.js, Docker containers, control panels like cPanel or Plesk.
These need separate update workflows:
- WordPress: Updates are in the dashboard under Updates. Enable automatic updates for minor releases.
- Node.js apps: Run
npm audit fixoryarn upgradeto patch dependencies. - Docker images: Rebuild containers regularly with
docker build --no-cacheto pull the latest base image. - cPanel: cPanel pushes updates automatically if you enabled it in WHM under Update Preferences.
Don't ignore these. Attackers exploit outdated CMS plugins and npm packages just as often as they exploit OpenSSL.
How often should you patch?
Security patches: as soon as they're released, after testing.
Non-security updates: monthly or quarterly, depending on your tolerance for change.
Kernel updates: whenever a critical CVE appears, plus during scheduled maintenance windows.
In practice, I patch staging every week and promote tested updates to production within 48 hours unless something breaks.
Common mistakes that get servers compromised
Delaying critical patches. The window between public disclosure and mass exploitation is hours, not weeks. Patch fast.
Skipping staging tests. Pushing untested updates to production will eventually break something important at the worst possible time.
Ignoring third-party software. Patching the OS but leaving WordPress or Docker unpatched leaves attackers an easy entry point.
Not monitoring logs. You won't know if a patch broke something subtle until customers complain.
Disabling automatic updates without a manual schedule. If you turn off automation, you must commit to manual patching on a regular cadence.
What to patch first when time is short
If you only have an hour, prioritize these:
- OpenSSH – Controls remote access to your server.
- Web server (Apache, Nginx) – Directly exposed to the internet.
- PHP / Python / Node.js – Application-layer vulnerabilities are common.
- Kernel – Deepest level of security but requires reboot.
- Database (MySQL, PostgreSQL) – Often targeted but less urgent if not exposed externally.
Patch the attack surface first, then work your way down.
