Dev

How To Install PHP 8.2 on Ubuntu 24.04 / 22.04

Ubuntu does not ship PHP 8.2 in its own archive. Ubuntu 24.04 comes with PHP 8.3 and Ubuntu 22.04 with PHP 8.1, so an application pinned to PHP 8.2 needs OndΕ™ej SurΓ½’s PPA, which builds every supported PHP branch. The branch added readonly classes and stand-alone null, false and true types (full list on PHP.Watch). Upstream security support for PHP 8.2 ends on 31 December 2026, so plan your move to a newer branch now.

Original content from computingforgeeks.com - post 132753

We add the PPA, install PHP 8.2 with its common modules, prove the build carries the PHP2Shell fix and hook it up to Nginx or Apache. Ubuntu 20.04 and 18.04 are no longer covered. In October 2026 we ran the install, both web server setups and the upgrade check on fresh Ubuntu 24.04 and 22.04 systems, and the output blocks come from those runs.

[ebook product=”2″ theme=”blue”]

Debian installation article: How To Install PHP 8.2 on Debian

Update Ubuntu System

Bring the server up to date before adding any repository, because the PPA builds link against current Ubuntu libraries and a stale system is where dependency errors come from. We also clear old packages and reboot if the upgrade pulled in a new kernel, so you start from a clean, known state.

sudo apt update && sudo apt -y upgrade

Remove packages nothing depends on any more, which keeps old kernels from filling /boot.

sudo apt autoremove

If the upgrade touched the kernel or core libraries, Ubuntu drops a flag file, so this line reboots only when that file exists.

[ -f /var/run/reboot-required ] && sudo reboot

Confirm which Ubuntu release you are on, because the PPA only builds for some of them.

cat /etc/os-release

Look at VERSION_CODENAME. It must read noble (24.04) or jammy (22.04) for the rest of this guide to work.

PRETTY_NAME="Ubuntu 24.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.5 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=noble
LOGO=ubuntu-logo

A 22.04 server shows jammy in the same field. Anything else, such as focal or resolute, means the PPA below will not give you PHP 8.2, so read the next section before you add it and decide whether the server needs a release upgrade first.

Add SurΓ½ PHP APT repository

To get PHP 8.2 packages installed on Ubuntu we’ll use OndΕ™ej SurΓ½’s PHP PPA, which provides the supported PHP branches for current Ubuntu LTS releases. Today that means Ubuntu 24.04 and 22.04 only, and the older releases are a dead end:

  • Ubuntu 20.04: the PPA’s focal index is empty, 0 packages
  • Ubuntu 18.04: the bionic index is empty as well
  • Ubuntu 26.04: no resolute build in the PPA at all

On 20.04 and 18.04 the only PHP left is Ubuntu’s own old branch, and its PHP2Shell fix ships through Ubuntu Pro, not the free archive, so a box on those releases without Pro has no free patched PHP. Upgrade the server to 24.04 instead of hunting for packages. On Ubuntu 26.04, use the native packages from the PHP 8.5 guide for Ubuntu 26.04, or SurΓ½’s packages.sury.org repository if an application really needs 8.2 there. Its setup steps are in the repository README.

Make sure add-apt-repository and the CA bundle are present before adding the repo.

sudo apt update
sudo apt install -y ca-certificates software-properties-common

Add the PPA. The -y flag skips the “Press ENTER” prompt, and add-apt-repository refreshes the package index on its own:

sudo add-apt-repository -y ppa:ondrej/php

On 22.04 it writes the source list and the signing key. The new description also says the PPA is being merged into packages.sury.org, with jammy and noble still served from here.

PPA publishes dbgsym, you may need to include 'main/debug' component
Repository: 'deb https://ppa.launchpadcontent.net/ondrej/php/ubuntu/ jammy main'
Description:
This repository is in process of being merged into https://packages.sury.org/php/;

For Ubuntu Resolute, https://packages.sury.org/php/ is the canonical way of getting PHP packages, for previous releases, I will provide a simple way how to migrate to the new repositories in upcoming weeks, you can still use this repository for Ubuntu Jammy and Ubuntu Noble.
More info: https://launchpad.net/~ondrej/+archive/ubuntu/php
Adding repository.
Adding deb entry to /etc/apt/sources.list.d/ondrej-ubuntu-php-jammy.list
Adding disabled deb-src entry to /etc/apt/sources.list.d/ondrej-ubuntu-php-jammy.list
Adding key to /etc/apt/trusted.gpg.d/ondrej-ubuntu-php.gpg with fingerprint B8DC7E53946656EFBCE4C1DD71DAEAAB4AD4CAB6

Confirm APT now sees PHP 8.2 and that the candidate comes from the PPA.

apt-cache policy php8.2

The candidate should be 8.2.35 or newer, served from ppa.launchpadcontent.net. “Unable to locate package” or an empty candidate means the PPA is not active for your release.

php8.2:
  Installed: (none)
  Candidate: 8.2.35-1+ubuntu24.04.1+deb.sury.org+1
  Version table:
     8.2.35-1+ubuntu24.04.1+deb.sury.org+1 500
        500 https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble/main amd64 Packages

On 22.04 you get the same release with ubuntu22.04.1 in the version string. The deb.sury.org suffix is how you tell a PPA build from an Ubuntu archive package later, which matters when you check for security fixes, because Ubuntu’s own PHP packages follow a different version scheme. On 22.04 the PPA also carries its own builds of libpcre2-8-0, libpcre3 and libxml2, so your next apt upgrade replaces those Ubuntu libraries with the PPA versions.

Install PHP 8.2 on Ubuntu

Once the PPA is added, use the apt command to install PHP 8.2. The php8.2 package pulls in Apache and libapache2-mod-php8.2 as well, which is fine for an Apache server. If you plan to run Nginx, run sudo apt install php8.2-cli in place of this line so Apache never lands on the server, then carry on with the version check and the modules. The Nginx section adds FPM later.

sudo apt install php8.2

Accept the package list when prompted. The exact count depends on what the server already has, so treat this 24.04 list as a guide:

The following additional packages will be installed:
  apache2 apache2-bin apache2-data apache2-utils libapache2-mod-php8.2
  libapr1t64 libaprutil1-dbd-sqlite3 libaprutil1-ldap libaprutil1t64 libbsd0
  libcurl4t64 libedit2 libgdbm-compat4t64 libgdbm6t64 libjansson4 liblua5.4-0
  libperl5.38t64 libsodium23 perl perl-modules-5.38 php-common php8.2-cli
  php8.2-common php8.2-opcache php8.2-readline psmisc ssl-cert
Suggested packages:
  apache2-doc apache2-suexec-pristine | apache2-suexec-custom www-browser ufw
  php-pear gdbm-l10n perl-doc libterm-readline-gnu-perl
  | libterm-readline-perl-perl make libtap-harness-archive-perl
The following NEW packages will be installed:
  apache2 apache2-bin apache2-data apache2-utils libapache2-mod-php8.2
  libapr1t64 libaprutil1-dbd-sqlite3 libaprutil1-ldap libaprutil1t64 libbsd0
  libcurl4t64 libedit2 libgdbm-compat4t64 libgdbm6t64 libjansson4 liblua5.4-0
  libperl5.38t64 libsodium23 perl perl-modules-5.38 php-common php8.2
  php8.2-cli php8.2-common php8.2-opcache php8.2-readline psmisc ssl-cert
0 upgraded, 28 newly installed, 0 to remove and 0 not upgraded.
Need to get 16.1 MB of archives.

Check which PHP version the command line now uses.

php -v

The first line names the PHP release and the build date.

PHP 8.2.35 (cli) (built: Oct 21 2026 14:30:30) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.35, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.35, Copyright (c), by Zend Technologies

Anything older than 8.2.35 here means the server still runs a build from before the October 2026 security release. The version line is a quick hint, but it does not prove what is fixed, so you should read the package changelog next.

Confirm the PHP2Shell fix (CVE-2026-109618 and CVE-2026-109619)

PHP2Shell is a pair of critical remote code execution bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619, both scored CVSS v4.0 9.2 and fixed upstream on 21 October 2026 in PHP 8.2.35 (and 8.5.12, 8.4.27, 8.3.36). The OndΕ™ej SurΓ½ PPA already ships 8.2.35 for both Ubuntu 24.04 and 22.04, so a fresh install from this guide is patched. Details are in the PHP security advisory.

The package changelog is the reliable check, because it names the CVEs the build fixes. Run it on any server that already had PHP 8.2 from this PPA:

zgrep -E 'CVE-2026-10961[89]' /usr/share/doc/php8.2-common/changelog.Debian.gz

A patched build prints the changelog line below, on 24.04 and 22.04 alike. No output means the installed package is older than the fixed 8.2.35 build.

   + (CVE-2026-109618, CVE-2026-109619): Avoid state corruption via

A fresh install from this guide can stop here and move on to the modules. On an existing server where the check prints nothing, upgrade every PHP 8.2 package. The Apache module and the embed library start with lib, so the glob misses them and they are named explicitly:

sudo apt update
sudo apt install --only-upgrade 'php8.2*' libapache2-mod-php8.2 libphp8.2-embed

APT skips anything in that list that is not installed, so the same line suits FPM and mod_php servers. On 22.04, needrestart can pop up a dialog offering to restart services. Whatever you pick there, restart the PHP handler yourself so no worker keeps running the old code. An Nginx server restarts FPM:

sudo systemctl restart php8.2-fpm

A mod_php server restarts Apache instead:

sudo systemctl restart apache2

If you installed the module set from this guide, php8.2-fpm is on the Apache server as well, so restart both:

sudo systemctl restart php8.2-fpm apache2

Long-running PHP CLI processes, such as queue workers kept alive by supervisor or a systemd unit, also hold the old code in memory. Restart each of them the same way:

sudo systemctl restart <worker>.service

Now prove the running service is newer than the package on disk. This prints the time of the last PHP 8.2 upgrade, including entries in rotated logs:

zgrep -h ' upgrade php8.2' /var/log/dpkg.log* | sort | tail -1

Compare it with the moment the service you restarted came up. Swap apache2 for php8.2-fpm on an FPM server:

systemctl show -p ActiveEnterTimestamp apache2

The timestamp has to be later than the dpkg line. Our Apache test server printed this right after the restart:

ActiveEnterTimestamp=Thu 2026-10-22 15:38:56 UTC

Rerun the zgrep afterwards and expect the CVE line. Then request a PHP page through the web server again, such as the test page from the Nginx or Apache section below. The PPA ships upstream 8.2.35, so the version the page reports comes from the restarted worker itself:

curl -s http://127.0.0.1/info.php

Our Apache test server answered with the patched release after the restart. An FPM site reports fpm-fcgi in the second field instead:

8.2.35 apache2handler

A server still on Ubuntu 20.04 or 18.04 cannot get there from this PPA, which is one more reason to move it to 24.04.

Install PHP 8.2 modules

PHP modules are libraries that add functionality to PHP, usually written in C and loaded as shared objects. Each one is its own package named php8.2- plus the module name, so the intl module installs like this:

sudo apt install -y php8.2-intl

Most web applications (WordPress, Laravel, Nextcloud) need a similar set, so install the commonly used modules in one go:

sudo apt install php8.2-{bcmath,fpm,xml,mysql,zip,intl,ldap,gd,cli,bz2,curl,mbstring,pgsql,opcache,soap,cgi}

List the modules PHP loads to confirm they all registered.

php -m

Every module you installed shows up, along with the ones compiled into PHP.

[PHP Modules]
bcmath
bz2
calendar
Core
ctype
curl
date
dom
exif
FFI
fileinfo
filter
ftp
gd
gettext
hash
iconv
intl
json
ldap
libxml
mbstring
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_pgsql
pgsql
Phar
posix
random
readline
Reflection
session
shmop
SimpleXML
soap
sockets
sodium
SPL
standard
sysvmsg
sysvsem
sysvshm
tokenizer
xml
xmlreader
xmlwriter
xsl
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache

If a module you installed is missing, the CLI is probably reading a different PHP version. Run php -v again, and if it shows another branch, point the default back with sudo update-alternatives --config php. Web requests are not affected by that switch, because FPM and mod_php load their own php.ini under /etc/php/8.2/.

Using PHP with Nginx or Apache

Pick one web server per host. Both paths below serve the same small test page, so you can see which PHP handler answered the request.

Hosting PHP application with Nginx web server

With Nginx, PHP code is executed by a separate process, PHP-FPM (FastCGI Process Manager). PHP-FPM is a daemon that listens for incoming PHP requests on a Unix socket and runs them in its own worker pool, while Nginx only forwards the request.

If you installed the php8.2 package earlier, Apache is already running on port 80, and the Nginx package will not start while Apache holds the port. Stop and disable Apache before installing Nginx. Skip this line if Apache was never installed:

sudo systemctl disable --now apache2

Install Nginx and the FPM package.

sudo apt install nginx php8.2-fpm

Create the document root for the site.

sudo mkdir -p /var/www/mysite

Then create a server block for the site in its own file, so the default site and future sites stay separate.

sudo vim /etc/nginx/sites-available/mysite

Paste the block below and change server_name to your domain. The fastcgi_pass line points at the PHP 8.2 FPM socket:

server {
    listen 80;
    server_name mysite.example.com;
    root /var/www/mysite;
    index index.php index.html;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }
}

Enable the site and validate the configuration.

sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
sudo nginx -t

Both lines must report success before you reload, otherwise the reload keeps the old configuration and the error sits in the output above.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Reload Nginx so it picks up the new site:

sudo systemctl reload nginx

Check that both services are up before testing a page:

systemctl is-active nginx php8.2-fpm

Both of our test servers printed two lines of active, which means Nginx and FPM are serving. Anything else, such as failed, points to journalctl -u nginx or journalctl -u php8.2-fpm for the reason:

active
active

Now add a test page that prints the PHP version and the handler that ran it:

sudo vim /var/www/mysite/index.php

Add these two lines.

<?php
echo PHP_VERSION, " ", PHP_SAPI, "\n";

Request it through Nginx. The Host header lets you test before DNS points at the server.

curl -s -H "Host: mysite.example.com" http://127.0.0.1/

A working setup answers with the version and fpm-fcgi. A 502 Bad Gateway means Nginx cannot reach the socket, so check that php8.2-fpm is running and that the socket path matches the config:

8.2.35 fpm-fcgi

Delete the test page once you have seen the result, since it tells anyone who asks which PHP release the server runs.

Hosting PHP application with Apache web server

Apache can run PHP inside its own worker processes through mod_php, so there is no separate daemon to manage. The PHP with Apache guide for Ubuntu and Debian goes further into virtual hosts and PHP-FPM under Apache.

Install the Apache web server and the Apache PHP module.

sudo apt install apache2 libapache2-mod-php8.2

Enable the mod_php module.

sudo a2enmod php8.2

The package already enabled it and switched Apache to the prefork MPM, which mod_php requires, so the command only confirms it:

Considering dependency mpm_prefork for php8.2:
Considering conflict mpm_event for mpm_prefork:
Considering conflict mpm_worker for mpm_prefork:
Module mpm_prefork already enabled
Considering conflict php5 for php8.2:
Module php8.2 already enabled

Restart Apache web server after the configuration.

sudo systemctl restart apache2

Create the same two-line test page in Apache’s default document root:

sudo vim /var/www/html/info.php

Paste the <?php and echo lines from the Nginx test, save, then request the page. This time Apache’s handler answers instead of FPM:

curl -s http://127.0.0.1/info.php

The response confirms mod_php is serving PHP 8.2.

8.2.35 apache2handler

If you get the raw PHP source back instead, mod_php is not loaded, so rerun sudo a2enmod php8.2 and restart Apache. Remove info.php when you are done with it, for the same reason as the Nginx test page.

Wrapping up

PHP 8.2 on Ubuntu 24.04 and 22.04 comes down to the OndΕ™ej SurΓ½ PPA, the php8.2-* packages and one handler, FPM for Nginx or mod_php for Apache. Treat it as a bridge rather than a destination: security support for the branch ends on 31 December 2026, and the PPA is already moving to packages.sury.org. If your code runs on a newer branch, the PHP 8.5 install on Ubuntu 24.04 follows the same pattern, and so does PHP 8.3 on Ubuntu. Back up the site before any PHP upgrade, and rerun the changelog check after every security release.

Recommended Web Development books to read:

Keep reading

Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) Ubuntu Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 Security UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP Php PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP Best Laptop Backpacks for Developers and Traveling Sysadmins Programming Best Laptop Backpacks for Developers and Traveling Sysadmins Install Zen Browser on Ubuntu 26.04 / 24.04 Ubuntu Install Zen Browser on Ubuntu 26.04 / 24.04 Configure /tmp on a Separate Partition or tmpfs on Linux Debian Configure /tmp on a Separate Partition or tmpfs on Linux

14 thoughts on “How To Install PHP 8.2 on Ubuntu 24.04 / 22.04”

  1. Thank you for this helpful tutorial. I am a beginner in linux/ubuntu. All works fine except one thing in GD.
    The code (see (1)) creates the file but I get an error on line 8 – though the image is created, but not shown – this message is shown as an image (see (2)) – on another provider-server it is executed as intended and shows the image. All modules are indicated as enabled in GD – jpg too . I cannot find the error πŸ™‚ . Could you give me a hint?
    (1)
    <?php
    $dest = imagecreatefromjpeg('Bilder/Background-Travel.jpg'); //Room01
    $src = imagecreatefromjpeg('BilderUpload/SunriseSunsetSonnenaufgang-Februar-2019.jpg');
    $src = imagecreatefromjpeg('BilderUpload/TravelNZRS9157_neu2.jpg');
    $src = imagecreatefromjpeg('BilderUpload/TravelPD_11_File_001.jpg');
    $srcScaled = imagescale( $src, 200, 150 );
    imagecopymerge($dest, $srcScaled, 135, 50, 0, 0, 200, 150, 100);
    header('Content-Type: image/jpg');
    imagejpeg($dest,'AAATest.jpg',100);
    echo "”;
    imagedestroy($dest);
    imagedestroy($src);
    ?>

    (2)

    Reply
  2. Hi,
    it had been a … header_remove php.ini on apache server … which made the difference in the error behaviour … πŸ™‚
    Best
    Axel

    Reply
  3. Hi. I’ve been using these instructions to install PHP8.2 on Ubuntu 18.04 (Bionic Beaver). When I attempt to install PHP it can’t find 8.2 in the repository for Bionic. Have this PHP vesrion been removed for Bionic? Thanks

    Reply

Leave a Comment

Press ESC to close