PHP 8.4 is the latest stable release of the PHP programming language, packed with performance improvements, new features like property hooks, asymmetric visibility, and a revamped DOM API. In this guide, I’ll walk you through installing PHP 8.4 on Debian 13 (Trixie) and Debian 12 (Bookworm), configuring it for production use, and integrating it with both Nginx and Apache.
I’ve been running PHP in production for over a decade, and getting the initial setup right saves you hours of debugging later. Let’s get into it.
Prerequisites
Before you start, make sure you have the following in place:
- A server running Debian 13 (Trixie) or Debian 12 (Bookworm)
- Root access or a user with sudo privileges
- A working internet connection
- Basic familiarity with the Linux command line
Start by updating your system packages:
sudo apt update && sudo apt upgrade -yStep 1 – Add the Sury PHP Repository
Debian’s default repositories don’t always ship the latest PHP version. The Sury repository, maintained by Ondrej Sury (a Debian PHP package maintainer), gives you access to PHP 8.4 and other recent PHP versions.
Install the required dependencies first:
sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2 curlAdd the Sury GPG key and repository:
curl -fsSL https://packages.sury.org/php/apt.gpg | sudo gpg --dearmor -o /usr/share/keyrings/sury-php.gpg
echo "deb [signed-by=/usr/share/keyrings/sury-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.listUpdate the package index to pull in packages from the new repository:
sudo apt updateVerify that the Sury repository is available:
apt-cache policy php8.4You should see version information with packages.sury.org listed as the source.
Step 2 – Install PHP 8.4 and Common Extensions
Now install PHP 8.4 along with the extensions most applications need:
sudo apt install -y php8.4 php8.4-cli php8.4-fpm php8.4-mysql php8.4-pgsql php8.4-curl php8.4-gd php8.4-mbstring php8.4-xml php8.4-zip php8.4-intl php8.4-opcache php8.4-redisHere’s what each extension does:
- cli – Command-line interface for running PHP scripts from the terminal
- fpm – FastCGI Process Manager for serving PHP with Nginx or Apache
- mysql – MySQL and MariaDB database support
- pgsql – PostgreSQL database support
- curl – HTTP client library for making API requests
- gd – Image processing library
- mbstring – Multibyte string handling for UTF-8 and other encodings
- xml – XML parsing and manipulation
- zip – ZIP archive support
- intl – Internationalization functions
- opcache – Bytecode caching for better performance
- redis – Redis key-value store support for sessions and caching
Verify the Installation
Check that PHP 8.4 is installed and working:
php -vExpected output:
PHP 8.4.x (cli) (built: ...)
Copyright (c) The PHP Group
Zend Engine v4.4.x, Copyright (c) Zend Technologies
with Zend OPcache v8.4.x, Copyright (c), by Zend TechnologiesList all installed PHP modules to confirm the extensions are loaded:
php -mStep 3 – Configure php.ini Settings
The default php.ini values are conservative and usually need adjusting for production workloads. There are separate php.ini files for CLI and FPM – we’ll focus on the FPM config since that’s what serves your web applications.
Open the FPM php.ini file:
sudo nano /etc/php/8.4/fpm/php.iniFind and update these settings. These values work well for most web applications – adjust based on your specific needs:
General Settings
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
max_input_time = 300
max_input_vars = 5000
date.timezone = UTCOPcache Settings
OPcache stores precompiled PHP bytecode in shared memory, which eliminates the need to parse scripts on every request. This is one of the single biggest performance wins you can get.
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 2
opcache.save_comments = 1
opcache.validate_timestamps = 1A quick note on opcache.validate_timestamps – set this to 0 in production if you deploy with a clear opcache step. When set to 0, PHP won’t check if files have changed, which gives you a small performance bump. But if you edit files directly on the server, keep it at 1.
Verify the configuration changes:
php -i | grep -E "memory_limit|upload_max_filesize|opcache.enable"Step 4 – Configure PHP-FPM Pool
PHP-FPM manages a pool of worker processes that handle incoming PHP requests. The default pool configuration lives in the www.conf file.
sudo nano /etc/php/8.4/fpm/pool.d/www.confKey settings to adjust:
; Process manager type - 'dynamic' is the best choice for most servers
pm = dynamic
; Maximum number of child processes - set based on available RAM
; Formula: (Total RAM - RAM for OS and other services) / Average PHP process size
; For a server with 4GB RAM, 50 is a reasonable starting point
pm.max_children = 50
; Number of child processes created on startup
pm.start_servers = 5
; Minimum number of idle processes
pm.min_spare_servers = 5
; Maximum number of idle processes
pm.max_spare_servers = 35
; Number of requests each child process should execute before respawning
; Helps prevent memory leaks from accumulating
pm.max_requests = 500If your server has limited RAM (1-2 GB), use more conservative values:
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500Enable and Start PHP-FPM
sudo systemctl enable php8.4-fpm
sudo systemctl start php8.4-fpmVerify that PHP-FPM is running:
sudo systemctl status php8.4-fpmYou should see active (running) in the output. Also confirm the FPM socket exists:
ls -la /run/php/php8.4-fpm.sockStep 5 – Integrate PHP 8.4 with Nginx
If you’re using Nginx, install it first (skip if already installed):
sudo apt install -y nginxCreate a virtual host configuration:
sudo nano /etc/nginx/sites-available/example.confAdd the following configuration (replace example.com with your domain):
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}Enable the site and test the Nginx configuration:
sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/
sudo nginx -tIf the test passes, reload Nginx:
sudo systemctl reload nginxStep 6 – Integrate PHP 8.4 with Apache
If you’re running Apache instead, install it along with the FastCGI module:
sudo apt install -y apache2 libapache2-mod-fcgidEnable the required Apache modules:
sudo a2enmod proxy_fcgi setenvif rewrite
sudo a2enconf php8.4-fpmCreate a virtual host configuration:
sudo nano /etc/apache2/sites-available/example.confAdd the following (replace example.com with your domain):
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
<Directory /var/www/example.com>
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/example_error.log
CustomLog ${APACHE_LOG_DIR}/example_access.log combined
</VirtualHost>Enable the site and test Apache’s configuration:
sudo a2ensite example.conf
sudo apachectl configtestIf you see Syntax OK, reload Apache:
sudo systemctl reload apache2Step 7 – Test with phpinfo()
Create a test file to confirm everything is working together:
sudo mkdir -p /var/www/example.com
echo '<?php phpinfo(); ?>' | sudo tee /var/www/example.com/info.phpSet the correct ownership:
sudo chown -R www-data:www-data /var/www/example.comOpen your browser and navigate to http://your-server-ip/info.php. You should see the PHP information page showing version 8.4 with all your installed extensions.
Important: Remove the info.php file after testing. It exposes detailed server information that you don’t want publicly accessible:
sudo rm /var/www/example.com/info.phpStep 8 – Manage Multiple PHP Versions with update-alternatives
If you have applications that still require an older PHP version, you can install multiple versions side by side and switch between them using update-alternatives.
For example, to install PHP 8.3 alongside 8.4:
sudo apt install -y php8.3 php8.3-cli php8.3-fpmRegister both versions with update-alternatives:
sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.4 84
sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.3 83Switch between versions interactively:
sudo update-alternatives --config phpThis shows a menu where you select which PHP version to use as the default CLI version. Choose the version you want and press Enter.
Or set a specific version directly:
sudo update-alternatives --set php /usr/bin/php8.4Verify the active version:
php -vFor web server integration, you control which PHP version handles requests by pointing your Nginx or Apache configuration to the correct FPM socket – for example, /run/php/php8.4-fpm.sock or /run/php/php8.3-fpm.sock. This means different virtual hosts can use different PHP versions.
Troubleshooting
PHP-FPM Fails to Start
Check the logs for specific errors:
sudo journalctl -xeu php8.4-fpmCommon causes include syntax errors in pool configuration or port/socket conflicts with another PHP-FPM version. Make sure you don’t have two FPM pools trying to listen on the same socket.
502 Bad Gateway in Nginx
This usually means Nginx can’t reach the PHP-FPM socket. Verify the socket exists and has the right permissions:
ls -la /run/php/php8.4-fpm.sock
sudo systemctl status php8.4-fpmAlso check that the fastcgi_pass path in your Nginx config matches the actual socket path.
Extensions Not Loading
If php -m doesn’t show an extension you installed, check if the extension’s .ini file exists:
ls /etc/php/8.4/mods-available/Enable it manually if needed:
sudo phpenmod -v 8.4 <extension-name>
sudo systemctl restart php8.4-fpmSury Repository GPG Key Errors
If you get GPG key errors during apt update, re-download the key:
sudo rm /usr/share/keyrings/sury-php.gpg
curl -fsSL https://packages.sury.org/php/apt.gpg | sudo gpg --dearmor -o /usr/share/keyrings/sury-php.gpg
sudo apt updateFile Upload Size Errors
If uploads fail for large files, make sure you’ve updated both upload_max_filesize and post_max_size in php.ini, and post_max_size is equal to or larger than upload_max_filesize. If using Nginx, also check the client_max_body_size directive:
# In your Nginx server block
client_max_body_size 64M;After making any changes, restart PHP-FPM and your web server:
sudo systemctl restart php8.4-fpm
sudo systemctl restart nginx # or apache2OPcache Not Working
Verify OPcache is active through the CLI:
php -r "var_dump(opcache_get_status());"If it returns false, make sure opcache.enable=1 is set in your FPM php.ini (not just the CLI php.ini) and that the opcache module is loaded.
Conclusion
You now have PHP 8.4 installed and configured on Debian 13 or Debian 12. The setup covers PHP-FPM with tuned pool settings, OPcache for performance, and integration with either Nginx or Apache. You also know how to manage multiple PHP versions if your projects need them.
For production servers, I’d recommend monitoring your PHP-FPM process usage over time and adjusting pm.max_children based on actual memory consumption. You can check the status page by enabling pm.status_path in your pool configuration.


































































this repository seems to be offline. apt update return this:
W: Failed to fetch https://packages.sury.org/php/dists/jessie/main/binary-amd64/Packages HttpError404