Upgrading Ubuntu LTS on a VPS Without Breaking Your Site
Your VPS still shows "Ubuntu 20.04.6 LTS" every time you log in, and the motd keeps nagging you that standard support has ended. You know you should move to 22.04 or 24.04, but the site is live, customers are on it, and a botched release upgrade can take down PHP, Nginx, and even your SSH access all at once. Here's how to do it without turning it into an incident.
Why This Isn't Just Another apt upgrade
Running apt update && apt upgrade keeps you patched within the same Ubuntu release — say, 22.04.3 to 22.04.4. That's routine and low-risk. A release upgrade (20.04 → 22.04, or 22.04 → 24.04) is a different animal: it swaps out your entire package repository, replaces core system libraries, and can silently change default versions of PHP, Python, and OpenSSL under whatever's running on the box.
Most support tickets we see aren't from the upgrade failing outright — they're from it succeeding technically while quietly breaking a site, a cron job, or a custom-compiled service nobody remembered existed.
Symptom: You're Avoiding the Upgrade (or It Won't Even Offer)
Two versions of this show up constantly:
- You've been putting it off. The server works today, so "upgrade later" has been the plan for eight months, and now you're out of security patches for the base OS entirely.
- The prompt refuses to appear. You run
do-release-upgradeand get "No new release found" even though a newer LTS clearly exists.
The second one is usually one of two settings. Check /etc/update-manager/release-upgrades — if Prompt=never or Prompt=lts is set and you're not yet eligible for the next LTS's .1 point release, the tool won't offer it. For LTS-to-LTS jumps, set Prompt=lts and try again; for the newest release before its first point update, you may need Prompt=normal temporarily.
Cause: What Actually Breaks Mid-Upgrade
Before you touch anything, know what you're walking into. The usual suspects:
- Third-party PPAs. A PPA added for the old codename (e.g.
focal) has no package for the new one (jammyornoble), so apt either fails the upgrade or silently drops the package. - PHP version jumps. Ubuntu 20.04 ships PHP 7.4 by default, 22.04 ships 8.1, 24.04 ships 8.3. If your app hard-depends on an older PHP and you're on the distro's stock packages (not Ondřej Surý's PPA), the upgrade can leave you on an incompatible version or break extensions like
mysqliorgd. - Config file conflicts. Nginx, Apache, and SSH configs you've hand-edited will trigger a "keep your version or install the maintainer's?" prompt during the upgrade. Answer wrong and you either lose your customizations or miss a required new directive.
- Docker and containerd. Docker's own apt repo is pinned to a specific Ubuntu codename. After the OS upgrade,
dockercommands can fail until you re-add the repo for the new release. - Kernel and reboot requirement. A release upgrade always installs a new kernel and needs a reboot to take effect — if that reboot doesn't come back cleanly, you need console access, not just SSH, to fix it.
Fix: A Safe, Boring Upgrade Path
Boring is the goal here. Skip nothing on this list, even for a small VPS.
1. Snapshot or full backup first, no exceptions
Take a VPS snapshot before you start. If you're on Getwebup, this is VPS → Snapshots → Create Snapshot — it takes a minute and turns a bad upgrade into a five-minute rollback instead of a rebuild.
2. Confirm your current state and clean up first
lsb_release -a
sudo apt update && sudo apt upgrade -y
sudo apt --purge autoremove -y
sudo apt list --installed | grep -i ppa
Fully patch the current release before upgrading — do-release-upgrade refuses to run cleanly on a system with pending updates. Remove or disable third-party PPAs you don't strictly need:
sudo add-apt-repository --remove ppa:some/old-ppa
sudo rm /etc/apt/sources.list.d/unused-repo.list
3. Open a safety-net console session
Keep your normal SSH session open, but also open your provider's browser-based console (Getwebup: VPS → Console) in a second tab before you start. If the upgrade breaks SSH or the network stack, the console is how you get back in without waiting on a support ticket.
4. Run the upgrade
sudo apt install update-manager-core -y
sudo do-release-upgrade
It'll walk you through package removals, new packages, and config conflicts one at a time. For any "modified config file" prompt on Nginx, Apache, PHP-FPM, or SSH, choose to view the diff before deciding — usually "keep the local version" is right, but check whether the new default adds something you need (a new SSL cipher list, a new PHP-FPM directive).
5. Reboot, then verify everything, in this order
sudo reboot
# after reconnecting:
lsb_release -a
sudo systemctl status nginx php8.1-fpm mysql
sudo nginx -t
curl -I https://yourdomain.com
If a service shows PHP version mismatches after the jump, re-point your web server config at the new socket path — Ubuntu often renames it, e.g. /run/php/php7.4-fpm.sock becomes /run/php/php8.1-fpm.sock.
6. Re-add pinned repos (Docker, Node, etc.)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update
Which Version Are You Actually Jumping To?
| Ubuntu Release | Codename | Default PHP | Standard Support Ends |
|---|---|---|---|
| 20.04 LTS | focal | 7.4 | April 2025 (ESM after) |
| 22.04 LTS | jammy | 8.1 | April 2027 |
| 24.04 LTS | noble | 8.3 | April 2029 |
Never skip a release. Ubuntu only supports upgrading one LTS at a time — 20.04 → 22.04 → 24.04 — not a direct 20.04 → 24.04 jump. do-release-upgrade will refuse the skip anyway, but if you've mixed in manual sources.list edits to force it, that's exactly where systems end up unbootable.
Prevention: Make the Next One Boring Too
- Don't let the gap grow. Upgrade within the first year of a new LTS release, while both the old and new version are well-documented and actively discussed online.
- Test on a snapshot clone first if the box runs anything business-critical — spin up a clone, run the upgrade there, note every prompt and fix, then repeat on production with no surprises.
- Track your PPAs and custom repos in a text file on the server itself (
/root/custom-repos.txt) so future-you isn't reverse-engineering what's installed and why. - Schedule it for low-traffic hours and warn anyone who deploys to the box — the upgrade window is usually 20–40 minutes, but config conflicts can stretch that if you're reading diffs carefully (you should be).
When to Just Rebuild Instead
If the VPS is more than two LTS versions behind, has accumulated years of undocumented manual changes, or runs cPanel/WHM (which doesn't support Ubuntu at all — it needs AlmaLinux or CloudLinux), skip the in-place upgrade. Provision a fresh VPS on the target release, migrate the app and data over deliberately, and retire the old one. It takes longer up front but you're not debugging a decade of drift under time pressure.
Frequently asked questions
Can I upgrade straight from Ubuntu 20.04 to 24.04?
No. Ubuntu only supports upgrading one LTS release at a time, so 20.04 has to go through 22.04 before it can reach 24.04. do-release-upgrade will refuse to skip a release, and forcing it by hand-editing sources.list is how systems end up unbootable.
What happens if my SSH session drops in the middle of the upgrade?
do-release-upgrade runs a fallback SSH daemon on port 1022 during the process specifically so a dropped connection doesn't lock you out. Still, keep your provider's browser-based console open in a separate tab as a second way in if anything goes wrong.
Will my PHP version change automatically after the upgrade?
Yes, if you're using Ubuntu's stock PHP packages rather than a third-party PPA like Ondrej Sury's. Ubuntu 20.04 defaults to PHP 7.4, 22.04 to 8.1, and 24.04 to 8.3. Check your app's compatibility with the new default before you upgrade, not after.
Does this apply to a cPanel server too?
No. cPanel/WHM doesn't run on Ubuntu at all — it requires AlmaLinux, CloudLinux, or RHEL. If you're on a cPanel VPS, OS upgrades work differently and are usually handled via a fresh AlmaLinux reinstall rather than an in-place release upgrade.
How long does a release upgrade actually take?
Usually 20-40 minutes for a small-to-medium VPS, most of it spent downloading and installing packages. Budget extra time if you're carefully reviewing config-file conflict prompts instead of accepting the defaults, which you should be.