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
sudofor 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.sourcesand/var/lib/extrepo/keys/sury.ascbefore adding the manualphp.sourcesfile. APT rejects duplicate Sury entries when theSigned-Bypaths 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, orphp-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.
| Method | Packages | Best for | Trade-off |
|---|---|---|---|
| Apache with mod_php | apache2, libapache2-mod-php8.4 | Simple local development or smaller sites | Apache switches to the prefork MPM |
| Apache with PHP-FPM | apache2, php8.4-fpm | Production Apache servers that need cleaner process separation | Requires Apache proxy modules and the FPM config |
| Nginx with PHP-FPM | nginx, php8.4-fpm | Production Nginx deployments and reverse-proxy stacks | Nginx 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.4on the same host, disable it before you enable the FPM configuration withsudo 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-jsonpackage. JSON support is built into PHP 8.x, whilephp8.4-xmlprovidesdom,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+93candidate from bookworm. On Debian 13,php8.4stays 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.


Thank you