PHP is the most widely used server-side scripting language for web development. It powers major platforms like WordPress, Laravel, Drupal, and Magento. RHEL 10, Rocky Linux 10, and AlmaLinux 10 ship PHP 8.3 in the default AppStream repository, and the Remi repository provides access to newer versions like PHP 8.4 and PHP 8.5.
This guide covers installing PHP on AlmaLinux 10, Rocky Linux 10, and RHEL 10 – from the default AppStream package to the latest PHP 8.5 via the Remi repository. We also cover PHP-FPM configuration with both Nginx and Apache, key php.ini tuning, and switching between PHP versions. Check the PHP supported versions page for current lifecycle dates before choosing a version for production.
Prerequisites
- A server running AlmaLinux 10, Rocky Linux 10, or RHEL 10
- Root or sudo access
- Internet connectivity for package downloads
- A web server (Nginx or Apache) if you plan to serve PHP pages – we cover both setups
Step 1: Install PHP from AppStream (Default Version)
RHEL 10 and its derivatives dropped modularity, so PHP 8.3 is available directly from the AppStream repository without enabling any module streams. This is the simplest path if PHP 8.3 meets your requirements.
Install PHP with a set of commonly needed extensions:
sudo dnf install php php-cli php-fpm php-mysqlnd php-pgsql php-gd php-mbstring php-xml php-curl php-zip php-intl php-opcache php-soap
Confirm the installed PHP version:
php -v
The output confirms PHP 8.3 from the AppStream repository:
PHP 8.3.19 (cli) (built: Mar 4 2026 00:00:00) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.3.19, Copyright (c) Zend Technologies
with Zend OPcache v8.3.19, Copyright (c), by Zend Technologies
If PHP 8.3 is all you need, skip ahead to Step 3 for extension management. If you need PHP 8.4 or 8.5, continue to Step 2.
Step 2: Install PHP 8.5 or 8.4 from Remi Repository
The Remi repository maintains up-to-date PHP packages for Enterprise Linux. PHP 8.5 is the latest stable release with active support until December 2027, and PHP 8.4 remains in active support until December 2026.
Enable EPEL and Remi repositories
Install EPEL first, then the Remi release package for EL10:
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-10.rpm
Enable the CodeReady Builder (CRB) repository, which provides development dependencies that some PHP extensions need:
sudo crb enable
Install PHP 8.5 from Remi
Reset any existing PHP module configuration and enable the Remi PHP 8.5 stream:
sudo dnf module reset php
sudo dnf module enable php:remi-8.5
Now install PHP with common extensions:
sudo dnf install php php-cli php-fpm php-mysqlnd php-pgsql php-gd php-mbstring php-xml php-curl php-zip php-intl php-opcache php-soap
Verify that PHP 8.5 is now active:
php -v
You should see PHP 8.5 confirmed in the output:
PHP 8.5.3 (cli) (built: Mar 4 2026 00:00:00) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.5.3, Copyright (c) Zend Technologies
with Zend OPcache v8.5.3, Copyright (c), by Zend Technologies
To install PHP 8.4 instead, replace remi-8.5 with remi-8.4 in the module enable command.
Step 3: Install PHP Extensions
PHP extensions add support for databases, image processing, caching, and other functionality your application needs. The base install from Step 1 or Step 2 covers most common use cases, but here is how to find and install additional extensions.
List all available PHP extensions:
dnf search php- | grep -i "^php-"
The table below covers commonly needed PHP extensions and what they provide:
| Package | Purpose |
|---|---|
php-mysqlnd | MySQL/MariaDB native driver |
php-pgsql | PostgreSQL driver |
php-redis | Redis client extension |
php-gd | Image processing (JPEG, PNG, GIF) |
php-mbstring | Multi-byte string handling (UTF-8) |
php-xml | XML parsing and DOM support |
php-curl | HTTP client (cURL bindings) |
php-zip | ZIP archive handling |
php-intl | Internationalization (ICU library) |
php-opcache | Bytecode caching for performance |
php-soap | SOAP web services |
php-ldap | LDAP directory access |
php-bcmath | Arbitrary precision math |
php-imagick | ImageMagick bindings |
Install any additional extensions you need. For example, to add Redis and ImageMagick support:
sudo dnf install php-redis php-imagick
After installing extensions, verify they are loaded:
php -m
This lists all loaded PHP modules. You can also check a specific extension:
php -m | grep -i redis
Step 4: Configure PHP-FPM
PHP-FPM (FastCGI Process Manager) is the standard way to run PHP with both Nginx and modern Apache setups. It runs as a separate service that handles PHP requests from the web server.
Enable and start PHP-FPM:
sudo systemctl enable --now php-fpm
Verify the service is running:
systemctl status php-fpm
The service should show active (running) with the process listening for connections:
● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
Active: active (running) since Sun 2026-03-22 10:00:00 UTC; 5s ago
Main PID: 12345 (php-fpm)
Status: "Ready to handle connections"
The main PHP-FPM pool configuration file is at /etc/php-fpm.d/www.conf. Open it to tune pool settings:
sudo vi /etc/php-fpm.d/www.conf
Key settings to adjust for production workloads:
; Run as the web server user
user = nginx
group = nginx
; Use a Unix socket for better performance (default on EL10)
listen = /run/php-fpm/www.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
; Process manager - dynamic is good for most workloads
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.
After making changes, restart PHP-FPM:
sudo systemctl restart php-fpm
Step 5: Configure PHP with Nginx
Nginx does not process PHP natively – it passes PHP requests to PHP-FPM over a Unix socket. If you already have Nginx installed on Rocky Linux 10 / AlmaLinux 10, add the PHP handler to your server block.
Install Nginx if you have not already:
sudo dnf install nginx
sudo systemctl enable --now nginx
Create a server block configuration for your site:
sudo vi /etc/nginx/conf.d/default.conf
Add the following configuration that passes .php requests to PHP-FPM:
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;
}
}
Make sure the PHP-FPM pool runs as the nginx user (as configured in Step 4). Test the Nginx configuration and reload:
sudo nginx -t && sudo systemctl reload nginx
Open the firewall for HTTP and HTTPS traffic. See our Firewalld guide for Rocky Linux 10 for more details on zone-based rules:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Step 6: Configure PHP with Apache
Apache can handle PHP through PHP-FPM using the mod_proxy_fcgi module, which is included by default in Apache on RHEL 10. This is the recommended approach over the older mod_php.
Install Apache if you have not already:
sudo dnf install httpd
sudo systemctl enable --now httpd
PHP-FPM ships a default Apache configuration file that sets up the proxy. Verify it exists:
cat /etc/httpd/conf.d/php.conf
The file should contain a handler that forwards .php files to PHP-FPM. If you need to customize it, open the file:
sudo vi /etc/httpd/conf.d/php.conf
The default configuration uses the Unix socket:
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>
DirectoryIndex index.php
Update the PHP-FPM pool to run as the apache user. Open /etc/php-fpm.d/www.conf and set:
user = apache
group = apache
listen.owner = apache
listen.group = apache
Restart both PHP-FPM and Apache to apply the changes:
sudo systemctl restart php-fpm httpd
Open the firewall for web traffic if you have not done so already:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Step 7: Configure php.ini Settings
The main PHP configuration file controls memory limits, upload sizes, error handling, and timezone settings. These defaults are conservative and usually need adjustment for production web applications.
Open the PHP configuration file:
sudo vi /etc/php.ini
Update the following directives based on your application requirements:
; Memory limit - increase for CMS/frameworks like WordPress, Laravel
memory_limit = 256M
; Maximum upload file size
upload_max_filesize = 64M
; Maximum POST data size - must be >= upload_max_filesize
post_max_size = 64M
; Maximum execution time in seconds
max_execution_time = 300
; Maximum input variables (increase for complex forms/WooCommerce)
max_input_vars = 5000
; Timezone - set to your server timezone
date.timezone = UTC
; Error display - disable in production, enable in development
display_errors = Off
log_errors = On
error_log = /var/log/php-fpm/error.log
; OPcache settings for production performance
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 60
opcache.validate_timestamps = 1
If you are running a LAMP stack with WordPress or a similar CMS, the settings above are a solid starting point. For Laravel or Symfony applications, you may also want to increase max_execution_time for queue workers.
Restart PHP-FPM after making changes:
sudo systemctl restart php-fpm
Step 8: Switch PHP Versions
If you installed PHP from the Remi repository, switching between versions is straightforward using DNF module streams. This is useful when testing application compatibility or upgrading to a newer PHP release.
Check which PHP module stream is currently enabled:
dnf module list php
The output shows available streams with [e] marking the enabled one:
Name Stream Profiles Summary
php remi-8.3 common [d] PHP scripting language
php remi-8.4 common [d] PHP scripting language
php remi-8.5 common [d] [e] PHP scripting language
To switch from PHP 8.5 to PHP 8.4, reset the module and enable the new stream:
sudo dnf module reset php
sudo dnf module enable php:remi-8.4
Then run a distro-sync to swap the packages:
sudo dnf distro-sync
Verify the version change:
php -v
Restart PHP-FPM after the switch:
sudo systemctl restart php-fpm
Always test your application after switching PHP versions. Check the PHP error log for deprecation notices or incompatibilities:
sudo tail -f /var/log/php-fpm/error.log
Step 9: Verify PHP Installation with phpinfo()
Create a PHP info page to confirm that PHP is working correctly with your web server. This page shows the full PHP configuration, loaded extensions, and server environment.
Create the test file in your web root:
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 your installed version, loaded modules, and configuration directives.
After verifying, remove the info page immediately. It exposes server details that attackers can use:
sudo rm /var/www/html/info.php
For a quick command-line verification without creating a web-accessible file, use:
php -i | head -20
You can also check that PHP-FPM is processing requests through the web server by checking the PHP-FPM status. If you set up a LEMP stack on Rocky Linux, the PHP-FPM pool status page gives real-time process metrics.
Conclusion
PHP is now installed and configured on your AlmaLinux 10, Rocky Linux 10, or RHEL 10 server. You have the default PHP 8.3 from AppStream or a newer version from the Remi repository, PHP-FPM running as a service, and integration with either Nginx or Apache.
For production deployments, enable HTTPS with Let’s Encrypt, set display_errors = Off, configure log rotation for PHP-FPM logs, and monitor PHP-FPM pool utilization to tune pm.max_children based on your server’s available memory. If you are running a Java application server like Tomcat alongside PHP, make sure to allocate memory budgets for each service separately.