How to Install PHP 8.4 on Debian 13, 12 and 11

Last updated Friday, May 22, 2026 1:13 pm Joshua James 7 min read 1 comment

Debian 13 (trixie) already ships PHP 8.4 in its default APT sources. Debian 12 (bookworm) and Debian 11 (bullseye) still need the Sury repository for the same branch. That split matters when you want to install PHP 8.4 on Debian for WordPress, Laravel, phpMyAdmin, or a custom application. PHP 8.4 adds property hooks, asymmetric visibility, and the updated HTML5 DOM API covered in the official PHP 8.4 release announcement.

On Debian 13, the working path stays inside the default APT sources. Debian 12 and Debian 11 need a manual DEB822 .sources entry for Sury instead of extrepo. Then you can choose the Apache or Nginx integration that matches your stack. PHP 8.4 remains in active support through December 2026 and receives security fixes through December 2028 according to the official PHP supported versions table.

Install PHP 8.4 on Debian

Debian 13 (trixie) ships PHP 8.4 in the default APT sources. Debian 12 (bookworm) defaults to PHP 8.2, and Debian 11 (bullseye) defaults to PHP 7.4, so those two releases need the Sury repository before the php8.4 packages appear. For the maintained default branch instead of a fixed PHP 8.4 branch, use the default PHP package on Debian guide.

Refresh APT and confirm your Debian release

Start with a fresh package index.

sudo apt update

Then confirm which Debian codename you are working with.

grep '^VERSION_CODENAME=' /etc/os-release
VERSION_CODENAME=bookworm

These commands use sudo for package management tasks that need root privileges. If your account does not have sudo access yet, follow the guide on how to add a user to sudoers on Debian.

The codename tells you which path to use next: trixie can install PHP 8.4 directly, while bookworm and bullseye need the Sury repository first.

Install PHP 8.4 from Debian 13 default APT sources

On Debian 13, check the candidate package first so you can confirm PHP 8.4 comes from Debian’s own repositories.

apt-cache policy php8.4-cli
php8.4-cli:
  Installed: (none)
  Candidate: 8.4.21-1~deb13u1
  Version table:
     8.4.21-1~deb13u1 500
        500 http://security.debian.org/debian-security trixie-security/main amd64 Packages
     8.4.16-1~deb13u1 500
        500 http://deb.debian.org/debian trixie/main amd64 Packages

Install the PHP 8.4 CLI package once the candidate looks correct. Avoid the generic php8.4 metapackage here because it can select an Apache module before you choose a web server path.

sudo apt install php8.4-cli

Verify the versioned CLI binary before you move on to Apache or Nginx integration.

php8.4 -r 'printf "%s.%s\n", PHP_MAJOR_VERSION, PHP_MINOR_VERSION;'
8.4

Add the Sury PHP repository on Debian 12 and Debian 11

Debian 12 and Debian 11 need the Sury repository because their default APT sources stop at older PHP branches. This workflow uses a direct key download into /usr/share/keyrings/ and a DEB822 .sources file, which matches the current Debian packaging rules better than the older extrepo path.

If you used an older extrepo-based Sury setup, remove /etc/apt/sources.list.d/extrepo_sury.sources and /var/lib/extrepo/keys/sury.asc before adding the manual php.sources file. APT rejects duplicate Sury entries when the Signed-By paths do not match.

Install the prerequisites and download the repository key. Most server and minimal Debian installs need these packages even when fuller desktop images already have them. The key download stays unprivileged first, then sudo install copies it into the root-owned keyring path with the right permissions. For details on the download flags, see the curl command in Linux guide.

sudo apt install -y ca-certificates curl
curl -fsSLo deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
sudo install -m 0644 deb.sury.org-php.gpg /usr/share/keyrings/deb.sury.org-php.gpg
rm -f deb.sury.org-php.gpg

Resolve your Debian codename in the current shell and keep using the same terminal for the next command.

CODENAME=$(. /etc/os-release && echo "$VERSION_CODENAME")
printf 'Using suite: %s\n' "$CODENAME"
Using suite: bookworm

Create the DEB822 source file next. The printf | sudo tee pattern is more reliable than a heredoc when readers copy the block from WordPress into a terminal.

printf '%s\n' \
    "Types: deb" \
    "URIs: https://packages.sury.org/php/" \
    "Suites: $CODENAME" \
    "Components: main" \
    "Signed-By: /usr/share/keyrings/deb.sury.org-php.gpg" | sudo tee /etc/apt/sources.list.d/php.sources >/dev/null

Refresh APT again after adding the Sury source.

sudo apt update

Then confirm that php8.4-cli resolves through the Sury source.

apt-cache policy php8.4-cli
php8.4-cli:
  Installed: (none)
  Candidate: 8.4.21-3+0~20260514.49+debian12~1.gbp45ccaf
  Version table:
     8.4.21-3+0~20260514.49+debian12~1.gbp45ccaf 500
        500 https://packages.sury.org/php bookworm/main amd64 Packages

Install the PHP 8.4 CLI package after the repository check passes. Web handlers come next so you can choose Apache mod_php, Apache with PHP-FPM, or Nginx with PHP-FPM deliberately.

sudo apt install php8.4-cli

Bookworm and bullseye use the same package names here. The only difference is the Sury suite name and the package revision string that apt-cache policy reports.

Review the APT transaction on systems that already have unversioned PHP packages such as php-fpm, php-curl, or php-mbstring. Enabling Sury can move those metapackages from Debian’s default branch to Sury’s PHP 8.4 branch.

Compare PHP 8.4 web server setups on Debian

Choose the web server integration that matches the system you are actually running.

MethodPackagesBest forTrade-off
Apache with mod_phpapache2, libapache2-mod-php8.4Simple local development or smaller sitesApache switches to the prefork MPM
Apache with PHP-FPMapache2, php8.4-fpmProduction Apache servers that need cleaner process separationRequires Apache proxy modules and the FPM config
Nginx with PHP-FPMnginx, php8.4-fpmProduction Nginx deployments and reverse-proxy stacksNginx needs a FastCGI block in the server configuration
  • Use Apache with mod_php when you want the shortest path to a working local stack.
  • Use Apache with PHP-FPM when you want Apache but still need separate PHP worker pools.
  • Use Nginx with PHP-FPM when the site already runs on Nginx or you plan to build a LEMP stack.

These three web server paths assume you already installed php8.4-cli from the release-specific step above.

Install PHP 8.4 with Apache mod_php on Debian

This path suits simpler Apache deployments and lab systems where the extra isolation from PHP-FPM is not necessary.

sudo apt install apache2 libapache2-mod-php8.4
sudo systemctl restart apache2

Installing libapache2-mod-php8.4 automatically enables the PHP module and switches Apache from mpm_event to mpm_prefork. The full apache2ctl path avoids Debian’s common default where /usr/sbin is outside an unprivileged SSH user’s PATH.

sudo /usr/sbin/apache2ctl -M 2>/dev/null | grep -E 'php[0-9]*_module'
php_module (shared)

Install PHP 8.4 with Apache and PHP-FPM on Debian

This setup keeps Apache in front while handing PHP requests to a separate FPM service.

sudo apt install apache2 php8.4-fpm
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.4-fpm
sudo systemctl enable php8.4-fpm --now
sudo systemctl restart apache2

If you previously tested libapache2-mod-php8.4 on the same host, disable it before you enable the FPM configuration with sudo a2dismod php8.4.

Check the service state and confirm that the PHP-FPM socket exists before you update any virtual host configuration.

systemctl is-active php8.4-fpm
stat -c '%A %U %G %n' /run/php/php8.4-fpm.sock
active
srw-rw---- www-data www-data /run/php/php8.4-fpm.sock

Install PHP 8.4 with Nginx and PHP-FPM on Debian

Nginx always needs PHP-FPM for PHP requests, so this path is the natural fit for a LEMP server.

sudo apt install nginx php8.4-fpm
sudo systemctl enable php8.4-fpm --now

Add the FastCGI block to the Nginx server block that should handle PHP files. For a complete virtual host workflow, use the dedicated guide to configure Nginx with PHP-FPM.

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

Test the Nginx syntax before you reload the service.

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

Reload Nginx once the syntax check passes.

sudo systemctl reload nginx

Verify PHP 8.4 on Debian

Run one final branch check after your chosen web server path is in place. The versioned php8.4 command proves the PHP 8.4 CLI is available even when the plain php command follows another alternatives target.

php8.4 -r 'printf "%s.%s\n", PHP_MAJOR_VERSION, PHP_MINOR_VERSION;'
8.4

From here, you can continue with Install Apache on Debian, Install Nginx on Debian, Install WordPress with Apache on Debian, or Install WordPress with Nginx on Debian if you are building a full application stack.

Install PHP 8.4 extensions on Debian

Most PHP applications need more than the base interpreter. The package set here covers common framework, CMS, database, caching, and image-processing workloads, and it also fixes the missing mbstring and DOM-related errors that often appear in PHPUnit or Composer checks. For image-processing-only work, the narrower PHP Imagick on Debian guide covers that extension in more detail.

sudo apt install php8.4-curl php8.4-gd php8.4-mbstring php8.4-mysql php8.4-xml php8.4-zip php8.4-intl php8.4-bcmath php8.4-imagick php8.4-redis php8.4-memcached php8.4-soap php8.4-apcu

There is no separate php8.4-json package. JSON support is built into PHP 8.x, while php8.4-xml provides dom, xmlreader, xmlwriter, and related XML modules.

Restart the PHP handler that matches your setup after you add new modules.

# Apache with mod_php
sudo systemctl restart apache2

# Apache or Nginx with PHP-FPM
sudo systemctl restart php8.4-fpm

Check the high-value modules before you hand the server to an application.

php8.4 -m | grep -E '^(apcu|bcmath|curl|gd|imagick|intl|mbstring|memcached|mysqli|redis|soap|xml|xmlreader|xmlwriter|zip)$'
apcu
bcmath
curl
gd
imagick
intl
mbstring
memcached
mysqli
redis
soap
xml
xmlreader
xmlwriter
zip

If you need dependency management after the runtime is ready, the next logical step is Install PHP Composer on Debian.

Update or remove PHP 8.4 on Debian

Update PHP 8.4 packages on Debian

Refresh package metadata before checking for PHP 8.4 updates.

sudo apt update

Build the upgrade list from installed PHP 8.4 packages so the CLI, web handler, and extensions update together without installing missing optional packages.

mapfile -t php84_packages < <(dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' 'php8.4*' 'libapache2-mod-php8.4' 2>/dev/null | awk '$1 == "ii" {print $2}')

if ((${#php84_packages[@]})); then
    printf '%s\n' "${php84_packages[@]}"
    sudo apt install --only-upgrade "${php84_packages[@]}"
else
    printf 'No installed PHP 8.4 packages found.\n'
fi

APT keeps Sury-managed PHP packages current only while the Sury source remains enabled on Debian 12 or Debian 11.

Verify the active PHP 8.4 CLI branch after the upgrade finishes.

php8.4 -r 'printf "%s.%s\n", PHP_MAJOR_VERSION, PHP_MINOR_VERSION;'
8.4

Remove PHP 8.4 packages on Debian

Purge the versioned packages first. The package list includes installed and residual-config PHP 8.4 packages, plus the Apache module package when it exists.

mapfile -t php84_packages < <(dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' 'php8.4*' 'libapache2-mod-php8.4' 2>/dev/null | awk '$1 ~ /^(ii|rc)/ {print $2}')

if ((${#php84_packages[@]})); then
    printf '%s\n' "${php84_packages[@]}"
    sudo apt purge "${php84_packages[@]}"
else
    printf 'No installed or residual PHP 8.4 packages found.\n'
fi

Review and remove orphaned dependencies separately so APT shows you the package list before anything else leaves the system.

sudo apt autoremove

Confirm that no installed or residual PHP 8.4 packages remain.

dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' 'php8.4*' 'libapache2-mod-php8.4' 2>/dev/null | grep -E '^(ii|rc)' || echo 'No installed or residual PHP 8.4 packages remain.'
No installed or residual PHP 8.4 packages remain.

Remove the Sury repository from Debian 12 and Debian 11

Only Debian 12 and Debian 11 need this cleanup step. Debian 13 keeps PHP 8.4 in the default repositories, so there is no third-party source file to remove. Keep the Sury source enabled if you still use another Sury-managed PHP branch or extension package.

sudo rm -f /etc/apt/sources.list.d/php.sources
sudo apt update

mapfile -t source_files < <(sudo find /etc/apt/sources.list /etc/apt/sources.list.d -type f 2>/dev/null)
remaining_refs=
if ((${#source_files[@]})); then
    remaining_refs=$(sudo grep -lF '/usr/share/keyrings/deb.sury.org-php.gpg' "${source_files[@]}" || true)
fi

if [ -z "$remaining_refs" ]; then
    sudo rm -f /usr/share/keyrings/deb.sury.org-php.gpg
else
    printf 'Sury keyring still referenced by:\n%s\n' "$remaining_refs"
fi

Verify that Sury no longer contributes a PHP 8.4 candidate.

apt-cache policy php8.4-cli | grep -F 'packages.sury.org' || echo 'No Sury PHP 8.4 candidate remains.'
No Sury PHP 8.4 candidate remains.

Check the plain php package afterward if you also want to confirm APT has fallen back to Debian’s default branch.

apt-cache policy php | sed -n '1,6p'
php:
  Installed: (none)
  Candidate: 2:7.4+76
  Version table:
     2:7.4+76 500
        500 http://deb.debian.org/debian bullseye/main amd64 Packages

On Debian 12, the same check falls back to the default 2:8.2+93 candidate from bookworm. On Debian 13, php8.4 stays available from Debian’s own repositories even after you purge the installed packages.

Troubleshoot PHP 8.4 on Debian

Resolve a Signed-By conflict from an older extrepo setup

If you previously enabled Sury with extrepo and then add the manual php.sources file from the Sury setup section, APT stops because both source files point to the same repository with different key paths.

E: Conflicting values set for option Signed-By regarding source https://packages.sury.org/php/ bullseye: /var/lib/extrepo/keys/sury.asc != /usr/share/keyrings/deb.sury.org-php.gpg
E: The list of sources could not be read.

Remove the old extrepo source and key, then refresh APT before you continue with the manual repository method.

sudo rm -f /etc/apt/sources.list.d/extrepo_sury.sources /var/lib/extrepo/keys/sury.asc
sudo apt update
Hit:1 http://security.debian.org/debian-security bullseye-security InRelease
Hit:2 http://deb.debian.org/debian bullseye InRelease
Hit:3 https://packages.sury.org/php bullseye InRelease
Reading package lists...

Fix the php8.4-fpm socket not found error on Debian

Nginx returns a 502 error when the PHP-FPM service is stopped or the socket path in the server block does not match the running FPM version.

systemctl is-active php8.4-fpm
stat -c '%A %U %G %n' /run/php/php8.4-fpm.sock
active
srw-rw---- www-data www-data /run/php/php8.4-fpm.sock

If the socket is missing or the service is inactive, start PHP-FPM again and retest the Nginx configuration.

sudo systemctl enable php8.4-fpm --now
sudo nginx -t
sudo systemctl reload nginx

Fix the PHPUnit mbstring or DOM extension error on Debian

PHPUnit commonly fails when the CLI environment is missing mbstring or the XML modules that provide DOM support.

phpunit requires the "dom", "json", "libxml", "mbstring", "tokenizer", "xml", "xmlwriter" extensions, but the "mbstring" extension is not available.

Install the missing modules first. The php8.4-xml package covers dom, xmlreader, and xmlwriter in one step.

sudo apt install php8.4-mbstring php8.4-xml
php8.4 -m | grep -E '^(dom|mbstring|xmlwriter)$'
dom
mbstring
xmlwriter

Fix Sury GPG key errors on Debian 12 and Debian 11

If apt update reports a missing public key, refresh the Sury keyring file and update APT again.

Err:1 https://packages.sury.org/php bookworm InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY B188E2B695BD4743

Download the key again, install it into the same keyring path, then refresh the repository metadata.

curl -fsSLo deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
sudo install -m 0644 deb.sury.org-php.gpg /usr/share/keyrings/deb.sury.org-php.gpg
rm -f deb.sury.org-php.gpg
sudo apt update

Confirm that APT can read the Sury package metadata again.

apt-cache policy php8.4-cli
php8.4-cli:
  Installed: (none)
  Candidate: 8.4.21-3+0~20260514.49+debian12~1.gbp45ccaf
  Version table:
     8.4.21-3+0~20260514.49+debian12~1.gbp45ccaf 500
        500 https://packages.sury.org/php bookworm/main amd64 Packages

Conclusion

PHP 8.4 is installed on Debian with the server integration that fits your stack, whether that means Apache with mod_php, Apache with PHP-FPM, or Nginx with PHP-FPM. From here, Install PHP Composer on Debian for application dependencies, then lock down the web tier with Secure Apache with Let’s Encrypt on Debian or Secure Nginx with Let’s Encrypt on Debian before the site goes live.

Follow LinuxCapable

Want more LinuxCapable guides in Google?

Add LinuxCapable as a preferred source so Google can show more of our fresh Linux tutorials in Top Stories and From your sources when relevant.

Add LinuxCapable as a preferred source on Google
Search LinuxCapable

Need another guide?

Search LinuxCapable for package installs, commands, troubleshooting, and follow-up guides related to what you just read.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffeeBuy me a coffee

1 thought on “How to Install PHP 8.4 on Debian 13, 12 and 11”

Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed in published comments:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<blockquote>quote</blockquote> quote block

Got a Question or Feedback?

We read and reply to every comment - let us know how we can help or improve this guide.

Let us know you are human: