How to Install PHP 8.4 and 8.5 on Debian 13 and 12

Quick Summary
- Debian 13 ships PHP 8.4 and Debian 12 ships PHP 8.2: install phpX.Y-fpm or libapache2-mod-phpX.Y plus extension packages such as phpX.Y-mysql with apt.
- For another version, such as PHP 8.5, add the Sury repository with its keyring package and install versioned packages like php8.5-fpm, not the unversioned php-* ones.
- Point Nginx or Apache at /run/php/phpX.Y-fpm.sock (or enable mod_php), switch the command-line version with update-alternatives, then purge the old phpX.Y-common.
To install PHP on Debian, start with the version your release ships: PHP 8.4 on Debian 13 (trixie) and PHP 8.2 on Debian 12 (bookworm). It installs with apt and gets security updates from Debian along with the rest of the system. If you need a different version, for example PHP 8.4 on Debian 12 or PHP 8.5 on Debian 13, add Ondřej Surý’s repository at packages.sury.org and install the versioned packages from there. The versions and dates below are current as of September 2026.
Which PHP and Debian versions are current
These are the PHP branches php.net supports, from its supported versions page:
- PHP 8.5: active support until 31 December 2027, security fixes until 31 December 2029.
- PHP 8.4: active support until 31 December 2026, security fixes until 31 December 2028.
- PHP 8.3: security fixes only, until 31 December 2027.
- PHP 8.2: security fixes only, until 31 December 2026.
PHP 8.1 and older no longer get fixes from php.net. WordPress recommends PHP 8.3 or greater.
Debian 13 has been the stable release since 9 August 2025 and ships PHP 8.4. Debian 12 ships PHP 8.2 and moved to Debian LTS on 11 June 2026, which supports it until 30 June 2028. Debian 11 (PHP 7.4) left LTS on 31 August 2026, so on that server the fix is a Debian upgrade, not just a PHP upgrade.
Step 1: check your Debian release and current PHP
cat /etc/os-release
php -v
apt list --installed 'php*'The VERSION line shows the release, for example 13 (trixie) or 12 (bookworm). php -v prints the command-line PHP version, or “command not found” if PHP isn’t installed. The last command lists the PHP packages already on the server with their versions, so you know which extensions to install again after a version change.
Step 2: install the PHP version Debian ships
This is the simplest option, and Debian keeps it patched: the security team on Debian 13, the LTS team on Debian 12. First choose how your web server runs PHP:
php8.4-fpm: PHP-FPM, a separate service. Nginx needs it, and Apache can use it too.libapache2-mod-php8.4: the Apache module (mod_php), which runs PHP inside Apache.
Both install the command-line PHP (php8.4-cli) as well. For example, PHP-FPM on Debian 13:
sudo apt update
sudo apt install php8.4-fpmOn Debian 12, write 8.2 instead of 8.4 in every package name, here and in the steps below. Don’t install only the php8.4 package on an Nginx server: it needs the Apache module, PHP-FPM or CGI, and when none is installed apt picks the Apache module, which brings Apache with it.
Step 3: add the extensions WordPress needs
The WordPress hosting handbook lists mysqli as required and recommends curl, dom, exif, fileinfo, imagick, intl, mbstring, xml and zip, among others. On Debian they come in these packages:
sudo apt install php8.4-mysql php8.4-curl php8.4-gd php8.4-intl php8.4-mbstring php8.4-xml php8.4-zip php8.4-imagickphp8.4-mysql provides mysqli, php8.4-xml provides DOM, SimpleXML and XML, and GD is the image editor WordPress falls back to when Imagick is missing. Exif and fileinfo are in php8.4-common, which is already installed, and OpenSSL is built in. Each extension package enables itself for PHP-FPM, Apache and the command line, and restarts PHP-FPM or Apache so the extension loads.
Step 4: install another PHP version from the Sury repository
Use this when you need a version your Debian release doesn’t ship, such as PHP 8.3 or 8.4 on Debian 12, or PHP 8.5 on Debian 13. The repository is run by Ondřej Surý, who also maintains Debian’s own PHP packages. It supports Debian’s stable, oldstable and LTS releases, but it is a third-party repository and its FAQ makes no guarantees.
These commands are the setup steps from the repository’s own README:
sudo apt-get update
sudo apt-get -y install lsb-release ca-certificates curl
sudo curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
sudo apt-get updateThe keyring package installs the repository’s signing key, signed-by tells apt which key signs this repository, and $(lsb_release -sc) fills in your release’s codename. Older guides download apt.gpg into /etc/apt/trusted.gpg.d/ instead; the keyring package is the current method.
Then install the version you want, always with versioned package names:
sudo apt install php8.5-fpm php8.5-mysql php8.5-curl php8.5-gd php8.5-intl php8.5-mbstring php8.5-xml php8.5-zip php8.5-imagickVersioned names matter here. With the repository added, the unversioned packages (php, php-fpm, php-mysql and so on) follow the repository’s default version instead of Debian’s: on Debian 12, if you use them, the next upgrade moves you from PHP 8.2 to 8.4. From now on apt also updates the PHP packages you already have, and some libraries they use, from this repository.
Step 5: connect PHP to your web server
Nginx with PHP-FPM
In your site’s server block (on Debian, a file in /etc/nginx/sites-available/), add index.php and pass PHP files to the PHP-FPM socket:
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}The PHP block is the one in Debian’s default Nginx site, where it ships commented out with an older socket path. The try_files line comes from WordPress’s Nginx guide and makes pretty permalinks work. Each PHP version has its own socket, /run/php/phpX.Y-fpm.sock, so the path decides which version the site runs. Test the configuration and reload Nginx:
sudo nginx -t
sudo systemctl reload nginxApache with PHP-FPM
When Apache is installed, the php8.4-fpm package prints the commands that enable it:
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.4-fpm
sudo systemctl restart apache2The php8.4-fpm configuration sends .php files to /run/php/php8.4-fpm.sock, but only while mod_php isn’t loaded. If a mod_php module is enabled, turn it off first, for example with sudo a2dismod php8.4.
Apache with mod_php
sudo apt install libapache2-mod-php8.4The package enables the module itself and switches Apache to the prefork MPM, which mod_php needs. It doesn’t enable itself when another PHP version’s module is already on, so switch versions by hand:
sudo a2dismod php8.2
sudo a2enmod php8.4
sudo systemctl restart apache2Step 6: switch the command-line PHP version
With several versions installed, the php command points to the highest one by default. The first command below lets you pick another from a list; the second sets it directly:
sudo update-alternatives --config php
sudo update-alternatives --set php /usr/bin/php8.4This only changes the command line: cron jobs and other scripts you run with php. The web server uses the version you set up in step 5. You can also call a version by name, for example php8.4 -v.
Step 7: check the result
php -v
php -m
php --ini
systemctl status php8.4-fpmphp -v shows the version, php -m lists the loaded extensions (look for mysqli, curl, intl, mbstring and imagick), and php --ini shows which php.ini the command line reads. The last command checks that the PHP-FPM service is running. The command line and the web server read separate files, /etc/php/8.4/cli/php.ini and /etc/php/8.4/fpm/php.ini (or apache2/php.ini with mod_php); editing php.ini over SSH shows how to change them. To see the version your site runs, open Tools > Site Health > Info in WordPress and look under Server.
Upgrade to a newer PHP version and remove the old one
Patch releases of the version you run arrive with your normal sudo apt update and sudo apt upgrade. Moving to a new minor version, say from 8.2 to 8.4, is a separate install:
- Check that your theme and plugins support the new version, then install it with the same extensions.
apt list --installed 'php8.2*'shows what you have now. - Copy any settings you changed in
/etc/php/8.2/, such as php.ini values or extra PHP-FPM pools infpm/pool.d/, to the same places under/etc/php/8.4/. - Point the web server at the new version: change the socket path to
php8.4-fpm.sockin Nginx; runsudo a2disconf php8.2-fpmandsudo a2enconf php8.4-fpmfor Apache with PHP-FPM; or swap the modules as shown above for mod_php. Then reload or restart the web server. - Test the site, and switch the command-line version with
update-alternativesif it doesn’t point to the new version already.
When everything works, remove the old version:
sudo apt-get --purge remove php8.2-common
sudo apt autoremoveRemoving php8.2-common also removes every PHP 8.2 package that depends on it, and --purge deletes their configuration files, so copy anything you still need first. If you ever remove the Sury repository itself, follow its guide to going back to Debian’s packages: the libraries it installed stop getting updates once the repository is gone.
Related articles
- installing PHP 7.4 on Debian 9 or 10: the older guide, for legacy servers only
- enabling the PHP SOAP extension on Debian: another PHP extension installed with apt
- setting up Memcached and its PHP extension on Debian: an in-memory cache for PHP applications such as WordPress
- fixing apt’s HTTPS method driver error: when apt can’t use an https:// repository on an older server
