Which PHP version apt install php pulls in has nothing to do with what your application needs and everything to do with which Debian you run. Debian 12 ships 8.2, Debian 13 ships 8.4. There is nothing in between, and nothing to choose from.
Which version each Debian ships
Every Debian release freezes exactly one PHP version and maintains it with security fixes for the whole lifetime of that release.
| Debian | Codename | PHP |
|---|---|---|
| 11 | bullseye | 7.4 |
| 12 | bookworm | 8.2 |
| 13 | trixie | 8.4 |
To find out what you are on:
cat /etc/debian_version; lsb_release -sc
The upstream version number in the packages stays put even as fixes land. Debian raises its own revision instead, turning 8.2.20-1~deb12u1 into 8.2.20-1~deb12u2. So an upstream number that looks older than the current PHP release does not mean vulnerabilities are open.
If the bundled version is not enough, Ondřej Surý's repository is the established route. It carries PHP 5.6 through 8.6 for current Debian releases; setup is covered in installing PHP via Sury.
Which packages you actually need
The php metapackage drags in a long list of dependencies, Apache and libapache2-mod-php among them. On a server running nginx, or one that only needs PHP on the command line, that is unwanted. Install deliberately instead.
For cron jobs or Composer, the command line is enough:
sudo apt install php-cli
Behind a web server, PHP-FPM is the usual choice. It runs as its own service, and both Apache and nginx talk to it:
sudo apt install php-fpm
Then the extensions your application asks for. This selection covers most web applications:
sudo apt install php-mysql php-curl php-gd php-mbstring php-xml php-zip php-intl php-bcmath
| Package | What it is for |
|---|---|
php-mysql | MySQL and MariaDB, provides PDO and mysqli |
php-curl | outbound HTTP requests from the application |
php-gd | image processing, thumbnails, captchas |
php-mbstring | strings with accents and multi-byte characters |
php-xml | XML, SimpleXML, DOM |
php-zip | reading and writing archives |
php-intl | locale-aware sorting, date and number formats |
php-bcmath | arbitrary precision arithmetic |
php-json appears in plenty of older guides and no longer exists. JSON support has been part of the core since PHP 8.0, so the install attempt ends with an error about an unknown package.
Wiring up Apache
Two routes lead there, and they are mutually exclusive.
Through PHP-FPM
The recommended route, because it works with the faster mpm_event.
sudo apt install php-fpm libapache2-mod-fcgid
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.2-fpm
sudo systemctl reload apache2
Adjust the number in php8.2-fpm to your version. ls /etc/apache2/conf-available/ | grep fpm shows which configurations are available.
Through mod_php
sudo apt install libapache2-mod-php
Works, but forces Apache onto mpm_prefork, because mod_php is not thread-safe. On a server with many concurrent connections that costs noticeable performance. If you later move from mod_php to FPM, disable the module first:
sudo a2dismod php8.2 mpm_prefork
sudo a2enmod mpm_event proxy_fcgi setenvif
sudo a2enconf php8.2-fpm
sudo systemctl restart apache2
Wiring up nginx
nginx has no mod_php; FPM is the only way. In the server block:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
Confirm the actual socket path with ls /run/php/. After changes, test and reload:
sudo nginx -t && sudo systemctl reload nginx
The two php.ini files
Debian keeps separate configurations for the command line and for FPM:
/etc/php/8.2/cli/php.ini ← php on the command line
/etc/php/8.2/fpm/php.ini ← PHP behind the web server
Change upload_max_filesize and wonder why the web interface still refuses the file, and you edited the wrong one. To see which file a given invocation actually reads:
php -i | grep "Loaded Configuration File"
The same applies to the web side through a script calling phpinfo(). After any change to the FPM configuration the service needs a restart — reloading the web server is not enough:
sudo systemctl restart php8.2-fpm
phpinfo() script reachable. It exposes paths, loaded extensions, version numbers and parts of your configuration — a ready-made map for anyone who finds the page. Delete it once you have looked.Checking that it works
php -v
php -m
systemctl status php8.2-fpm
php -v reports the command-line version, php -m lists loaded extensions. If one you installed is missing, the service was not restarted afterwards.
Troubleshooting
| Problem | Cause and fix |
|---|---|
| The browser offers the PHP file as a download | PHP is not wired to the web server. Enable the FPM configuration or check fastcgi_pass. |
php -v shows a different version than the website | Command line and FPM can run different versions. See running multiple PHP versions. |
A php.ini change has no effect | The wrong one of the two files was edited, or php-fpm was not restarted. |
| An extension is missing despite installing it | The service was not restarted, or the package belongs to a different PHP version. |
php-json cannot be installed | Built into the core since PHP 8.0; there is no separate package. |
| Apache will not start after moving to FPM | mpm_prefork and mpm_event are both enabled. Disable one. |
No socket under /run/php/ | FPM is not running. systemctl status php8.2-fpm gives the reason. |
Frequently asked questions about PHP on Debian
Which PHP version does my Debian have?
Debian 11 ships PHP 7.4, Debian 12 ships 8.2 and Debian 13 ships 8.4. No other version is available from Debian's own repositories; that needs an additional one.
Do I need php-fpm or libapache2-mod-php?
PHP-FPM for new installations. It works with both Apache and nginx and allows the faster mpm_event. mod_php forces Apache onto mpm_prefork and is the weaker choice today.
Where is php.ini?
At /etc/php/<version>/cli/php.ini for the command line and /etc/php/<version>/fpm/php.ini for the web server. They are separate. php -i | grep "Loaded Configuration File" shows which one applies.
How do I get a newer PHP version than Debian offers?
Through the Sury repository, which provides PHP 5.6 to 8.6 for current Debian releases. Setup is covered in installing PHP via Sury.
Do I have to restart after a configuration change?
With FPM, yes: systemctl restart php8.2-fpm. Reloading the web server is not enough, because PHP runs in its own service.