
Letting updates pile up is an easy way to lose control of a VPS. The fix isn’t “run apt upgrade when you remember.” Build a routine you can trust: automatic security patches, a reboot plan that won’t wake you at 3am, and an audit trail you can show when someone asks what changed.
This VPS security update tutorial walks through a production-friendly patch setup for Ubuntu and Debian. You’ll use unattended-upgrades, reboot control, restart checks, and a simple “prove it / roll back” mindset.
It’s written for real hosting stacks: WordPress, cPanel/DirectAdmin nodes, small SaaS apps, and agency VPS fleets.
What you’ll build in this VPS security update tutorial
- Automatic security patching via
unattended-upgrades(with sane defaults) - Reboot control (no surprise overnight reboots unless you allow it)
- Verification: logs, timers, and reports that show what actually ran
- Kernel/user-space restart checks so you know when a reboot is truly required
- A practical maintenance runbook: patch, test, restart, reboot, validate
Prerequisites and sizing (don’t skip this)
Treat patching like capacity planning. Most security updates are small. The real risk comes from restarts, reboots, and a disk that’s too full for dpkg to work.
- OS: Ubuntu 22.04/24.04 LTS or Debian 12/13
- Access: root SSH or a sudo user
- Disk headroom: keep at least 2–5 GB free on
/and/varto avoid dpkg failures - Time sync: accurate time prevents TLS and cron oddities; if you suspect drift, use our VPS time sync troubleshooting tutorial
If you host client sites or multiple apps, don’t run this on a starved VPS. Leave CPU/RAM headroom so upgrades don’t stall.
Headroom also helps you avoid restarts during peak traffic.
A HostMyCode VPS fits this workflow well because you can plan maintenance windows and snapshot before changes.
Step 1: Baseline your current patch status (and spot obvious risk)
Start by checking what the server thinks is pending. This shows whether you’re tuning an existing routine or clearing a backlog.
uname -a
cat /etc/os-release
apt update
apt -s upgrade
apt -s full-upgrade
On Debian and Ubuntu, “security updates” often show up as normal package updates. There isn’t one magic command you can rely on.
The goal is simple. Automate the safe part (security upgrades). Control the disruptive part (reboots).
Step 2: Install unattended-upgrades and the right helper packages
unattended-upgrades should feel boring. It installs approved updates on a schedule and leaves logs you can audit later.
apt install -y unattended-upgrades apt-listchanges needrestart
unattended-upgrades: runs the automated patchingapt-listchanges: shows/emails upstream changelogs for updated packages (useful when a dependency change surprises you)needrestart: identifies services that should be restarted after upgrades and flags when a reboot is required
Step 3: Configure unattended-upgrades for security-only (recommended)
The most common failure mode is enabling “everything” and getting an unexpected change at the wrong time. For hosting workloads, start with security-only.
Apply feature updates during a planned window. Give yourself time to test.
Edit:
nano /etc/apt/apt.conf.d/50unattended-upgrades
Use these patterns as a baseline. The exact entries vary by distro and release. The intent stays the same.
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
};
Unattended-Upgrade::Package-Blacklist {
// Example: hold back a known-problem package by name
// "openssl";
};
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Automatic-Reboot-Time "03:30";
Unattended-Upgrade::Mail "root";
Unattended-Upgrade::MailReport "on-change";
Notes that matter in production:
- Reboots are off above on purpose. You control reboot timing.
MailReport "on-change";gives you a change record without daily spam.- Dependency cleanup helps keep the system tidy, but watch it on servers with uncommon modules.
Step 4: Enable the schedule (systemd timers) and confirm it runs
On current Ubuntu and Debian releases, unattended upgrades usually run via systemd timers. Enable it, then confirm it’s active.
systemctl enable --now unattended-upgrades
systemctl status unattended-upgrades
systemctl list-timers | grep -E 'apt|unattended'
Then read what actually happened:
tail -n 80 /var/log/unattended-upgrades/unattended-upgrades.log
tail -n 80 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
If you want to validate the configuration without changing the system, run a dry-run:
unattended-upgrade --dry-run --debug
Step 5: Control reboots with a predictable maintenance window
Many security updates patch shared libraries used by Nginx/Apache and PHP. In those cases, a service restart is often enough.
Kernel updates are different. You usually need a reboot to get the protection.
A practical pattern looks like this:
- Let unattended upgrades install security patches daily
- Schedule a weekly reboot window (or reboot only when required)
Create a weekly check that reboots only if needed. One simple marker is /var/run/reboot-required (common on Ubuntu).
Another option is needrestart (works across both).
Option A: Ubuntu-style reboot-required file (simple)
nano /usr/local/sbin/reboot-if-required
#!/bin/sh
set -eu
if [ -f /var/run/reboot-required ]; then
logger "reboot-if-required: reboot required, rebooting now"
/sbin/reboot
else
logger "reboot-if-required: no reboot required"
fi
chmod +x /usr/local/sbin/reboot-if-required
Now schedule it. If you use cron:
crontab -e
# Sundays at 04:10
10 4 * * 0 /usr/local/sbin/reboot-if-required
Option B: needrestart-driven approach (more accurate)
This reduces guesswork. It also shows exactly what needs attention.
needrestart -r i
If it reports a kernel restart is required, plan a reboot window. If it only lists services, restart those services first (next step) and keep the box up.
Step 6: Restart the right services after patching (web + mail + SSH)
Rebooting every time a library changes turns routine patching into downtime. Where it’s safe, restart only what needs it.
After an unattended run (or during your maintenance window), check what’s affected:
needrestart
Common services to restart on hosting VPS setups:
php8.x-fpm(WordPress, Laravel, Magento on Nginx/Apache)nginxorapache2redis-server/memcachedif you use object cachingpostfix/dovecotif the VPS handles mail
Examples:
systemctl restart php8.3-fpm
systemctl restart nginx
systemctl restart postfix dovecot
Pitfall: avoid restarting SSH remotely unless you have out-of-band access or a second session open. If you must touch it, reload is safer than restart:
systemctl reload ssh
Step 7: Validate you didn’t break HTTPS, redirects, or WordPress logins
When patching goes wrong, it usually shows up fast. Common symptoms include TLS failures, 502/503 responses, or redirect loops after a web stack restart.
- Check HTTPS negotiation and the certificate chain quickly:
curl -I https://yourdomain.com
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
If redirects get strange after changes to the web server or PHP, follow our HTTPS redirect troubleshooting tutorial.
For WordPress, test the real money paths: /wp-login.php, admin actions, and checkout. If you run aggressive caching, watch logged-in cookies and cart sessions.
(If caching is next on your list, our WordPress full-page caching tutorial helps you avoid the usual WooCommerce pitfalls.)
Step 8: Add a “patch proof” checklist you can reuse every month
Use this runbook for planned maintenance windows (weekly or monthly). It’s short on purpose.
- Confirm backups/snapshots exist (and you can restore). If you haven’t practiced, run a restore drill using our VPS restore drill tutorial.
- Update and upgrade:
apt update apt -y upgrade - See what needs restarting:
needrestart - Restart services (web, PHP-FPM, mail if applicable).
- Check if a reboot is required:
test -f /var/run/reboot-required && cat /var/run/reboot-required || true - Reboot during your window (if required), then validate the site(s):
reboot # After reconnect: uptime systemctl --failed curl -I https://yourdomain.com
Step 9: Get alerts when patching fails (quietly)
unattended-upgrades writes everything down. That’s not enough if nobody reads the logs.
Two low-effort options:
- Email reports via
Unattended-Upgrade::MailReport(already configured earlier) - Daily log summaries using Logwatch
Logwatch works well for small fleets. If you want that setup, follow our Logwatch setup tutorial.
Pay attention to apt/dpkg errors and auth anomalies.
Step 10: Make updates safer with staging and DNS cutover (for high-value sites)
If one WordPress site or store outage costs real money, treat OS updates like deployments. Test first, then ship.
- Clone production to a staging VPS and patch there first.
- Validate checkout, forms, admin, and backups.
- Patch production after staging looks clean.
HostMyCode can help you move and validate faster via managed migrations, especially if you’re consolidating sites from shared hosting to a VPS.
For planned traffic-safe moves, use a low TTL and keep a rollback plan ready. Our DNS cutover tutorial lays out a cutover process that avoids the usual downtime traps.
Troubleshooting: common update failures on hosting VPS servers
dpkg was interrupted / “configure -a” errors
dpkg --configure -a
apt -f install
apt update && apt -y upgrade
If it keeps failing, check disk space first. Low /var causes a lot of “mystery” upgrade problems on busy servers.
“No space left on device” during upgrades
Don’t guess—measure. Our VPS disk space troubleshooting tutorial walks you through finding the culprit (logs, caches, mail queues, backups).
Quick cleanup that’s usually safe:
apt clean
journalctl --vacuum-time=14d
After updates: 502/503 errors or PHP timeouts
Start with service status. Then go straight to the error logs.
systemctl status nginx php8.3-fpm --no-pager
tail -n 120 /var/log/nginx/error.log
tail -n 120 /var/log/apache2/error.log
If you host many sites on one VPS, per-site PHP-FPM limits keep one noisy tenant from taking everything down. See our VPS PHP-FPM pool tuning tutorial.
Kernel updated but you haven’t rebooted yet
Compare what you’re running with what’s installed:
uname -r
ls -1 /boot/vmlinuz-* | tail
If a newer kernel is installed but not running, schedule a reboot window.
On high-traffic systems, take a quick snapshot (when available) and confirm backups before you reboot.
Hardening your patch workflow (small upgrades that add real safety)
- Keep SSH safe before you automate anything. If you need a clean baseline, follow our SSH lockdown tutorial.
- Limit exposure during maintenance by tightening inbound rules. If your firewall policy is still “allow all,” fix that first. (We have a separate guide, but keep this tutorial focused on patching.)
- Document your maintenance window in a shared note: day/time, expected reboot behavior, rollback path.
- Test restores quarterly. Backups you never restore are just expensive archives.
If you want predictable patching without late-night surprises, start with a VPS that has enough headroom for maintenance and growth. A managed VPS hosting plan can also handle routine update hygiene, service restarts, and basic security checks while you focus on your sites.
If you prefer to run it yourself, a fast HostMyCode VPS gives you full control over schedules, snapshots, and change windows.
FAQ
Should I enable automatic reboots for security updates?
For production hosting VPS servers, default to no. Auto-reboots can hit during traffic spikes or heavy cron windows. Reboot on your schedule when the kernel changes.
Is unattended-upgrades enough, or do I still need manual maintenance?
You still need periodic maintenance for kernel reboots, feature updates, and application-level changes (PHP versions, modules, config updates). Unattended upgrades mainly reduce risk between planned windows.
How do I know if I must reboot after updates?
Use needrestart and check for /var/run/reboot-required (commonly present on Ubuntu). If a new kernel is installed, you’ll usually need a reboot to actually be protected.
Will automatic security updates break WordPress?
Security updates rarely break WordPress directly, but they can restart PHP-FPM or the web server. That tends to expose existing configuration issues. That’s why the validation step (curl checks, error logs) matters.
What’s the safest way to patch a server that hosts multiple client sites?
Patch staging first for your highest-value sites, then patch production during a window. Pair that with per-site PHP-FPM pools and tested backups so one failure doesn’t become a multi-site outage.
Summary: a calm, repeatable patch workflow
This VPS security update tutorial covered unattended security patching, controlled reboot behavior, and a verification loop you can run quickly.
That’s the difference between “we patch sometimes” and a process you can repeat every month without surprises.
If you’re consolidating sites or want a cleaner maintenance path, move to a VPS you can right-size and run properly. Start with HostMyCode VPS or offload the routine work to managed VPS hosting for fewer surprises and clearer accountability.