How To

How To Install PHP 8.0 on Debian 13 / 12

PHP 8.0 lost upstream security support on 26 November 2023, and no current Debian release ships it. Debian 13 defaults to PHP 8.4 and Debian 12 to PHP 8.2, so to install PHP 8.0 on Debian today you need OndΕ™ej SurΓ½’s repository, which still builds the branch and keeps backporting security fixes into its 8.0.30 packages, the PHP2Shell fixes of 21 October 2026 included. Use it to keep an application you haven’t ported yet running, because that’s all an end-of-life branch is good for. For anything new, start on a supported branch with the current PHP guide for Debian, which installs Debian’s own PHP 8.4.

Original content from computingforgeeks.com - post 78399

Below we add the Sury repository, install PHP 8.0 and its extensions, and prove the installed build is patched against PHP2Shell. Every command in this guide was run on fresh Debian 13 and Debian 12 systems in October 2026 against Sury’s patched PHP 8.0 build, and the output blocks come from those runs.

The official release of PHP 8 is November 26, 2020. This major release of PHP came with lots of new features and performance improvements. It also brought breaking changes, which meant some code needed modifications to run on PHP 8. Some of the nice set of new features that came with PHP 8 were the JIT compiler, named arguments, union types, attributes, and many more. On Ubuntu, the PHP 8.0 guide for Ubuntu uses OndΕ™ej’s PPA instead.

Update the system

Before you start installation of PHP 8 on Debian update your system to the latest release. The Sury packages link against current Debian libraries, so a stale system is where dependency errors come from.

sudo apt update && sudo apt -y upgrade

Since there could be kernel updates consider system reboot after the upgrade.

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

If the file isn’t there, the line does nothing and you can carry on with the repository. A minimal install may never write that file, so compare the running kernel from uname -r with the newest installed kernel package from dpkg -l 'linux-image-*' | grep ^ii, and reboot if they differ.

Add the SurΓ½ APT repository

PHP 8 packages for Debian are available on the DEB.SURY.ORG repository, which publishes every PHP branch from 5.6 to 8.5 side by side. The old version of this guide installed software-properties-common and gnupg2 here. On a fresh Debian 13 system that line now stops with Error: Unable to locate package software-properties-common, because trixie dropped the package, and neither tool is needed any more. Install the three small tools the setup really uses:

sudo apt install -y lsb-release ca-certificates curl

Sury ships its signing key as a small Debian package. It drops the keyring into /usr/share/keyrings/ and keeps it current when the key rotates, so you never manage key files by hand:

curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb

Add the repository signed by that keyring, with the keyring path and file name from Sury’s own README. lsb_release -sc fills in your release codename, trixie or bookworm, so the same line serves both releases. Once it is in place, the next apt upgrade also moves Debian’s own php-common and any Debian PHP packages you already have to Sury’s builds.

echo "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list

Perform package index update to confirm the repository has been added:

sudo apt update

You should see two packages.sury.org lines, the release file and the package list. This is Debian 13, and Debian 12 shows bookworm in the same places. A signature error here means the keyring package did not install, so rerun the dpkg -i line before going further.

Hit:1 http://deb.debian.org/debian trixie InRelease
Hit:2 http://deb.debian.org/debian trixie-updates InRelease
Hit:3 http://deb.debian.org/debian-security trixie-security InRelease
Get:4 https://packages.sury.org/php trixie InRelease [6129 B]
Get:5 https://packages.sury.org/php trixie/main amd64 Packages [287 kB]
Fetched 293 kB in 0s (1251 kB/s)

Confirm that apt will take PHP 8.0 from Sury before you install anything. The version string keeps the 1: epoch and carries the 21 October 2026 snapshot date, which you’ll need for the PHP2Shell check later.

apt-cache policy php8.0

On Debian 13 the candidate reads like this, and Debian 12 shows the same release with debian12 in the suffix:

php8.0:
  Installed: (none)
  Candidate: 1:8.0.30-25+0~20261021.88+debian13~1.gbpabebea
  Version table:
     1:8.0.30-25+0~20261021.88+debian13~1.gbpabebea 500
        500 https://packages.sury.org/php trixie/main amd64 Packages

Older releases are a different story. Debian 10 (buster) has no Sury repository at all any more, so it gets no PHP 8.0 updates from anyone. Sury still publishes the same patched 8.0.30 build for Debian 11 (bullseye), but Debian 11 is out of support, and the free archive has no fix for Debian’s own PHP 7.4 there. Only Freexian’s paid ELTS covers bullseye, with php7.4 7.4.33-1+deb11u14 (ELA-1853-1). A patched PHP does not make the rest of a dead release safe, so move those servers up one release at a time, because Debian supports upgrades only from the previous release: start with the buster to bullseye upgrade, then 11 to 12 and 12 to 13.

Install PHP 8.0 on Debian

With the repository added you can begin the installation of PHP 8.0 on Debian Linux OS. On a fresh server the php8.0 package pulls in Apache with libapache2-mod-php8.0 and starts Apache straight away, so expect a web server on port 80 when it finishes:

sudo apt install -y php8.0

Debian 13’s apt prints the new summary format, with apache2 and the Apache module in the dependency list. Debian 12 installed 38 packages for the same command:

Installing:
  php8.0

Installing dependencies:
  adduser                  libgdbm6t64             perl
  apache2                  libgpm2                 perl-modules-5.40
  apache2-bin              libjansson4             php-common
  apache2-data             liblua5.4-0             php8.0-cli
  apache2-utils            libncursesw6            php8.0-common
  libapache2-mod-php8.0    libperl5.40             php8.0-opcache
  libapr1t64               libproc2-0              php8.0-readline
  libaprutil1-dbd-sqlite3  libsodium23             procps
  libaprutil1-ldap         libtext-charwidth-perl  psmisc
  libaprutil1t64           libtext-wrapi18n-perl   sensible-utils
  libargon2-1              libxml2                 ssl-cert
  libedit2                 media-types             ucf
  libgdbm-compat4t64       netbase

Summary:
  Upgrading: 0, Installing: 39, Removing: 0, Not Upgrading: 0
  Download size: 17.0 MB

Confirm the default PHP version on the server. If you run several branches side by side, php points at whichever one Debian’s alternatives system picked, so this also tells you what your scripts and cron jobs will use.

php -v

Debian 13 printed this, and Debian 12 the same release with a build time of 08:20:50:

PHP 8.0.30 (cli) (built: Oct 21 2026 08:21:48) ( 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

Every PHP 8.0 build has said 8.0.30 since 2023, the vulnerable ones and the patched ones alike, so the version line cannot tell you whether you are safe. The next check reads the package instead.

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, which php.net scored CVSS v4.0 9.2 in its 20 October pre-announcement. Upstream fixed both on 21 October 2026 in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.0 got no release because the branch is end of life, but Sury backported both fixes from 8.2.35 into 1:8.0.30-25 for trixie, bookworm and bullseye, so a server installed from this repository on or after 21 October is covered. The full write-up is in the PHP security advisory.

The changelog is the reliable check, because Sury names the CVEs in the entry that fixes them:

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

Both Debian 13 and Debian 12 printed this line. It sits in the 1:8.0.30-25 entry dated 21 October 2026, while the previous build, 1:8.0.30-24 from July 2026, has no such line, so empty output means your build is older than 1:8.0.30-25:

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

Minimal and container images often strip /usr/share/doc, so there is no changelog to read. This line compares the installed version with the fixed one and needs no documentation files. Keep the 1: epoch in it, and run it only where php8.0-common is installed, since a missing package falls through to a misleading VULNERABLE:

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

Both fresh installs answered with the good result.

patched

A fresh install from this guide can stop here and move on to the extensions. On an existing server that came back VULNERABLE, upgrade every PHP 8.0 package. The Apache module and the embed library start with lib, which the glob misses, so they are named explicitly, and apt skips any that aren’t installed:

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

The new files on disk do not help until the processes holding the old library restart. Sury’s archive only carries the current build, so we could not replay an upgrade from 1:8.0.30-24 and watch what the packages restart on their own. Restart the PHP services yourself either way. With PHP-FPM, restart the FPM service:

sudo systemctl restart php8.0-fpm

With mod_php, which is what the php8.0 package sets up, restart Apache. If both are installed, run both lines. Long-running PHP CLI workers, such as queue consumers under supervisor or in their own systemd unit, keep the old code in memory too, so restart those as well:

sudo systemctl restart apache2

Now prove the running service is newer than the package on disk. This prints the last time PHP 8.0 was installed or upgraded, rotated logs included:

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

Our Debian 13 system had only ever installed the patched build, so the line records that install. On an upgraded server it reads upgrade followed by the old and new versions:

2026-10-22 19:59:23 install php8.0-fpm:amd64 <none> 1:8.0.30-25+0~20261021.88+debian13~1.gbpabebea

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

systemctl show -p ActiveEnterTimestamp apache2

The timestamp has to be later than the dpkg line, as it is here. If it is earlier, the service is still running the old build, so restart it again:

ActiveEnterTimestamp=Thu 2026-10-22 19:59:41 UTC

To see which handler actually serves your PHP, and therefore which service the restart has to cover, put a two-line test page in Apache’s default document root:

echo '<?php echo PHP_VERSION, " ", PHP_SAPI, "\n";' | sudo tee /var/www/html/info.php

Request it through Apache.

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

Both systems answered with mod_php, which means apache2 is the service to restart. A site behind PHP-FPM answers fpm-fcgi instead:

8.0.30 apache2handler

Delete the page with sudo rm /var/www/html/info.php once you have read it, because it tells anyone who finds it which PHP build you run. For the full patch walkthrough across Debian’s own PHP packages as well, see patching PHP2Shell on Debian 13 and 12.

Install PHP 8.0 extensions

To install PHP 8 extensions on Debian use the following command syntax:

sudo apt install -y php8.0-<extension>

Replace <extension> with the actual extension name. Each extension is its own package, so you install only what your application needs, and the bundled extensions share the core’s 8.0.30 build. PECL extensions such as redis or imagick carry their own versions (6.3.0 and 3.8.1 on Debian 13 in October 2026). To see what the repository offers for PHP 8.0, list the package names and leave out the debug symbol packages.

apt-cache pkgnames php8.0- | grep -v dbgsym | sort | pr -4 -t -w 96

Sury carried 88 of them on Debian 13 in October 2026.

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

This example installs the modules most database-backed applications need, plus FPM.

sudo apt install -y php8.0-{mysql,cli,common,imap,ldap,xml,fpm,curl,mbstring,zip}

Debian 13 installed eight new extension packages plus their libraries. Debian 12 reported 14 newly installed packages for the same line:

Installing:
  php8.0-curl  php8.0-imap  php8.0-mbstring  php8.0-xml
  php8.0-fpm   php8.0-ldap  php8.0-mysql     php8.0-zip

Installing dependencies:
  libc-client2007e  libgpg-error-l10n  libonig5    libzip5
  libgcrypt20       libgpg-error0      libxslt1.1  mlock

Suggested packages:
  uw-mailutils  rng-tools  php-pear

Summary:
  Upgrading: 0, Installing: 16, Removing: 0, Not Upgrading: 0

The php8.0-fpm package starts its own service but prints NOTICE: Not enabling PHP 8.0 FPM by default. when Apache is present. Apache keeps answering through mod_php until you enable proxy_fcgi and the php8.0-fpm configuration, which is why the PHP2Shell restart above covers both services. Use the same installation format for all other PHP extensions available in the repository. To check loaded PHP modules use the command:

php -m

Each extension you installed shows up as a module name in that list, for example imap, ldap, mysqli and zip after the line above.

Recommended 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 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 QElectroTech on Ubuntu (Easy Guide for 20.04 & Later) Debian Install QElectroTech on Ubuntu (Easy Guide for 20.04 & Later)

9 thoughts on “How To Install PHP 8.0 on Debian 13 / 12”

  1. Thanks! I got helped.
    I got massage “apt-key is deprecated. Manage keyring files in trusted.gpg.d instead” in step2.
    So I also referred “https://packages.sury.org/php/README.txt”.

    Reply
  2. Doesn’t seem to work in Debian 9 (Stretch):

    $ sudo apt update
    Ign:1 http://ftp.de.debian.org/debian stretch InRelease
    Hit:2 http://ftp.de.debian.org/debian-security stretch/updates InRelease
    Ign:3 https://packages.sury.org/php stretch InRelease
    Hit:4 http://ftp.de.debian.org/debian stretch-updates InRelease
    Err:5 https://packages.sury.org/php stretch Release
    403 Forbidden
    Hit:6 http://ftp.de.debian.org/debian stretch-backports InRelease
    Hit:7 http://ftp.de.debian.org/debian stretch Release
    Reading package lists… Done
    E: The repository ‘https://packages.sury.org/php stretch Release’ does not have a Release file.
    N: Updating from such a repository can’t be done securely, and is therefore disabled by default.
    N: See apt-secure(8) manpage for repository creation and user configuration details.

    Reply

Leave a Comment

Press ESC to close