Introduction
Hi everyone!
I recently ran into a critical issue while managing a staging environment on AlmaLinux 9, running PHP via the Remi repository and served by Apache. After a routine dnf update
, all my CLI-based PHP scripts broke. Miraculously, my web server didn’t go down, but this experience taught me some important lessons about package management in RedHat-based systems.
Here’s the story of what happened, why it happened, and my ongoing steps to recovery.
Background
- OS: AlmaLinux 9 (RHEL-compatible)
- Web server: Apache
- PHP: Installed from the Remi repository – not AlmaLinux’s built-in version
- Usage: Both web (served by Apache) and CLI batch jobs use PHP extensively
The Incident
All my PHP-based batch jobs suddenly failed with cryptic errors such as:
Call to undefined function pg_connect()
Class PDO not found
The lucky part:
The web server (Apache) kept running and serving PHP just fine. If Apache had been restarted, it likely would’ve been affected too, but I dodged that bullet—for now.
Initial Troubleshooting
1. Check the PHP CLI
php --version
php -m | grep pgsql
php -i | grep PDO
Result:
CLI PHP was missing all key extensions I rely on, including pdo
and pgsql
.
2. Check which PHP binary is active
It turned out that /usr/bin/php
was now the default AlmaLinux PHP, installed from the official repository—with hardly any extensions.
But /opt/remi/php81/root/bin/php
(Remi’s version) was still present and contained all the required extensions.
3. Double-check recent changes
Reviewing automation and update logs, I discovered:
Ansible had executed a
dnf update
(full system upgrade).
This means all system packages—including PHP—got upgraded, with AlmaLinux’s official repositories often “winning” over Remi, replacing the carefully configured PHP stack.
What Was (and Wasn’t) Broken
- All CLI-based PHP scripts were dead due to missing extensions.
- Apache kept serving PHP pages. The web wasn’t affected (yet) since Apache hadn’t been restarted and still used the loaded Remi PHP module.
- Other possible dependency issues could appear, depending on what else was touched by
dnf update
.
Steps Toward Recovery
1. Locate and test the Remi PHP binary
/opt/remi/php81/root/bin/php --version
/opt/remi/php81/root/bin/php -m | grep pgsql
Confirmed: everything is still in place with Remi’s PHP.
2. Restore the system PHP symlink
Point the system’s php
command (e.g., /usr/bin/php
) back to Remi’s PHP for CLI use:
sudo ln -sf /opt/remi/php81/root/bin/php /usr/bin/php
Check with which php
that the change is effective.
Now, CLI PHP is mostly working again—as a temporary workaround!
3. Proper Clean-up (A Work in Progress)
At the time of writing, I am still working through the full clean-up process.
Here’s the plan I’m following:
-
Remove any official AlmaLinux PHP packages that were installed by
dnf update
:
dnf remove php php-cli php-common # ...and any others that don't belong
-
Reinstall Remi PHP core and all required extensions:
dnf install php81 php81-php-cli php81-php-pgsql php81-php-pdo # and whatever else you require
Verify that Apache is configured to use Remi’s PHP module, and restart Apache only after the above is done.
Double-check all settings and run tests to ensure CLI and web parity.
I’ll update this post with final steps and results once the proper fix is fully in place!
Why Did This Happen? (And How to Prevent It)
- On AlmaLinux and other RHEL derivatives,
dnf update
upgrades ALL packages from ALL enabled repositories. - This is not like
apt update
on Debian/Ubuntu, which only updates package lists (and requiresapt upgrade
to actually change any package versions). - Distro default repositories can override custom builds (like Remi) if you’re not careful.
- If possible, add a
exclude=php*
line to yourdnf.conf
or explicitly scope which packages to upgrade. - With automation (Ansible, CI, etc.), never blindly run a global
dnf update
—always specify only the packages you want managed.
Conclusion & Takeaways
-
dnf update
is powerful and dangerous in custom environments—use with extreme caution. - Apache might survive—for a while—but system-level PHP (CLI) can break immediately if binary paths change.
- Restoring the correct symlink is only a temporary fix; the real solution is to remove conflicting packages and ensure everything is installed from the intended repo.
- Regularly check which
php
you’re running (which php
) and what extensions are available (php -m
), especially after any updates. - Update your automation and deployment playbooks to avoid this mess in the future.
If this happens to you:
Symlink back to Remi’s PHP, clean up conflicting packages, and don’t use dnf update
like you’d use apt update
!
Top comments (0)