This guide covers installing PHP 8.4 on Fedora 42, 41, and 40. PHP 8.4 ships with property hooks, asymmetric visibility, the array_find() function, improved JIT performance, and deprecation of implicit nullable parameter types. Fedora moves faster than RHEL when it comes to packaging, but the default repositories don’t always have the latest PHP release on day one. We will use the Remi repository to get PHP 8.4, then configure it for production use with both Nginx and Apache.
If you are running RHEL, Rocky Linux, or AlmaLinux instead, see our PHP 8.4 on RHEL guide. For Debian systems, check the PHP 8.4 on Debian guide.
Prerequisites
Before you begin, make sure the following are in place:
- A running Fedora 42, 41, or 40 system with root or sudo access
- System packages updated to the latest versions
- A working internet connection for downloading packages
Start by updating your system:
sudo dnf update -y
Verify your Fedora release:
cat /etc/fedora-release
Step 1: Install the Remi Repository
Remi Collet maintains PHP packages for Fedora and RHEL-family distributions, and his repository is the standard way to get the latest PHP releases on Fedora. Unlike RHEL, Fedora does not require EPEL as a dependency for Remi. The Fedora base repositories already provide everything Remi needs.
Install the Remi repository for your Fedora version:
sudo dnf install -y https://rpms.remirepo.net/fedora/remi-release-$(rpm -E %fedora).rpm
This command automatically detects your Fedora release number and pulls the correct Remi package.
Verify the repository is available:
sudo dnf repolist | grep remi
You should see remi and remi-modular listed in the output.
Step 2: Enable the PHP 8.4 Module Stream
Fedora uses DNF modularity to manage PHP versions. Before enabling the Remi PHP 8.4 stream, check which PHP module stream is currently active:
sudo dnf module list php
If a default PHP module is already enabled, reset it first:
sudo dnf module reset php -y
Now enable the Remi PHP 8.4 stream:
sudo dnf module enable php:remi-8.4 -y
Confirm the active stream:
sudo dnf module list php
Look for remi-8.4 [e] in the output. The [e] flag means the stream is enabled.
Fedora-specific note: Fedora’s modular system works the same as RHEL’s, but Fedora releases tend to ship newer base PHP versions. Even so, the Remi stream gives you control over exactly which PHP version you run, regardless of what Fedora ships by default.
Step 3: Install PHP 8.4 and Common Extensions
Install PHP 8.4 with the extensions that most web applications need:
sudo dnf install -y php php-fpm php-cli php-mysqlnd php-pgsql php-curl php-gd php-mbstring php-xml php-zip php-intl php-opcache php-redis php-bcmath php-soap php-ldap
Here is what each extension provides:
| Package | Purpose |
|---|---|
php-fpm | FastCGI Process Manager – required for Nginx and recommended for Apache |
php-cli | Command-line interface for running PHP scripts |
php-mysqlnd | Native MySQL/MariaDB driver |
php-pgsql | PostgreSQL database driver |
php-curl | Client URL library for HTTP requests |
php-gd | Image processing library |
php-mbstring | Multibyte string handling for UTF-8 and other encodings |
php-xml | XML parsing and manipulation |
php-zip | ZIP archive handling |
php-intl | Internationalization functions (ICU library) |
php-opcache | Opcode caching for performance |
php-redis | Redis key-value store driver |
php-bcmath | Arbitrary precision math for financial calculations |
php-soap | SOAP protocol support for web services |
php-ldap | LDAP directory access for authentication |
To search for additional extensions available in the Remi repository:
sudo dnf search php- | grep remi
Step 4: Verify the PHP Installation
Check the installed PHP version:
php -v
Expected 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 Technologies
List all loaded PHP modules to confirm your extensions are active:
php -m
You can also check where the configuration files are loaded from:
php --ini
This shows the main php.ini path and the scan directory where extension-specific .ini files are stored. On Fedora with Remi, the scan directory is /etc/php.d/.
Step 5: Configure php.ini
The main PHP configuration file on Fedora is /etc/php.ini. Open it with your preferred editor:
sudo vi /etc/php.ini
Below are the settings I recommend adjusting for most production workloads. Tune the values based on your server resources and application requirements.
Memory and execution limits
memory_limit = 256M
max_execution_time = 300
max_input_time = 300
max_input_vars = 5000
File upload settings
upload_max_filesize = 64M
post_max_size = 64M
Timezone
date.timezone = UTC
OPcache settings
OPcache stores precompiled PHP bytecode in shared memory, which eliminates the need to parse scripts on every request. This is one of the biggest performance wins you can get. Edit the OPcache configuration file:
sudo vi /etc/php.d/10-opcache.ini
Set the following values:
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
opcache.validate_timestamps=1
opcache.save_comments=1
opcache.jit=on
opcache.jit_buffer_size=128M
The JIT compiler in PHP 8.4 provides additional performance gains for CPU-bound workloads. The opcache.jit=on setting enables it with the default tracing mode. If your workload is mostly I/O-bound (typical for web applications), JIT won’t make a dramatic difference, but it doesn’t hurt either.
Verify the configuration changes took effect:
php -i | grep -E "memory_limit|upload_max_filesize|opcache.enable"
Step 6: Configure PHP-FPM
PHP-FPM handles PHP requests as a separate process pool and is the recommended way to run PHP with both Nginx and Apache. On Fedora, the main pool configuration file is:
sudo vi /etc/php-fpm.d/www.conf
Key settings to review and adjust:
; Process user and group - match your web server user
user = nginx
group = nginx
; Listen on a Unix socket for better performance
listen = /run/php-fpm/www.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
; Process manager settings
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
If you are using Apache instead of Nginx, change the user, group, listen.owner, and listen.group values to apache:
user = apache
group = apache
listen.owner = apache
listen.group = apache
A quick note on the pm directive:
- dynamic – spawns child processes on demand between min and max limits. Good default for most servers.
- static – keeps a fixed number of child processes running at all times. Useful for dedicated PHP servers with predictable load.
- ondemand – only spawns workers when requests arrive, then kills idle ones. Good for low-traffic sites to save memory.
For servers with 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 = 500
Step 7: Enable and Start PHP-FPM
sudo systemctl enable --now php-fpm
Verify PHP-FPM is running:
sudo systemctl status php-fpm
You should see active (running) in the output. Also confirm the socket file exists:
ls -la /run/php-fpm/www.sock
Step 8: Integrate PHP 8.4 with Nginx
If you are running Nginx, install it first if you have not already:
sudo dnf install -y nginx
sudo systemctl enable --now nginx
Create or edit your Nginx server block. Fedora keeps Nginx configuration files in /etc/nginx/conf.d/:
sudo vi /etc/nginx/conf.d/default.conf
Add the following configuration:
server {
listen 80;
server_name your_domain.com;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Test the Nginx configuration and reload:
sudo nginx -t && sudo systemctl reload nginx
Step 9: Integrate PHP 8.4 with Apache
Apache supports PHP through two methods: mod_php and PHP-FPM. PHP-FPM is the recommended approach because it handles processes independently and performs better under load.
Option A: Using PHP-FPM with Apache (Recommended)
Install Apache if you have not already:
sudo dnf install -y httpd
sudo systemctl enable --now httpd
Make sure the user/group in /etc/php-fpm.d/www.conf is set to apache as shown in Step 6. Then create a configuration file for PHP-FPM:
sudo vi /etc/httpd/conf.d/php-fpm.conf
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>
DirectoryIndex index.php
Restart both services:
sudo systemctl restart php-fpm httpd
Option B: Using mod_php with Apache
If you prefer the traditional mod_php approach (simpler setup but less efficient under heavy load), install the PHP Apache module:
sudo dnf install -y httpd php
sudo systemctl restart httpd
Verify the module is loaded:
httpd -M | grep php
You should see php_module in the output. Keep in mind that mod_php runs PHP inside the Apache process itself, which uses more memory per worker than PHP-FPM. For production servers handling significant traffic, PHP-FPM is the better choice.
Step 10: Test with phpinfo()
Create a test PHP file in your web root to verify everything is working:
echo '<?php phpinfo(); ?>' | sudo tee /var/www/html/info.php
Open your browser and navigate to:
http://your_server_ip/info.php
You should see the PHP information page showing version 8.4.x with all your installed extensions listed. Check the following sections:
- PHP Version – confirms 8.4.x
- Server API – shows FPM/FastCGI (if using PHP-FPM) or Apache 2.0 Handler (if using mod_php)
- Loaded Configuration File – should point to /etc/php.ini
- OPcache – should show enabled with JIT active
Important: Remove the test file after verification. Leaving phpinfo() exposed is a security risk as it reveals detailed server configuration.
sudo rm -f /var/www/html/info.php
Switching Between PHP Versions with DNF Modules
One of the advantages of DNF module streams is the ability to switch between PHP versions without manually removing packages. This is particularly useful on Fedora where you might need to test applications against different PHP releases.
List available PHP module streams
sudo dnf module list php
This shows all available streams from both the Fedora base and Remi repositories.
Switch to a different PHP version
To switch from PHP 8.4 to PHP 8.3, for example:
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.3 -y
sudo dnf distro-sync -y
After switching, verify the active version:
php -v
Then restart PHP-FPM and your web server:
sudo systemctl restart php-fpm
sudo systemctl restart nginx # or httpd for Apache
Switch back to PHP 8.4
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.4 -y
sudo dnf distro-sync -y
sudo systemctl restart php-fpm
Fedora-specific note: Unlike RHEL where you typically stick with one PHP version for the lifetime of the OS release, Fedora’s shorter lifecycle means you are more likely to upgrade PHP alongside OS upgrades. When you upgrade from, say, Fedora 41 to 42, re-install the Remi repository for the new release and re-enable your preferred PHP stream.
Troubleshooting
PHP-FPM fails to start
Check the PHP-FPM logs for errors:
sudo journalctl -u php-fpm -e --no-pager
Common causes:
- Socket permission errors – verify listen.owner and listen.group in www.conf match your web server user.
- Port already in use – another PHP-FPM instance or process may be binding to the same socket. Check with
ss -tlnp | grep php. - Syntax errors in configuration – validate with
php-fpm -t.
502 Bad Gateway in Nginx
This usually means Nginx cannot communicate with PHP-FPM. Check these:
# Confirm PHP-FPM is running
sudo systemctl status php-fpm
# Check the socket file exists and has correct permissions
ls -la /run/php-fpm/www.sock
# Verify Nginx is pointing to the correct socket path
grep fastcgi_pass /etc/nginx/conf.d/*.conf
PHP extensions not loading
If a specific extension does not show up in php -m output:
# Check if the extension package is installed
rpm -qa | grep php-
# Verify the .ini file exists in the scan directory
ls /etc/php.d/
# Check for errors when loading the extension
php -d display_errors=1 -r "phpinfo();" 2>&1 | grep -i error
Module stream conflicts
If you see errors about conflicting module streams when installing PHP packages:
# Reset all PHP module streams
sudo dnf module reset php -y
# Remove any existing PHP packages
sudo dnf remove -y 'php-*'
# Re-enable the desired stream and install fresh
sudo dnf module enable php:remi-8.4 -y
sudo dnf install -y php php-fpm php-cli
SELinux blocking PHP-FPM
Fedora ships with SELinux in enforcing mode by default. If PHP-FPM is denied access to files or network resources, check for audit denials:
sudo ausearch -m avc -ts recent
Common SELinux booleans you may need to enable:
# Allow PHP-FPM to connect to databases over the network
sudo setsebool -P httpd_can_network_connect_db 1
# Allow PHP-FPM to make outbound network connections (APIs, remote services)
sudo setsebool -P httpd_can_network_connect 1
# Allow PHP-FPM to send emails
sudo setsebool -P httpd_can_sendmail 1
Firewall not allowing HTTP traffic
Fedora uses firewalld by default. If you cannot reach your web server from a browser, open the necessary ports:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Verify the firewall rules:
sudo firewall-cmd --list-services
File upload size errors
If uploads fail for large files, make sure you have updated both upload_max_filesize and post_max_size in php.ini, and that post_max_size is equal to or larger than upload_max_filesize. If using Nginx, also set the client_max_body_size directive in your server block:
# In your Nginx server block
client_max_body_size 64M;
After making changes, restart PHP-FPM and your web server:
sudo systemctl restart php-fpm
sudo systemctl restart nginx # or httpd for Apache
Conclusion
You now have PHP 8.4 running on Fedora with full production configuration. We covered installing PHP from the Remi repository using DNF module streams, configuring php.ini and PHP-FPM for production workloads, integrating with both Nginx and Apache, and switching between PHP versions when needed. The key difference from RHEL is that Fedora does not need EPEL as a Remi dependency, and Fedora’s shorter release cycle means you should plan for re-enabling Remi after each OS upgrade. The DNF module system keeps version management clean and predictable across all your Fedora servers.