This guide updates PHP on a server with Ubuntu or Debian. It works for PHP from the distribution itself and for PHP from Ondřej Surý's repositories (the ppa:ondrej/php PPA on Ubuntu and packages.sury.org on Debian), which many guides, including the Pterodactyl one, use to get a newer PHP.
Updating within a branch (for example 8.3.30 to 8.3.36) brings bug and security fixes without new features, and is how you get security fixes. Moving to a new branch (8.3 to 8.4) is a bigger change: see the last section.
Find out where your PHP comes from#
apt policy php8.3-fpm
Replace 8.3 with your branch. Under Version table, the line with *** is the installed version, with the repository it came from below it:
ppa.launchpadcontent.net/ondrej/php(orppa.launchpad.net/ondrej/php): the PPA on Ubuntu;packages.sury.org/php: Ondřej Surý's repository;archive.ubuntu.com,security.ubuntu.com,deb.debian.orgorsecurity.debian.org: the distribution itself.
A distribution keeps PHP on one branch for the life of the release and adds security fixes to it, often under its own version number. The repositories of Ondřej Surý follow the PHP project's releases and offer several branches side by side.
Add Ondřej Surý's repository (only if you want it)#
Skip this if your PHP already comes from it, or if you are happy with the distribution's PHP.
On Ubuntu 22.04 or 24.04, add the PPA:
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
On Debian, and on Ubuntu 26.04 (for which the maintainer points to packages.sury.org instead of the PPA), add packages.sury.org:
sudo apt-get update
sudo apt-get -y install lsb-release ca-certificates curl
sudo curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
sudo apt-get update
These are the commands from the repository's own instructions (packages.sury.org/php/README.txt).
Update all installed PHP packages#
-
Refresh the package lists:
sudo apt update -
See which PHP packages have an update:
apt list --upgradable 2>/dev/null | grep -i php -
Update every installed PHP package, and nothing else:
sudo apt install --only-upgrade $(dpkg-query -W -f='${db:Status-Abbrev} ${Package}\n' 'php*' | awk '$1=="ii" {print $2}')This lists the installed packages whose name starts with
phpand upgrades them. Extensions such asphp8.3-mysqlorphp8.3-redisare included, so the extensions and PHP itself stay on the same version.You can also run
sudo apt upgrade, which updates PHP together with everything else on the server. -
Restart PHP-FPM for every branch you have. To see which ones run:
systemctl list-units --type=service 'php*-fpm*'Then restart each one, for example:
sudo systemctl restart php8.3-fpm -
If Apache runs PHP itself (mod_php, package
libapache2-mod-php8.3), restart Apache:sudo systemctl restart apache2
Check the version of the command line and PHP-FPM#
The command line (php) and PHP-FPM, which serves your websites, are separate programs. Check both.
-
The command line:
php -v -
PHP-FPM, for each branch:
/usr/sbin/php-fpm8.3 -v -
The installed packages:
dpkg -l 'php*' | grep '^ii'All packages of one branch should have the same version.
-
That PHP-FPM runs since after the update:
systemctl status php8.3-fpmLook at the time on the Active line.
On the distribution's own packages, the number after PHP in php -v can be lower than the latest release of the PHP project while the package still has the security fixes. Compare the full package version from step 3 with your distribution's security tracker (ubuntu.com/security or security-tracker.debian.org).
Several PHP versions side by side#
With Ondřej Surý's repositories you can install several branches at once. Each branch has its own packages (php8.2-*, php8.3-*), its own settings in /etc/php/<branch>/ and its own PHP-FPM service.
-
Which version the command line uses: choose it with
sudo update-alternatives --config php -
Which version a website uses: that is set in the web server. For NGINX it is the socket in the site's
fastcgi_passline, for exampleunix:/run/php/php8.3-fpm.sock. -
Updating: the command in step 3 above updates every branch at once. Restart the PHP-FPM service of every branch afterwards.
Move to a new PHP branch#
-
Check that your software supports the new branch. For example, Pterodactyl Panel 1.x lists only PHP 8.2 and 8.3.
-
List the extensions you use now:
dpkg -l 'php8.2*' | grep '^ii' -
Install the same packages for the new branch, for example:
sudo apt install php8.3-fpm php8.3-cli php8.3-mysql php8.3-mbstring php8.3-xml php8.3-curl php8.3-zip php8.3-gd php8.3-bcmath -
Copy any settings you changed in
/etc/php/8.2/fpm/(php.ini, pool files) to/etc/php/8.3/fpm/. Do not copy whole files blindly: compare them. -
Point the website at the new socket (for NGINX,
php8.3-fpm.sockinfastcgi_pass), test the configuration and reload:sudo nginx -t && sudo systemctl reload nginx -
Check the site. Keep the old branch installed until everything works; then you can stop it with
sudo systemctl disable --now php8.2-fpm.
To keep PHP patched without thinking about it, see automatic security updates on Ubuntu and Debian.