Using apt to install, update, and remove software on Ubuntu servers and Multipass VMs, safely. For Amazon Linux 1 servers, see the separate Amazon Linux 1 sheet.
READ-ONLY only looks; safeCHANGES THINGS be carefulON THE SERVER type it after logging in to the server$ = you type this
The basics
#1How software works on Ubuntu
Ubuntu installs software as packages from repositories: online catalogs run by Ubuntu. The tool that manages them is apt. It's the server version of Homebrew.
Words you'll see
Package
One installable piece of software, like apache2 or php8.3-curl.
Repository (repo)
An online catalog of packages. Ubuntu's own are set up already.
Dependency
Another package something needs. apt installs them automatically.
PPA
An extra repository run by someone else, for software or versions Ubuntu doesn't include (section 6).
apt vs apt-get
Same job. apt is the friendlier version for typing; older guides use apt-get. Both work.
GOOD TO KNOWAlmost every apt command that changes something needs sudo in front. Commands that only look don't.
Installed: the version on this server. (none) = not installed.
Candidate: the newest version available. Different from Installed = an update is waiting.
Example: install
sudo apt install unzipThe following NEW packages will be installed:
unzip
0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded.
Do you want to continue? [Y/n]
It lists what it will do first. Read the list, especially any line saying packages will be REMOVED.
[Y/n]: press Y (or just Enter, since the capital letter is the default) to go ahead, N to cancel.
E: Unable to locate package = typo, or the catalog is out of date. Run sudo apt update and try again.
⚠ CAREFULpurge deletes the program's settings files in /etc too, for example all of Apache's site settings with purge apache2. Use remove unless you're sure you want the settings gone.
Do it in this order, one command at a time. Reading the list before saying yes is what makes it safe.
What this updates
Everything installed with apt:
The operating system's parts: the kernel (the core of Linux), system libraries, security tools like OpenSSL, everyday commands.
Server software: Apache, PHP, and anything else installed with apt.
Ubuntu's small "point releases" (24.04.1, 24.04.2…) arrive this way too.
What it doesn't
It doesn't move to a new Ubuntu version. You stay on 24.04 and get its fixes.
Moving to the next version (like 26.04) is a separate, much bigger job (do-release-upgrade). For a live server, building a fresh one is usually safer than upgrading in place.
Anything not installed with apt isn't touched.
0. Before you start
On a client server: have a recent backup or AMI/snapshot, and pick a quiet time (not during exams).
On a Multipass VM: take a snapshot (see the Multipass sheet).
1. Refresh the catalog
sudo apt updateHit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Get:2 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB]
…
5 packages can be upgraded. Run 'apt list --upgradable' to see them.
Changes nothing installed. Hit = no change in that catalog; Get = downloaded a newer one. The last line says how many updates are waiting.
One line per package: name, where it comes from, new version, then the version you have now.
-security in the source = a security fix. Those matter most.
Look for anything big to your sites: apache2, php…, linux-image… (the kernel, which needs a reboot).
3. Install the updates
sudo apt upgrade
Shows the list again, then asks Do you want to continue? [Y/n].
The following upgrades have been deferred due to phasing = Ubuntu is rolling those out gradually. Normal; they'll come in a later run.
Get more security updates through Ubuntu Pro = an advertisement for Ubuntu's paid service. Safe to ignore.
Afterward it may say it's restarting services, or show a screen asking which services to restart. Accept the defaults (Tab to OK, then Enter).
4. Does it need a reboot? (read-only)
cat /var/run/reboot-required*** System restart required ***
No such file or directory = no reboot needed. Done.
*** System restart required *** = usually a kernel update. See which packages asked: cat /var/run/reboot-required.pkgs.
5. Reboot, if needed, at a quiet time
sudo reboot
Your connection drops. Wait a minute or two, log back in, and check your sites load.
6. Clean up (optional)
sudo apt autoremove
Removes old kernels and leftover helpers. It lists them first and asks [Y/n].
⚠ UPGRADE VS FULL-UPGRADEsudo apt upgrade never removes anything, which makes it the safe choice for routine updates. sudo apt full-upgrade may remove packages to complete an upgrade. Only use it when you've read the list and know why.
Ubuntu servers install security updates on their own every day, using a tool called unattended-upgrades. It's on by default. Regular (non-security) updates still wait for you.
Both "1" = on, running daily. "0" or a missing file = off.
What has it installed? (read-only)
sudo tail -n 20 /var/log/unattended-upgrades/unattended-upgrades.log2026-11-02 06:14:22,512 INFO Packages that will be upgraded: libssl3t64 openssl
2026-11-02 06:14:40,108 INFO All upgrades installed
Each run lists the packages it upgraded. No packages found that can be upgraded unattended = nothing new that day.
Turn it on (if it's off)
sudo dpkg-reconfigure-plowunattended-upgrades
A screen asks Automatically download and install stable updates? Choose Yes. This writes the 20auto-upgrades file shown above.
What it does NOT do
It doesn't reboot. Kernel fixes wait until you reboot. Check for the reboot notice (section 3, step 4) now and then.
It doesn't install non-security updates. Those are your routine in section 3.
WHEN YOU LOG INUbuntu's welcome text tells you how many updates are waiting, and shows *** System restart required *** when a reboot is pending. Worth a glance every time.
A hold keeps one package at its current version, even when you run apt upgrade. Useful when an update would break something and you need time to test it.
Task
Command
Safe?
Hold at current version
sudo apt-mark hold php8.3-fpm
CHANGES THINGS
List everything on hold
apt-mark showhold
READ-ONLY
Release the hold
sudo apt-mark unhold php8.3-fpm
CHANGES THINGS
What you'll see
php8.3-fpm set on hold. = done.
During apt upgrade, held packages appear under The following packages have been kept back and aren't upgraded.
⚠ DON'T FORGET ITA held package also misses its security fixes, including the automatic ones (section 4). Run apt-mark showhold now and then, and release holds once you've tested the update.
GOOD TO KNOW"Kept back" doesn't always mean a hold. It also appears for phased updates (section 3) and for updates that need a brand-new helper package. To take one of those anyway: sudo apt install PACKAGE.
Each Moodle version only runs on certain PHP versions. Ubuntu 24.04 comes with PHP 8.3 only, which suits Moodle 4.4 and newer. Older Moodle sites need an older PHP from an extra repository.
Which PHP each Moodle version needs
Moodle
PHP (lowest – highest)
On Ubuntu 24.04
3.9
7.2 – 7.4
Needs extra repo (7.4)
3.11, 4.0
7.3 – 8.0
Needs extra repo (8.0)
4.1 (LTS)
7.4 – 8.1
Needs extra repo (8.1)
4.2, 4.3
8.0 – 8.2
Needs extra repo (8.2)
4.4, 4.5 (LTS)
8.1 – 8.3
Built in (8.3)
5.0, 5.1
8.2 – 8.4
Built in (8.3)
5.2
8.3 – 8.4
Built in (8.3)
From Moodle's official PHP page (Nov 2026). Check it again before a big change: docs.moodle.org/en/PHP.
⚠ OLD PHP = NO SECURITY FIXESPHP 8.1 and older no longer get security fixes from the PHP project. Sites that need them can run, but they're the ones to move to a newer Moodle first.
Which PHP is on this server? (read-only)
php -vPHP 8.3.6 (cli) (built: …)
ls /etc/php/8.1 8.3
php -v shows the default version for typed commands (like Moodle's cron and admin/cli scripts).
ls /etc/php/ lists every version installed. More than one is normal.
Which version each website uses is set in Apache / PHP-FPM, not here. That's on the PHP-FPM sheet.
Install PHP 8.3 with Moodle's extensions (built in)
The first installs PHP itself (the FPM version, which runs your sites). The second adds Moodle's extensions. The {…} part is shorthand: the server expands it to php8.3-cliphp8.3-curl …, one package each. mysql is the extension Moodle uses to talk to your RDS database.
An older PHP from the extra repository
Older PHP versions for Ubuntu come from a well-known PPA (extra repository) run by Ondřej Surý, a long-time Debian PHP maintainer. It's used very widely, but it's run by him, not by Ubuntu.
1. Add the extra repository (once per server)
sudo add-apt-repository ppa:ondrej/php
Shows a description and asks you to press Enter. It refreshes the catalog on its own at the end.
2. Install the version you need, with Moodle's extensions
Example for Moodle 4.1. Change 8.1 in both commands to the version from the table. No Copy buttons on purpose.
3. Check it (read-only)
php8.1 -v
4. Change the default for typed commands (only if needed)
sudo update-alternatives--config php
Shows a numbered list of installed versions; type the number you want and press Enter. This only changes what php means when typed. It doesn't change any website.
AFTER ADDING THE PPAThe extra repository also offers newer builds of PHP 8.3 than Ubuntu's own. Your next apt upgrade may switch 8.3 to the PPA's version. That's normal; just expect PHP in the upgrade list.
Could not get lock /var/lib/dpkg/lock-frontend … held by process 1234 (unattended-upgr)
Another apt is running, usually the automatic updates. Wait a few minutes and try again. Never delete the lock files; that can break the package system.
dpkg was interrupted, you must manually run 'sudo dpkg --configure-a'
A previous run was cut off (lost connection, reboot). Run exactly what it says: sudo dpkg --configure-a. It finishes the job.
A half-finished install. Run sudo apt --fix-broken install, read the list it proposes, then answer.
E: Unable to locate package …
Typo, catalog out of date (sudo apt update), or it comes from a PPA you haven't added (section 6).
The following packages have been kept back
Not an error. A hold, a phased update, or one needing a new helper (section 5).
Failed to fetch … / Temporary failure resolving
The server can't reach the internet or the catalog site. Try again later; check the server's outbound network.
Release file … is not valid yet
The server's clock is wrong. Check with date.
No space left on device
The disk is full. Check with df -h, then free space with sudo apt clean (deletes downloaded installers) and sudo apt autoremove.
⚠ IF AN UPGRADE BREAKS A SITECheck history.log (section 7) to see exactly what changed. Then either hold that package (section 5) while you fix the cause, or restore the server's backup/snapshot. Avoid downgrading packages by hand on a live server.