AlmaLinux and Rocky Linux focus on stability, so the PHP versions in their own repositories are often older than what modern apps require. The Remi repository, maintained by a long-time Fedora and PHP packager, provides current PHP builds for these systems. This guide enables it, installs PHP-FPM from a module stream, and adds extra versions alongside when you need more than one.
Before you start
- A Linux VPS running AlmaLinux or Rocky Linux 8 or 9, with a sudo user. Check your release:
cat /etc/redhat-release- SSH access: Connect to your Linux VPS with SSH.
- A web server, either Nginx or Apache (
httpd), if you will serve PHP sites. You can also install it afterwards.
Note: Remi supports specific PHP versions for each OS release, and that list changes as versions reach end of life. Run dnf module list php after enabling the repository to see what is offered on your server.
Enable EPEL and the extra repositories
Remi depends on packages from EPEL, which in turn needs the CodeReady Builder (CRB) repository on version 9, called PowerTools on version 8.
AlmaLinux and Rocky Linux 9
sudo dnf install -y dnf-plugins-core epel-release
sudo dnf config-manager --set-enabled crb
sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpmAlmaLinux and Rocky Linux 8
sudo dnf install -y dnf-plugins-core epel-release
sudo dnf config-manager --set-enabled powertools
sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpmAccept the GPG key prompts when dnf asks. They come from the EPEL and Remi repositories you just added.
Choose a PHP module stream
On these systems PHP is delivered as a module with several streams, one per version. List them:
sudo dnf module list phpYou will see the OS streams (for example 8.1 or 8.2) and Remi streams named like remi-8.3 and remi-8.4. Only one stream can be enabled at a time.
Reset any stream that is already enabled, then enable the one you want:
sudo dnf module reset -y php
sudo dnf module enable -y php:remi-8.3Install PHP-FPM and extensions
sudo dnf install -y php-fpm php-cli php-common php-mysqlnd php-gd php-mbstring php-xml php-intl php-opcache php-pecl-zip php-bcmathExtension package names on these systems differ from Debian. For example, MySQL support is php-mysqlnd, and PECL extensions such as Redis or Imagick are php-pecl-redis (check the exact name with dnf search php-pecl).
Start PHP-FPM and enable it at boot:
sudo systemctl enable --now php-fpm
php -vConnect PHP-FPM to your web server
The default pool is /etc/php-fpm.d/www.conf. Its key settings are:
user = apache
group = apache
listen = /run/php-fpm/www.sock
listen.acl_users = apache,nginx- Apache (
httpd): the package adds/etc/httpd/conf.d/php.conf, which sends.phpfiles to this socket. Restarthttpdand PHP works. - Nginx: the package adds
/etc/nginx/conf.d/php-fpm.confwith an upstream calledphp-fpm, and/etc/nginx/default.d/php.conf. In your own server blocks, point PHP at the socket directly:
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/www.sock;
}If only Nginx runs on the server, change user and group in the pool to nginx, so file ownership is consistent. Then restart PHP-FPM.
SELinux in enforcing mode allows the web server to use this socket by default. If your site's files live outside /var/www, label them correctly as explained in SELinux basics.
Run more than one PHP version
The module stream sets the default PHP. For other versions, Remi provides separately named packages that install under /opt/remi, so they do not conflict:
sudo dnf install -y php82-php-fpm php82-php-cli php82-php-mysqlnd php82-php-gd php82-php-mbstring php82-php-xml php82-php-intl php82-php-opcache
sudo systemctl enable --now php82-php-fpmEach extra version has its own:
- Service:
php82-php-fpm - CLI command:
php82 - Pool config:
/etc/opt/remi/php82/php-fpm.d/www.conf - php.ini:
/etc/opt/remi/php82/php.ini - Socket:
/var/opt/remi/php82/run/php-fpm/www.sock
Point a site at that socket path to run it on PHP 8.2 while the rest of the server uses the default version.
Check it works
php -v
php -m | grep -E "mysqlnd|mbstring|Zend OPcache"
systemctl status php-fpm --no-pager
ls -l /run/php-fpm/The version should match the stream you enabled, the modules should be listed, the service should be active (running) and the socket should exist.
For a web test, create /var/www/html/info.php containing <?php echo PHP_VERSION; and open it in a browser. Delete it right after.
Troubleshooting
- "Modular dependency problems" or a conflict during install: another stream is still enabled. Run
sudo dnf module reset -y phpand enable the stream again. epel-releaseinstalls but packages are missing: CRB (9) or PowerTools (8) is not enabled. Run theconfig-managercommand for your version.- 502 or "File not found" from Nginx: the socket path or
SCRIPT_FILENAMEis wrong, or the pool'slisten.acl_usersdoes not includenginx. - Permission denied writing uploads with SELinux on: the folder needs the
httpd_sys_rw_content_tlabel. See Fix SELinux denials.
Next steps
- Size PHP-FPM workers to your RAM: Tune PHP-FPM pools (pm.max_children).
- Install a web server on the same system: Install Nginx on AlmaLinux and Rocky Linux.
