VPS security · Practical guide

Patch an Ubuntu VPS with package checks, restart verification and a recovery plan

Inspect Ubuntu updates, simulate package changes, verify unattended-upgrades and check services and reboot requirements after maintenance.

Archive placement: September 2024

Network equipment in server racks

Patching is a sequence of discovery, change and verification. An administrator needs to know which repositories supply the software, what an upgrade will change and how the application behaves afterward. Automatic security updates can reduce routine work, but they do not maintain every container, plugin or manually installed dependency on the server.

Identify the operating system and package sources

Inspect release and package configuration
cat /etc/os-release
uname -r
apt-cache policy
systemctl --failed
df -h / /var /boot

Check that the operating-system release and the packages you depend on still have appropriate support. Repository entries can include third-party software, but adding a repository does not automatically make unattended-upgrades maintain it. Record applications installed outside apt, including containers, Python environments, Node packages and manually downloaded binaries.

Check free space before starting. A full filesystem or /boot partition can leave a package operation incomplete. Do not remove package-manager lock files to force an upgrade; first establish whether another legitimate apt or unattended-upgrade process is running and allow it to finish.

Refresh package information and simulate the change

Review pending upgrades without installing them
sudo apt update
apt list --upgradable
apt-mark showhold
sudo apt-get -s upgrade

The simulation helps identify changed packages and anything held back. It is not a guarantee that the application is compatible with a new library or runtime. Review proposed removals and major changes separately. Do not use dist-upgrade or a release upgrade simply to clear a list of pending updates without understanding the wider effect.

Create a completed recovery point and any application-specific exports before a substantial change. For an online shop or database-backed service, decide how writes will be handled during rollback: restoring yesterday's server image can also remove today's orders.

Apply updates and inspect the actual outcome

Run the reviewed upgrade, then check system state
sudo apt upgrade
systemctl --failed
sudo journalctl -p err --since '30 minutes ago' --no-pager
test ! -e /var/run/reboot-required || cat /var/run/reboot-required

Read configuration-file prompts rather than automatically replacing local settings. Inspect the actual application units, not only generic system errors: for example, systemctl status nginx.service or the unit that starts your application. Service names differ between web stacks, so substitute the installed service.

A reboot-required notice means you should plan a reboot, not ignore it indefinitely. Check console access first, notify affected users where needed and verify a fresh SSH connection and application transaction afterward. The running kernel shown by uname -r should be compared with the installed and intended kernel, rather than assuming that package installation changed the running system.

Audit automatic updates instead of assuming they work

Inspect the daily upgrade path
systemctl list-timers 'apt-daily*' --all --no-pager
sudo unattended-upgrade --dry-run --debug
sudo tail -n 80 /var/log/unattended-upgrades/unattended-upgrades.log

The unattended-upgrades package and log file must exist for those checks. The dry run explains eligible packages and configured origins without installing them. Review /etc/apt/apt.conf.d/20auto-upgrades and 50unattended-upgrades, including allowed origins, notifications and reboot behavior. Use a maintained local override when you need custom policy.

A timer that exists is not proof of successful installation. Look for recent completed runs and errors. Decide who receives notifications and how failed jobs become actionable work. Keep application-level updates in a separate inventory because system packages do not cover every way software reaches a VPS.

Verify a business workflow and preserve evidence

Example external response check from a separate machine
curl --fail --show-error --silent \
  --connect-timeout 5 --max-time 15 \
  -o /dev/null -w 'status=%{http_code} total=%{time_total}s
' https://example.com/

A successful response is a useful first check, but a cached home page may not exercise the database or background worker. Test a representative operation such as a controlled login, form submission or staging transaction, and inspect the related logs. Use a dedicated health endpoint only if your application implements one with the dependencies you intend to monitor.

Record the maintenance time, package changes, reboots and verification results. If a problem appears later, those notes help distinguish an upgrade regression from an unrelated traffic spike or application deployment.

Recover deliberately when a change fails

Start by determining whether the system is partially upgraded, a service is misconfigured or the application is incompatible. Inspect the package logs and the affected unit before changing more components. Restoring a known-good configuration may be enough; restoring a full server backup is a wider and potentially data-overwriting action.

  • Keep the previous configuration and a verified recovery point before maintenance.
  • Preserve console access if SSH or the network fails.
  • Coordinate rollback with any application data written since the backup.
  • Resolve the cause of a failed update before re-enabling the same automatic change.

Primary documentation

← Back to all guidesDiscuss your hosting setup ↗