PHP is a general-purpose scripting language that powers the majority of dynamic websites and web applications, including WordPress, Drupal, and Laravel. Rocky Linux 10 and AlmaLinux 10 ship PHP 8.3 in the AppStream repositories, which works for most production workloads. For PHP 8.4 with its property hooks, asymmetric visibility, and new array functions, the Remi repository provides up-to-date packages.
This guide covers both methods – installing PHP 8.3 from AppStream and PHP 8.4 from the Remi repository on Rocky Linux 10 and AlmaLinux 10. We also configure PHP-FPM with Nginx, install common extensions, tune php.ini for production, and handle firewall and SELinux settings.
Prerequisites
- A server running Rocky Linux 10 or AlmaLinux 10 with root or sudo access
- At least 1 GB RAM and 10 GB free disk space
- A working internet connection to download packages
- Nginx or Apache installed if you plan to serve PHP web applications (this guide uses Nginx)
Step 1: Install PHP 8.3 from AppStream (Default)
Rocky Linux 10 and AlmaLinux 10 include PHP 8.3 in the default AppStream repository. This is the simplest option and receives security updates through the OS lifecycle.
Install PHP with the CLI and commonly used extensions:
sudo dnf install -y php php-cli php-fpm php-mysqlnd php-gd php-mbstring php-xml php-curl php-zip php-opcache php-bcmath php-intl php-soap
Confirm the installed version matches PHP 8.3:
php --version
The output confirms PHP 8.3 is installed from the AppStream repository:
PHP 8.3.29 (cli) (built: Mar 11 2026 00:00:00) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.3.29, Copyright (c) Zend Technologies
with Zend OPcache v8.3.29, Copyright (c), by Zend Technologies
If PHP 8.3 from AppStream meets your requirements, skip ahead to Step 3 to configure PHP-FPM. If you need PHP 8.4 features like property hooks, asymmetric visibility, or the new array_find() functions, continue with Step 2.
Step 2: Install PHP 8.4 from Remi Repository
PHP 8.4 brings significant improvements including property hooks, asymmetric visibility, lazy objects, HTML5 DOM parser, new array functions (array_find, array_any, array_all), and multibyte string functions (mb_trim, mb_ucfirst). To get PHP 8.4 on Rocky Linux 10 or AlmaLinux 10, use the Remi repository.
Add EPEL and Remi repositories
Install EPEL first, as Remi depends on it:
sudo dnf install -y epel-release
Enable the CodeReady Builder (CRB) repository, which provides development dependencies needed by some PHP extensions:
sudo dnf config-manager --set-enabled crb
Add the Remi repository for EL 10:
sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-10.rpm
Remove default PHP and install PHP 8.4
If you already installed PHP 8.3 from AppStream, remove it first to avoid conflicts:
sudo dnf remove -y php php-cli php-common php-fpm
Reset the PHP module stream and enable Remi’s PHP 8.4:
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.4 -y
Install PHP 8.4 with common extensions:
sudo dnf install -y php php-cli php-fpm php-mysqlnd php-gd php-mbstring php-xml php-curl php-zip php-opcache php-bcmath php-intl php-soap
Verify PHP 8.4 is active:
php --version
The output should confirm PHP 8.4 from the Remi repository:
PHP 8.4.5 (cli) (built: Mar 12 2026 01:55:56) (NTS gcc x86_64)
Copyright (c) The PHP Group
Built by Remi's RPM repository #StandWithUkraine
Zend Engine v4.4.5, Copyright (c) Zend Technologies
with Zend OPcache v8.4.5, Copyright (c), by Zend Technologies
Step 3: Review Installed PHP Extensions
List all loaded PHP modules to confirm extensions were installed correctly:
php -m
You should see modules like curl, gd, mbstring, mysqlnd, opcache, xml, and zip in the list. If any extension is missing, install it with:
sudo dnf install -y php-
The table below lists commonly needed PHP extensions and their purpose:
| Extension | Purpose |
|---|---|
php-mysqlnd | MySQL/MariaDB native driver for database connections |
php-gd | Image processing (thumbnails, watermarks, captchas) |
php-mbstring | Multibyte string handling for UTF-8 content |
php-xml | XML parsing and manipulation |
php-curl | HTTP client for API calls and remote requests |
php-zip | ZIP archive compression and extraction |
php-opcache | Bytecode cache for PHP performance |
php-bcmath | Arbitrary precision mathematics |
php-intl | Internationalization (formatting, transliteration) |
php-soap | SOAP protocol support for web services |
For applications like WordPress on Nginx, the extensions above cover all requirements. Framework-specific apps may need additional extensions – check your application’s documentation.
Step 4: Configure PHP-FPM with Nginx
PHP-FPM (FastCGI Process Manager) is the recommended way to run PHP behind Nginx. It manages worker processes, handles request queuing, and provides process-level isolation.
Configure PHP-FPM pool
Open the default PHP-FPM pool configuration:
sudo vi /etc/php-fpm.d/www.conf
Update these settings to run PHP-FPM as the nginx user and use a Unix socket for better performance:
; Run as nginx user for proper file permissions
user = nginx
group = nginx
; Use Unix socket instead of TCP for lower latency
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
The pm.max_children value depends on your available RAM. Each PHP-FPM worker uses roughly 30-50 MB. For a server with 2 GB RAM, keep it at 20-30. For 4 GB or more, 50 is reasonable.
Configure Nginx to pass PHP requests to PHP-FPM
Create or edit an Nginx server block. Open the configuration file:
sudo vi /etc/nginx/conf.d/default.conf
Add the PHP-FPM location block inside your server section:
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 for syntax errors:
sudo nginx -t
A successful test shows:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Step 5: Tune php.ini for Production
The default php.ini ships with conservative values. For production web applications, adjust these key directives. Open the file:
sudo vi /etc/php.ini
Update these settings for a typical production web server:
; Memory and execution limits
memory_limit = 256M
max_execution_time = 300
max_input_time = 300
max_input_vars = 5000
; File upload limits
upload_max_filesize = 64M
post_max_size = 64M
; Error handling - log errors but don't display them to visitors
display_errors = Off
log_errors = On
error_log = /var/log/php-fpm/error.log
; Session security
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
; Timezone - set to your server's timezone
date.timezone = UTC
The table below explains each directive and its recommended production value:
| Directive | Recommended Value |
|---|---|
memory_limit | 256M (increase to 512M for heavy CMS like Magento) |
max_execution_time | 300 (seconds – prevents runaway scripts) |
upload_max_filesize | 64M (match your application’s upload needs) |
post_max_size | 64M (must be equal to or larger than upload_max_filesize) |
display_errors | Off (never expose errors to visitors in production) |
opcache.enable | 1 (enabled by default – dramatically improves performance) |
Configure OPcache for performance
OPcache stores precompiled PHP bytecode in shared memory, eliminating the need to parse scripts on every request. Open the OPcache configuration:
sudo vi /etc/php.d/10-opcache.ini
Set these values for production use:
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
Setting opcache.revalidate_freq=60 means PHP checks for file changes every 60 seconds. During active development, set this to 0 so changes take effect immediately.
Step 6: Start and Enable PHP-FPM
Enable PHP-FPM to start at boot and start the service:
sudo systemctl enable --now php-fpm
Restart Nginx to pick up the PHP-FPM configuration:
sudo systemctl restart nginx
Verify both services are running:
sudo systemctl status php-fpm nginx
Both services should show active (running). If PHP-FPM fails to start, check the log:
sudo journalctl -u php-fpm -e --no-pager
Step 7: Configure Firewall for Web Traffic
Open HTTP (port 80/TCP) and HTTPS (port 443/TCP) in the firewall to allow web traffic:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Confirm the rules are active:
sudo firewall-cmd --list-services
The output should include http and https in the list of allowed services.
Step 8: Configure SELinux for PHP-FPM
Rocky Linux 10 and AlmaLinux 10 run SELinux in enforcing mode by default. PHP-FPM needs specific SELinux booleans to function properly – especially if your application connects to a database or sends emails.
Allow PHP-FPM to connect to database servers (required for MySQL or MariaDB connections):
sudo setsebool -P httpd_can_network_connect_db 1
Allow PHP-FPM to make outbound network connections (needed for API calls, sending email, fetching remote content):
sudo setsebool -P httpd_can_network_connect 1
If your PHP application writes to directories outside the default web root, allow that with:
sudo setsebool -P httpd_unified 1
Verify the booleans are set:
getsebool httpd_can_network_connect_db httpd_can_network_connect httpd_unified
All three should show --> on in the output.
Step 9: Test PHP Processing
Create a test PHP file to confirm Nginx passes requests to PHP-FPM correctly:
echo "" | sudo tee /var/www/html/info.php
Open http://your-server-ip/info.php in a browser. You should see the PHP information page showing the installed version, loaded extensions, and configuration values. If you plan to deploy a full web application, follow our guide on installing Tomcat with SSL on RHEL/Rocky for a reference on setting up SSL certificates.
Remove the test file after verification – it exposes sensitive server details:
sudo rm -f /var/www/html/info.php
Step 10: Switch Between PHP Versions
If you installed PHP 8.4 from Remi and need to switch back to PHP 8.3 from AppStream (or vice versa), use the module system:
sudo dnf module reset php -y
sudo dnf module enable php:8.3 -y
sudo dnf distro-sync -y
To switch to a different Remi version, replace the stream name:
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.4 -y
sudo dnf distro-sync -y
After switching versions, restart PHP-FPM and verify:
sudo systemctl restart php-fpm
php --version
If you run web applications backed by a LEMP stack, test your application thoroughly after any PHP version change.
Conclusion
PHP is running on Rocky Linux 10 / AlmaLinux 10 – either 8.3 from AppStream or 8.4 from the Remi repository. PHP-FPM is configured with Nginx, common extensions are installed, and the firewall and SELinux policies are set for production use.
For a production deployment, add SSL/TLS certificates using Let’s Encrypt, set up log rotation for /var/log/php-fpm/, monitor PHP-FPM worker usage with tools like pm.status_path, and keep PHP updated with regular dnf update runs.