How To

How To Install PHP 8.0 on Ubuntu 24.04 / 22.04

PHP 8.0 has been end of life upstream since 26 November 2023, and php.net ships no new 8.0 releases. The patched builds you can still install on Ubuntu come from Ondřej Surý’s PPA, which backports security fixes and keeps the version at 8.0.30. Use it to keep a legacy application running on Ubuntu 24.04 or 22.04 while you port it, and put new servers on PHP 8.4 on Ubuntu or 8.5.

Original content from computingforgeeks.com - post 78181

You install PHP 8.0 and its extensions, then prove the build carries the PHP2Shell fix, which on this PPA means package 1:8.0.30-25 or later. Every command below except the reboot, the PHP-FPM reload and the extension name template was run as a sudo user on a fresh Ubuntu 24.04 test system in October 2026, including an upgrade from the pre-fix build, with the install and PHP2Shell checks repeated on Ubuntu 22.04.

Update the Ubuntu system

Bring all system packages up to date first. You want PHP to land on current libraries rather than on ones the next upgrade is about to replace.

sudo apt update && sudo apt -y upgrade

Reboot when the upgrade pulled in a new kernel or core libraries such as glibc, because running services keep the old copies in memory until they restart. Ubuntu flags that case with /var/run/reboot-required, so this line reboots only when the file exists and does nothing otherwise.

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

If it rebooted, log in again once the server is back and carry on with the repository.

Add the Ondřej Surý PPA

Ubuntu’s own archive carries PHP 8.3 on 24.04 and PHP 8.1 on 22.04, never 8.0, so PHP 8.0 comes from the Ondřej Surý PPA. Install the tools add-apt-repository needs, then add the PPA.

sudo apt install lsb-release ca-certificates apt-transport-https software-properties-common -y
sudo add-apt-repository ppa:ondrej/php

Press Enter at the prompt to add the repository. The command refreshes the package index on its own; we piped Enter in, so in our capture the refresh lines print ahead of the PPA description. That description says the PPA is being merged into packages.sury.org while Jammy and Noble can keep using it, so expect to switch this server to a new repository line later.

Get:1 https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble InRelease [24.3 kB]
Hit:2 http://security.ubuntu.com/ubuntu noble-security InRelease
Hit:3 http://archive.ubuntu.com/ubuntu noble InRelease
Get:4 https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble/main amd64 Packages [317 kB]
Get:5 http://security.ubuntu.com/ubuntu noble-security/main amd64 Components [59.1 kB]
Hit:6 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:7 http://archive.ubuntu.com/ubuntu noble-backports InRelease
Get:8 http://archive.ubuntu.com/ubuntu noble/main amd64 Components [665 kB]
Get:9 http://security.ubuntu.com/ubuntu noble-security/universe amd64 Components [97.3 kB]
Get:10 http://security.ubuntu.com/ubuntu noble-security/restricted amd64 Components [157 B]
Get:11 http://security.ubuntu.com/ubuntu noble-security/multiverse amd64 Components [158 B]
Get:12 http://archive.ubuntu.com/ubuntu noble/universe amd64 Components [5943 kB]
Get:13 http://archive.ubuntu.com/ubuntu noble/multiverse amd64 Components [41.9 kB]
Get:14 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Components [242 kB]
Get:15 http://archive.ubuntu.com/ubuntu noble-updates/universe amd64 Components [537 kB]
Get:16 http://archive.ubuntu.com/ubuntu noble-updates/restricted amd64 Components [159 B]
Get:17 http://archive.ubuntu.com/ubuntu noble-updates/multiverse amd64 Components [887 B]
Get:18 http://archive.ubuntu.com/ubuntu noble-backports/main amd64 Components [6348 B]
Get:19 http://archive.ubuntu.com/ubuntu noble-backports/universe amd64 Components [13.6 kB]
Get:20 http://archive.ubuntu.com/ubuntu noble-backports/restricted amd64 Components [160 B]
Get:21 http://archive.ubuntu.com/ubuntu noble-backports/multiverse amd64 Components [161 B]
Fetched 7948 kB in 3s (2914 kB/s)
Reading package lists...
PPA publishes dbgsym, you may need to include 'main/debug' component
Repository: 'Types: deb
URIs: https://ppa.launchpadcontent.net/ondrej/php/ubuntu/
Suites: noble
Components: 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.

Before installing, confirm which PHP 8.0 build apt will pick, because that version decides whether you are patched against PHP2Shell.

apt-cache policy php8.0-common

The candidate on 24.04 is 1:8.0.30-25 with an Ubuntu suffix, and 22.04 gets the same build with ubuntu22.04.1 in the suffix. The PPA keeps only its newest build, so a single line is normal.

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

Ubuntu 20.04 and 26.04 are outside this guide. The PPA’s focal index is empty, so 20.04 can no longer get PHP 8.0 from it at all, and the only PHP2Shell fix for Ubuntu’s own php7.4 there ships through Ubuntu Pro. The PPA has no resolute build either, and Ubuntu 26.04 carries PHP 8.5 in its own archive, so a new 26.04 server follows the PHP 8.5 setup on Ubuntu 26.04 instead.

Install PHP 8.0 on Ubuntu

The php8.0 metapackage installs the CLI and the Apache module, and it pulls in Apache itself. Apache is enabled and started on port 80 straight away, serving PHP through mod_php, so if you planned Nginx on this host, stop and disable Apache before Nginx needs the port. Install the metapackage.

sudo apt install php8.0

Hit the y key to start installation. On Ubuntu 24.04 the list shows Apache and libapache2-mod-php8.0 coming along with the PHP packages.

The following additional packages will be installed:
  apache2 apache2-bin apache2-data apache2-utils libapache2-mod-php8.0
  libapr1t64 libaprutil1-dbd-sqlite3 libaprutil1-ldap libaprutil1t64 libbsd0
  libedit2 libgdbm-compat4t64 libgdbm6t64 libjansson4 liblua5.4-0
  libperl5.38t64 libsodium23 perl perl-modules-5.38 php-common php8.0-cli
  php8.0-common php8.0-opcache php8.0-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.0
  libapr1t64 libaprutil1-dbd-sqlite3 libaprutil1-ldap libaprutil1t64 libbsd0
  libedit2 libgdbm-compat4t64 libgdbm6t64 libjansson4 liblua5.4-0
  libperl5.38t64 libsodium23 perl perl-modules-5.38 php-common php8.0
  php8.0-cli php8.0-common php8.0-opcache php8.0-readline psmisc ssl-cert
0 upgraded, 27 newly installed, 0 to remove and 0 not upgraded.
Need to get 15.3 MB of archives.
After this operation, 80.0 MB of additional disk space will be used.
Do you want to continue? [Y/n] y

Confirm the PHP version on the server. You will see why this number alone isn’t enough in a moment.

php -v

The CLI reports 8.0.30, and it will keep reporting 8.0.30 for as long as the PPA ships 8.0, because every fix since then is a backport inside the same upstream version.

PHP 8.0.30 (cli) (built: Oct 21 2026 14:25:38) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.30, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.30, Copyright (c), by Zend Technologies

So php -v can’t tell you whether you are patched, and the build date proves nothing on its own either. The package checks in the next section can.

Check PHP 8.0 for PHP2Shell (CVE-2026-109618, CVE-2026-109619)

PHP2Shell is a pair of critical remote code execution bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619, scored CVSS v4.0 9.2 in php.net’s 20 October pre-announcement. PHP fixed them on 21 October 2026 in 8.5.12, 8.4.27, 8.3.36 and 8.2.35 and released nothing for 8.0, only minimal source backports for 7.4, 8.0 and 8.1 aimed at people who build PHP themselves. The PPA backported the fix from 8.2.35 into 1:8.0.30-25, as its changelog says, for both Ubuntu 24.04 and 22.04, so a fresh install from this guide is already patched. The PHP security advisory has the details.

The package changelog names the CVEs a build fixes, which makes it the reliable check on any server with PHP 8.0 from the PPA. You can run it before or after an upgrade.

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

A patched build prints this line. No output means the installed package is older than 1:8.0.30-25.

   + [CVE-2026-109618, CVE-2026-109619]: Avoid state corruption via

Minimized Ubuntu images strip /usr/share/doc, and then there is no changelog to read. This version comparison works without it. Keep the 1: epoch in the threshold, since dpkg compares it first and you would get a false result without it.

dpkg --compare-versions "$(dpkg-query -W -f='${Version}' php8.0-common)" ge 1:8.0.30-25 && echo patched || echo VULNERABLE

It printed VULNERABLE on our test server while the previous PPA build, 1:8.0.30-24, was installed, and this after the upgrade.

patched

A fresh install can stop here and move on to the extensions. On an existing server where either check fails, upgrade every PHP 8.0 package. The Apache module and the embed library start with lib, so the glob misses them and they’re named explicitly. APT skips any name that isn’t installed.

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

When we ran the upgrade, the packages restarted Apache and PHP-FPM on their own. Restart them yourself anyway so no worker keeps the old code in memory. A mod_php server restarts Apache, and a server that also has php8.0-fpm (the extensions step installs it) restarts both:

sudo systemctl restart apache2 php8.0-fpm

Drop php8.0-fpm from that line if it is not installed, or drop apache2 on an Nginx server. Long-running PHP CLI processes, such as queue workers kept alive by supervisor or a systemd unit, hold the old code too, so restart those as well. Next, find when the PHP 8.0 packages were last upgraded, including entries in rotated logs.

zgrep -hE ' (install|upgrade) php8.0-(common|fpm):' /var/log/dpkg.log* | sort | tail -1

Our test server shows the jump from the pre-fix build to the fixed one. Your line will carry your own date and versions.

2026-10-22 19:56:16 upgrade php8.0-fpm:amd64 1:8.0.30-24+ubuntu24.04.1+deb.sury.org+1 1:8.0.30-25+ubuntu24.04.1+deb.sury.org+1

Compare that with the moment each restarted service came up, because a service that started before the upgrade is still running the old code, whatever the package database says.

systemctl show -p ActiveEnterTimestamp apache2 php8.0-fpm

Both timestamps must be later than the dpkg line, and here they are. If yours are earlier, you skipped the restart.

ActiveEnterTimestamp=Thu 2026-10-22 19:56:44 UTC

ActiveEnterTimestamp=Thu 2026-10-22 19:56:45 UTC

Don’t rely on a PHP_VERSION test page for this. Like Ubuntu 24.04’s own php8.3, the PPA build reports a bare 8.0.30 through Apache before and after the fix, so a test page confirms which SAPI answers but can’t prove which code it runs. The package version plus a service start time later than the upgrade is the proof.

Install PHP 8.0 extensions

Every PHP 8.0 extension is a separate package named php8.0- followed by the extension. The general form you type is below.

sudo apt install php8.0-<extension>

List the extension packages the PPA actually offers before you build an install line, because names differ between the PPA and Ubuntu’s archive.

apt-cache pkgnames php8.0- | sort | paste - - - - -

On Ubuntu 24.04 the PPA carries these, and you pick from this list.

php8.0-amqp	php8.0-apcu	php8.0-ast	php8.0-bcmath	php8.0-bz2
php8.0-cgi	php8.0-cli	php8.0-common	php8.0-curl	php8.0-dba
php8.0-decimal	php8.0-dev	php8.0-dio	php8.0-ds	php8.0-enchant
php8.0-excimer	php8.0-fpm	php8.0-gd	php8.0-gearman	php8.0-gmagick
php8.0-gmp	php8.0-gnupg	php8.0-grpc	php8.0-http	php8.0-igbinary
php8.0-imagick	php8.0-imap	php8.0-inotify	php8.0-interbase	php8.0-intl
php8.0-ldap	php8.0-libvirt-php	php8.0-litespeed	php8.0-lz4	php8.0-mailparse
php8.0-maxminddb	php8.0-mbstring	php8.0-mcrypt	php8.0-memcache	php8.0-memcached
php8.0-mongodb	php8.0-msgpack	php8.0-mysql	php8.0-oauth	php8.0-odbc
php8.0-opcache	php8.0-opentelemetry	php8.0-pcov	php8.0-pgsql	php8.0-phalcon
php8.0-phalcon5	php8.0-phpdbg	php8.0-pinba	php8.0-pq	php8.0-protobuf
php8.0-ps	php8.0-pspell	php8.0-psr	php8.0-raphf	php8.0-rdkafka
php8.0-readline	php8.0-redis	php8.0-rrd	php8.0-smbclient	php8.0-snmp
php8.0-soap	php8.0-solr	php8.0-sqlite3	php8.0-ssh2	php8.0-stomp
php8.0-swoole	php8.0-sybase	php8.0-tideways	php8.0-tidy	php8.0-uopz
php8.0-uploadprogress	php8.0-uuid	php8.0-vips	php8.0-xdebug	php8.0-xhprof
php8.0-xlswriter	php8.0-xml	php8.0-xmlrpc	php8.0-xsl	php8.0-yac
php8.0-yaml	php8.0-zip	php8.0-zmq	php8.0-zstd

Bash expands the braces below into nine package names, including PHP-FPM, which Nginx needs. Trim the list to what your application asks for, because every extra module is code loaded into each PHP worker.

sudo apt install php8.0-{cli,common,fpm,imap,redis,snmp,xml,zip,mbstring}

The FPM package prints a notice that it isn’t enabling itself in Apache. That is expected: Apache keeps serving PHP through mod_php, and PHP-FPM runs alongside it until you point a web server at its socket. If you want to list all PHP 8.0 loaded modules, use the command below.

php -m

Nginx has no PHP module, so with Nginx every PHP request goes to PHP-FPM, and the service has to be running before the site works. Check it now, since a failed start only shows up later as a 502 from Nginx and points you at the wrong component.

systemctl status php*-fpm.service

The package enables and starts the service on install, so you should see active (running).

● php8.0-fpm.service - The PHP 8.0 FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php8.0-fpm.service; enabled; preset: enabled)
     Active: active (running) since Thu 2026-10-22 19:55:01 UTC; 5s ago
       Docs: man:php-fpm8.0(8)
    Process: 13580 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/8.0/fpm/pool.d/www.conf 80 (code=exited, status=0/SUCCESS)
   Main PID: 13577 (php-fpm8.0)
     Status: "Ready to handle connections"
      Tasks: 3 (limit: 1204)
     Memory: 8.8M (peak: 9.9M)
        CPU: 91ms

Same format is used to install other extensions. Reload the service with sudo systemctl reload php8.0-fpm after any change under /etc/php/8.0/fpm/, so the workers pick it up.

Reference:

If 8.0 is only a stopgap for one application, the PHP 8.2 guide for 24.04 and 22.04 is the smallest jump, though 8.2 itself reaches end of life on 31 December 2026, and the PHP 8.5 install with Nginx and PHP-FPM on 24.04 is where new work should land.

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 Ubuntu 26.04 vs 24.04 LTS: Should You Upgrade Now? Ubuntu Ubuntu 26.04 vs 24.04 LTS: Should You Upgrade Now? Upgrade a Single Package on Ubuntu / Debian with apt Debian Upgrade a Single Package on Ubuntu / Debian with apt APT Cheat Sheet: apt and apt-get Commands for Ubuntu/Debian Cheat Sheets APT Cheat Sheet: apt and apt-get Commands for Ubuntu/Debian Install Lightworks Video Editor on Ubuntu / Linux Mint / Debian Debian Install Lightworks Video Editor on Ubuntu / Linux Mint / Debian

4 thoughts on “How To Install PHP 8.0 on Ubuntu 24.04 / 22.04”

  1. Ondřej Surý PPA repository no longer works on ubuntu 22.04 ?

    ServerNotFoundError: Unable to find the server at api.launchpad.net

    Reply

Leave a Comment

Press ESC to close