AlmaLinux

How To Install PHP 8.4 on Rocky / AlmaLinux 9|8

Install PHP 8 4 Rocky AlmaLinux

Remi’s php84 Software Collection runs PHP 8.4 on Rocky Linux and AlmaLinux 9 or 8 without touching the PHP that ships with the OS. It installs under /opt/remi/php84, gives you its own php84 command and php84-php-fpm service, and leaves the system php package alone. Apps pinned to the AppStream build keep working while you move others over.

Original content from computingforgeeks.com - post 158898

The steps below add EPEL and Remi, install PHP 8.4 with extensions, and show you how to prove the build is patched against PHP2Shell. If you would rather make PHP 8.4 the system default on EL10, the module stream guide for Rocky Linux 10 covers that route, and Ubuntu readers have a separate PHP 8.4 install for Ubuntu. Every command below was run on Rocky Linux 9 in October 2026 against Remi’s PHP 8.4.27 packages, and the install steps were repeated on AlmaLinux 8.

Add the EPEL and Remi repositories

Run this on a freshly provisioned Rocky Linux or AlmaLinux server when you can, rather than on a box already serving live traffic, so a dependency surprise never lands on production first. If you still need the server, our notes on installing Rocky Linux on a Hetzner root server get you there. CentOS Stream 8 is end of life and gets no updates at all, so put it on an EL9 or EL10 base before adding anything new to it.

Remi’s packages depend on libraries that only EPEL carries (libsodium, for one), and EPEL’s own instructions enable the CRB repository first (it is called PowerTools on EL8), because some EPEL packages need libraries from it. The config-manager subcommand comes from dnf-plugins-core, which a minimal install does not have, so install that too. Run the first line plus the one for your major version:

sudo dnf install -y dnf-plugins-core

## EL 9-based systems ##
sudo dnf config-manager --set-enabled crb

## EL 8-based systems ##
sudo dnf config-manager --set-enabled powertools

On our minimal Rocky Linux 9 server, config-manager failed with No such command: config-manager until dnf-plugins-core was installed, and then CRB showed up in the repolist. The PowerTools line is EPEL’s documented EL8 equivalent, which we did not run. With that done, install the EPEL release package.

sudo dnf -y install epel-release

Then install the Remi release package that matches your major version. Pick one line, not both:

## EL 9-based systems ##
sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm

## EL 8-based systems ##
sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpm

Confirm both repositories are active before going further. A failed remi-release install leaves dnf unable to find php84 later, and the error then points at the wrong step.

sudo dnf repolist

On Rocky Linux 9 you should see epel, remi-modular and remi-safe next to the base repositories:

repo id             repo name
appstream           Rocky Linux 9 - AppStream
baseos              Rocky Linux 9 - BaseOS
epel                Extra Packages for Enterprise Linux 9 - x86_64
epel-cisco-openh264 Extra Packages for Enterprise Linux 9 openh264 (From Cisco) - x86_64
extras              Rocky Linux 9 - Extras
remi-modular        Remi's Modular repository for Enterprise Linux 9 - x86_64
remi-safe           Safe Remi's RPM repository for Enterprise Linux 9 - x86_64

The remi-safe repository is the one that matters here, because it holds the php84 collection. Despite what older guides say, it is not a testing repository. It carries the stable Software Collections and is enabled by default, since its packages install side by side and never replace anything from the base OS. If it’s missing from your repolist, turn it on:

sudo dnf config-manager --set-enabled remi-safe

The same command enabled remi-safe cleanly on Rocky Linux 9 and AlmaLinux 8, although on both it was already on after the Remi release package went in.

Install PHP 8.4 on Rocky / AlmaLinux

Each PHP branch in remi-safe has its own metapackage named phpXY. List them to see which collections your server can install:

sudo dnf list --available "php8?"

Remi lists every collection from 8.0 to 8.6 on Rocky Linux 9, and AlmaLinux 8 showed the same list with el8 builds. Not all of them are good picks: php86 is a release candidate, and 8.0 and 8.1 are end of life upstream, so new work belongs on 8.4 or 8.5.

Available Packages
php80.x86_64                      8.0-3.el9.remi                       remi-safe
php81.x86_64                      8.1-4.el9.remi                       remi-safe
php82.x86_64                      8.2-5.el9.remi                       remi-safe
php83.x86_64                      8.3-1.el9.remi                       remi-safe
php84.x86_64                      8.4-1.el9.remi                       remi-safe
php85.x86_64                      8.5-1.el9.remi                       remi-safe
php86.x86_64                      8.6-1.el9.remi                       remi-safe

Install the PHP 8.4 collection. The php84 metapackage pulls in the CLI, the common files and the runtime, and its weak dependencies add FPM and the usual extensions, so one package name gives you a working base.

sudo dnf install php84

dnf resolves the transaction and asks you to confirm it. The block below is trimmed to the PHP packages and the EPEL and SCL libraries they need on Rocky Linux 9; the full dependency list depends on what your server already has, and a minimal install pulls in more:

Installing:
 php84                         x86_64  8.4-1.el9.remi          remi-safe  6.9 k
Installing dependencies:
 libsodium                     x86_64  1.0.18-9.el9            epel       160 k
 oniguruma5php                 x86_64  6.9.10-1.el9.remi       remi-safe  222 k
 php84-php-cli                 x86_64  8.4.27-1.el9.remi       remi-safe  3.9 M
 php84-php-common              x86_64  8.4.27-1.el9.remi       remi-safe  769 k
 php84-runtime                 x86_64  8.4-1.el9.remi          remi-safe  1.1 M
 scl-utils                     x86_64  1:2.0.3-4.el9           appstream   36 k
Installing weak dependencies:
 php84-php-fpm                 x86_64  8.4.27-1.el9.remi       remi-safe  2.0 M
 php84-php-mbstring            x86_64  8.4.27-1.el9.remi       remi-safe  535 k
 php84-php-opcache             x86_64  8.4.27-1.el9.remi       remi-safe  515 k
 php84-php-pdo                 x86_64  8.4.27-1.el9.remi       remi-safe   95 k
 php84-php-sodium              x86_64  8.4.27-1.el9.remi       remi-safe   41 k
 php84-php-xml                 x86_64  8.4.27-1.el9.remi       remi-safe  722 k

Answer y. On a first install dnf then asks to import the EPEL and Remi GPG keys (RPM-GPG-KEY-remi.el9 on EL9), and you have to accept those too, because a run that can’t import them stops with Refusing to automatically import keys when running unattended. Add -y to the install command if you’re scripting it.

Because this is a Software Collection, it stays separate from the base OS. Three paths are worth remembering:

  • The installation lives under /opt/remi/php84
  • Configuration files, including php.ini and the FPM pools, sit in /etc/opt/remi/php84
  • The FPM pool is configured to listen on /var/opt/remi/php84/run/php-fpm/www.sock

The collection does not add a plain php binary to your PATH, so call it as php84 when you check the version.

php84 --version

Rocky Linux 9 and AlmaLinux 8 both reported the same Remi build from 19 October, which is the patched release covered in the next section.

PHP 8.4.27 (cli) (built: Oct 19 2026 14:38:59) (NTS gcc x86_64)
Copyright (c) The PHP Group
Built by Remi's RPM repository <https://rpms.remirepo.net/> #StandWithUkraine #NoAI
Zend Engine v4.4.27, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.27, Copyright (c), by Zend Technologies

A command not found here means php84-php-cli never installed, so rerun the install and read the dnf error. A version below 8.4.27 means the server holds an older build, and the PHP2Shell section below shows how to fix that.

Enable PHP-FPM 8.4

The collection’s FPM service is what a web server talks to, and the package installs it disabled, so nothing serves PHP 8.4 over FastCGI until you start it. Enable it now so it also comes back after a reboot:

sudo systemctl enable --now php84-php-fpm

Then confirm the service is up:

systemctl is-active php84-php-fpm

It should answer with one word:

active

Anything else (inactive or failed) means the pool did not start, and sudo journalctl -u php84-php-fpm shows why. Skip this step only if you plan to run PHP through the collection’s Apache module instead of FPM.

Check PHP 8.4 for PHP2Shell (CVE-2026-109618, CVE-2026-109619)

PHP2Shell is the common name for a pair of critical remote code execution bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619, both rated CVSS v4.0 9.2 in PHP’s 20 October pre-announcement. They were fixed upstream on 21 October 2026 in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 according to the PHP security advisory. Remi’s php84 collection already ships 8.4.27 for EL9 and EL8, so a server you build from this guide today is patched. One built before that runs 8.4.26 or older until you upgrade it.

PHP’s 21 October advisory told Remi users to switch to distro packages, because Remi had no update out that day. Remi shipped 8.4.27 on 22 October, so upgrading the collection is now enough. If you’d rather follow the advisory and move to distro PHP, the fixed AppStream options are the php:8.2 and php:8.3 module streams on Rocky Linux 9 (its php:8.1 stream was still unfixed on 22 October) and every PHP stream on AlmaLinux 9 and 8. None of them is PHP 8.4, so check your application first.

With Remi the package version is the check, because its changelog only says “Update to 8.4.27” and never names the CVE IDs, so grepping it for them prints nothing even on a fixed build. Ask rpm instead:

rpm -q php84-php-common

Anything at 8.4.27 or later is fixed. Our fresh Rocky Linux 9 install printed:

php84-php-common-8.4.27-1.el9.remi.x86_64

On a fresh install you can stop here. On an existing server that shows 8.4.26 or older, upgrade the whole collection in one transaction and then restart PHP-FPM, because the FPM master keeps serving the old code from memory until it restarts. try-restart restarts the service only if it is running, so it is safe on a box where FPM is stopped:

sudo dnf upgrade -y "php84*"
sudo systemctl try-restart php84-php-fpm

If the server runs PHP through the collection’s Apache module instead, restart httpd too. We did not test the Apache module path. On our FPM-only server the command just reported Unit httpd.service not found, which is harmless:

sudo systemctl try-restart httpd

For an in-place upgrade php84 --version only proves the CLI, so check when the FPM service last started instead:

systemctl show -p ActiveEnterTimestamp php84-php-fpm

The timestamp must not be earlier than the end of the upgrade. An older one means FPM is still the pre-upgrade process, so restart it again and recheck.

ActiveEnterTimestamp=Thu 2026-10-22 16:11:31 UTC

dnf history list only shows the upgrade time to the minute, which is too coarse for that comparison. List the transactions, then open the newest Upgrade row by its ID (7 on our server, so use your own) to get the end time in seconds:

sudo dnf history list php84-php-common
sudo dnf history info 7

The list shows the downgrade we used to fake an old server, then the upgrade. Running the upgrade again with nothing to update printed Nothing to do and added no row, so the newest Upgrade row is always a real one:

ID     | Command line             | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
     7 | upgrade -y php84*        | 2026-10-22 16:11 | Upgrade        |    8   
     6 | downgrade -y php84-php*  | 2026-10-22 16:11 | Downgrade      |    8   
     5 | install -y php84         | 2026-10-22 16:10 | Install        |   35 EE

The info output carries the exact times. FPM’s 16:11:31 start matches the end of the transaction, so the running FPM is the patched code:

Transaction ID : 7
Begin time     : Thu Oct 22 16:11:30 2026
Begin rpmdb    : 72bf32bfcec974470623bd3f75f9cd27135551b3e80e5cdcc4fad22e9a84d1bd
End time       : Thu Oct 22 16:11:31 2026 (1 seconds)

A quicker cross-check is needs-restarting, which lists services still running deleted or replaced files. Empty output means nothing is left to restart:

sudo dnf needs-restarting -s

We rolled our Rocky Linux 9 server back to 8.4.26 and then started FPM on it to reproduce an unpatched box, which is the downgrade row above. The upgrade took a few seconds, and a PHP page served through the FPM socket answered 8.4.26 fpm-fcgi before it and 8.4.27 fpm-fcgi after the restart. The package restarted php84-php-fpm during the transaction in our test; restart anyway and confirm with the checks above. The other branches in remi-safe carry the fix too (8.5.12, 8.3.36, 8.2.35, plus backports for 8.1, 8.0 and 7.4), and if you are stuck on one of those older branches, our PHP2Shell notes for end-of-life PHP cover what else to check.

Install PHP 8.4 Extensions

Extensions for the collection are named php84-php-<extension>, and the repository carries more than 200 of them. List what is available.

sudo dnf list --available "php84-php-*"

As an example, install the mysqlnd and zip extensions. The zip name resolves to Remi’s php84-php-pecl-zip package, so either name works.

sudo dnf install php84-php-mysqlnd php84-php-zip

List the loaded modules to confirm both are active. The CLI and FPM read the same php.d directory under /etc/opt/remi/php84, so what loads here also loads in FPM once the service restarts.

php84 --modules

You should see mysqli, mysqlnd, pdo_mysql and zip in the list:

[PHP Modules]
bz2
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gettext
hash
iconv
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
random
readline
Reflection
session
SimpleXML
sockets
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
xsl
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache

FPM reads new extensions only when it starts, so run sudo systemctl try-restart php84-php-fpm after adding one. Your Nginx or Apache FastCGI config then points at the /var/opt/remi/php84/run/php-fpm/www.sock socket, which we confirmed answers PHP 8.4 requests on Rocky Linux 9. If PHP 8.4 is the only PHP the server will ever run, Remi’s php:remi-8.4 module stream gives you a plain php command and standard paths on EL9 and EL8, the same route the Rocky Linux 10 guide linked above takes. For PHP 8.5, our PHP 8.5 guide for Rocky Linux 10 covers it. When you need several branches side by side, or the base OS PHP must stay put, the Remi collection is the one we’d run.

Keep reading

PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP Php PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP PHP2Shell on End-of-Life PHP 8.1, 8.0 and 7.4 (WHMCS, ionCube) Php PHP2Shell on End-of-Life PHP 8.1, 8.0 and 7.4 (WHMCS, ionCube) Patch PHP2Shell (CVE-2026-109618) on Ubuntu 26.04 / 24.04 / 22.04 Php Patch PHP2Shell (CVE-2026-109618) on Ubuntu 26.04 / 24.04 / 22.04 Best Monitor Arms for a Multi-Monitor Developer Desk Programming Best Monitor Arms for a Multi-Monitor Developer Desk Best Mouse and Keyboard for Programming Programming Best Mouse and Keyboard for Programming Best Node.js Books for 2026: Express, Fastify and NestJS Books Best Node.js Books for 2026: Express, Fastify and NestJS

Leave a Comment

Press ESC to close