OneLinersCommand workbench
Guides
Services & Applications / Packages & Updates

Install PHP 8.5 from Remi on RHEL, AlmaLinux, or Rocky Linux

Enable EPEL, CRB or CodeReady Builder, and the official Remi repository; switch the system PHP module to 8.5; install FPM and verify the exact runtime.

35 min8 stepsChanges system stateRevision 2
Save or explore
Save to collectionCreate a collection in the sidebar first.
0 of 8 steps completed
Goal

Obtain a maintained PHP 8.5 system runtime when the base Enterprise Linux repositories provide an older branch, without mixing arbitrary RPM sources.

Supported environments
  • RHEL 8, 9, 10
  • AlmaLinux / Rocky Linux 8, 9, 10
  • PHP 8.5
Prerequisites
  • Supported host and recovery access Use a supported distribution, keep an independent root-capable session, and record the current package repositories before changing the PHP runtime.cat /etc/os-release && uname -m
  • Application compatibility Confirm the application, framework, extensions, and deployment tooling explicitly support the target PHP branch.
  • Configuration backup Archive the active PHP, web-server, and application configuration before packages, pools, or handlers change.
Operating boundary

OneLiners never runs these steps or stores secrets. Review placeholders, versions, current state, and change-control requirements before using a command.

Full guide

What you will build

System
  • A PHP 8.5 system runtime on a supported RHEL, AlmaLinux, or Rocky Linux 8–10 host using Fedora EPEL, the distribution's CodeReady Builder/CRB repository, and the official Remi release package and module stream.
  • A reviewed package transaction that moves the system PHP family together, installs only an explicit baseline of CLI, FPM, OPcache and application-required extensions, and preserves a configuration/package inventory for rollback.
  • An enabled but not yet publicly connected `php-fpm` service with exact version, configuration-file, syntax, service, extension and package-repository provenance evidence.
Observable outcome
  • The platform gate reports a supported distribution major and x86_64/aarch64 architecture; EPEL, CodeReady Builder/CRB and Remi repositories are enabled through their official packages or tools.
  • `php -v` reports 8.5.x, `php-fpm -t` succeeds, the systemd service is active, required modules are visible, and DNF identifies the installed PHP packages as coming from the intended Remi stream.
  • The application compatibility decision, pre-change configuration/archive/package list, transaction review, rollback stream, handler cutover and post-install security work are documented rather than hidden inside a blind package install.

Architecture

How the parts fit together

Enterprise Linux supplies BaseOS/AppStream and a builder repository. Fedora EPEL and Remi add dependencies and the PHP 8.5 packages. Installing `remi-release-<major>.rpm` adds signed repository definitions; selecting `php:remi-8.5/common` tells DNF modular dependency solving to treat Remi's PHP family as the active system stream. Unprefixed packages such as `php-cli` and `php-fpm` then replace or upgrade the system PHP branch together. The CLI reads `/etc/php.ini` plus `/etc/php.d`, while `php-fpm` runs as a separate systemd service and pool configuration. This guide stops before Apache/nginx traffic is connected because handler selection, pool identity, application configuration and deployment verification are separate production boundaries.

BaseOS and AppStreamProvide the supported Enterprise Linux base and package-management framework.
CodeReady Builder or CRBSupplies additional dependencies required by EPEL/Remi; Red Hat does not support CRB content itself.
Fedora EPELAdds Extra Packages for Enterprise Linux and the supported CRB helper used by compatible distributions.
Remi release repositoryInstalls repository definitions and signed metadata for maintained PHP branches.
php:remi-8.5 module streamSelects a coherent system-wide PHP 8.5 package family for DNF4-based Enterprise Linux.
PHP CLI and PHP-FPMProvide command-line/runtime inspection and a web-server-facing FastCGI service with independent configuration validation.
  1. The operator proves distribution, major version and architecture before constructing any repository URL.
  2. Current PHP packages, stream, extensions, repositories and configuration are archived as rollback evidence.
  3. Official EPEL plus builder repositories satisfy dependencies; the official Remi release package adds Remi metadata and signing configuration.
  4. DNF previews and then switches the PHP family to `remi-8.5`, resolving a coherent transaction instead of mixing individual RPM files.
  5. The required runtime/extension baseline is installed, FPM is validated and started, and version/configuration/repository evidence is captured before any web handler changes.

Assumptions

  • The host is RHEL, AlmaLinux, or Rocky Linux major 8, 9, or 10 on x86_64/aarch64, has working trusted DNS/TLS/time, and its lifecycle and support policy permit EPEL plus Remi packages.
  • RHEL is registered with a valid entitlement when `subscription-manager` is required. Clone hosts provide the EPEL `crb` helper or an equivalent documented CRB repository.
  • Application owners have confirmed PHP 8.5 support for the framework, Composer dependencies, extensions, encoders/agents and deployment tooling using a clone or staging environment.
  • An independent root-capable session, maintenance window, host/application backup and tested rollback are available. This is a system-stream replacement, not a side-by-side installation.
  • The web server is not automatically pointed at the new FPM service by this guide; pool identity, socket permissions, handler scope and real application acceptance are completed separately.

Key concepts

system stream
A selected modular package family whose unprefixed names replace the distribution PHP branch system-wide; it affects CLI, FPM and extension dependencies together.
Remi SCL
A separate prefixed package layout such as `php85-php-*` under `/opt/remi`; use the parallel-install guide when the system PHP must remain unchanged.
EPEL
Fedora's Extra Packages for Enterprise Linux repository, used here only through its official release package for the detected major version.
CodeReady Builder / CRB
A repository with additional build/runtime dependencies. RHEL calls it CodeReady Builder; compatible distributions commonly expose CRB.
module switch-to
A DNF operation that changes an enabled module stream and synchronizes installed packages with the target stream rather than enabling a name only.
package provenance
Evidence of which repository supplied an installed NEVRA package, checked with DNF rather than inferred from a binary version string.
PHP-FPM
A long-running FastCGI process manager used by web servers; installing and starting it does not safely configure a site handler by itself.

Security and production boundaries

  • Adding EPEL and Remi expands the software supply chain. Use only HTTPS official release packages, retain RPM signature checking, inspect repository files/keys, and never disable `gpgcheck` to bypass a failure.
  • PHP 8.5 compatibility must include native extensions, monitoring/security agents and Composer dependencies. An extension missing from the target repository is a stop condition, not a reason to download an arbitrary RPM.
  • Do not expose a `phpinfo()` page or point all virtual hosts at the new default FPM pool. Build a dedicated pool/handler and a minimal authenticated health check, then remove test scripts.
  • A successful CLI version does not prove FPM configuration, web-handler isolation, SELinux access, socket permissions, application migrations, or rollback safety.
  • Third-party repository packages may change the vendor support boundary for the host. Record the decision and lifecycle owner before production installation.

Stop before continuing if

  • Stop if the distribution/major/architecture is unsupported, RHEL is unregistered, repository TLS/signature checks fail, official repository IDs cannot be identified, or the host has mixed/conflicting RPM sources.
  • Do not switch streams until application/extension compatibility, transaction preview, configuration backup, package inventory, maintenance ownership and rollback stream are documented.
  • Stop if DNF proposes removing unrelated applications, critical extensions have no PHP 8.5 build, dependency resolution requires disabling GPG checks, or available disk/inode capacity is insufficient.
  • Do not connect production traffic until FPM syntax/service, dedicated pool/handler, SELinux/socket permissions, application health, logs and rollback are verified.
01

instruction

Identify the exact Enterprise Linux release

read-only

Choose repository URLs and the builder repository for the detected major version; stop unless the host is RHEL, AlmaLinux, or Rocky Linux 8–10 on an architecture published by Remi.

Why this step matters

Repository URLs and dependency repositories are major-version and architecture specific, so a hard platform gate prevents a plausible-looking command from installing the wrong release package.

What to understand

Source `/etc/os-release`, derive the numeric major without trusting free-form display text, and print architecture explicitly.

The case statement accepts only RHEL, AlmaLinux and Rocky Linux 8–10 on Remi-published x86_64/aarch64. It exits before any network or package mutation on other systems.

Cloud images and compatible derivatives can differ in repository management; they need their own reviewed guide rather than weakening this guard.

System changes

  • No persistent change; reads operating-system identity and machine architecture and exits nonzero for unsupported combinations.

Syntax explained

. /etc/os-release
Loads distribution-maintained identity variables into the current shell.
${VERSION_ID%%.*}
Removes the first dot and everything after it to derive the major release.
uname -m
Reports kernel machine architecture used to select published packages.
case ... exit 1
Fails closed when the exact distribution-major-architecture tuple is outside scope.
Command
. /etc/os-release; EL_MAJOR="${VERSION_ID%%.*}"; ARCH="$(uname -m)"; printf 'id=%s major=%s version=%s arch=%s\n' "$ID" "$EL_MAJOR" "$VERSION_ID" "$ARCH"; case "$ID:$EL_MAJOR:$ARCH" in rhel:[89]:x86_64|rhel:10:x86_64|rhel:[89]:aarch64|rhel:10:aarch64|almalinux:[89]:x86_64|almalinux:10:x86_64|almalinux:[89]:aarch64|almalinux:10:aarch64|rocky:[89]:x86_64|rocky:10:x86_64|rocky:[89]:aarch64|rocky:10:aarch64) ;; *) printf 'Unsupported platform for this guide\n' >&2; exit 1;; esac
Example output / evidence
id=almalinux major=10 version=10.0 arch=x86_64

Checkpoint: Checkpoint: inspect platform

Continue whenThe output shows one supported ID, major 8–10, full version, and x86_64 or aarch64; unsupported hosts stop before repository work.

Stop whenID, major or architecture is unexpected, the host is an in-place-upgrade hybrid, or lifecycle/support ownership is unclear.

If this step fails

A seemingly compatible Enterprise Linux derivative is rejected.

Likely causeThis guide deliberately supports only tested IDs and repository-management paths.

Safe checks
  • cat /etc/os-release
  • rpm -E %rhel
  • uname -m

ResolutionUse that distribution's official instructions and a separately validated procedure; do not edit the guard blindly.

Security notes

  • Failing closed prevents an attacker-controlled or mistaken URL/version substitution from changing the host supply chain.

Alternatives

  • Use Remi's official configuration wizard manually for another explicitly supported distribution and record a separate reviewed runbook.

Stop conditions

  • ID, major or architecture is unexpected, the host is an in-place-upgrade hybrid, or lifecycle/support ownership is unclear.
02

instruction

Inventory the current PHP runtime and repositories

read-only

Capture the current package, module stream, extensions, and enabled repositories so rollback does not depend on memory.

Why this step matters

The installed binary, module selection, package set and enabled repositories are all needed to assess blast radius and construct a rollback; `php -v` alone omits most of that state.

What to understand

A missing `php` binary is acceptable and printed as such, but the module/repository inventory must still succeed.

Record installed `php*` NEVRAs and provenance separately before the mutation even though the quick command displays the human-oriented stream/repository state.

Identify web handlers and services before installation so starting a new FPM unit cannot accidentally compete for a socket.

System changes

  • No persistent change; reads current PHP version, module streams, enabled repositories, packages and service context.

Syntax explained

php -v 2>/dev/null || true
Records a current CLI when present without failing a clean host.
dnf module list php
Displays available, enabled and installed PHP module streams.
dnf repolist --enabled
Lists repositories currently allowed to satisfy transactions.
Command
php -v 2>/dev/null || true; sudo dnf module list php; sudo dnf repolist --enabled
Example output / evidence
The installed branch, active stream, and repository IDs are recorded.

Checkpoint: Checkpoint: inventory runtime

Continue whenThe current branch/absence, selected stream, installed package family, handlers and all enabled repository IDs are saved as pre-change evidence.

Stop whenPackages come from unknown/mixed repositories, DNF reports damage, current handler/socket ownership is unknown, or rollback stream cannot be identified.

If this step fails

DNF shows modular filtering or duplicate PHP packages from several repositories.

Likely causeA prior third-party repository, manual RPM or incomplete stream change already mixed the runtime.

Safe checks
  • sudo dnf check
  • dnf repoquery --installed --qf '%{name} %{evr} %{repoid}' 'php*' | sort

ResolutionRepair and document the existing package state before introducing Remi; do not stack another repository over unresolved damage.

Security notes

  • Repository inventory is supply-chain evidence; store it with the change record and flag any disabled signature checking.

Alternatives

  • Collect the same NEVRA, stream, repo, service, socket and config evidence through signed configuration-management inventory.

Stop conditions

  • Packages come from unknown/mixed repositories, DNF reports damage, current handler/socket ownership is unknown, or rollback stream cannot be identified.
03

instruction

Back up PHP and web-server configuration

caution

Preserve configuration and package inventory before changing the system module stream.

Why this step matters

Module switching can replace default configuration and make old directives incompatible, so both files and exact package inventory are required for a controlled return to the prior runtime.

What to understand

Archive only existing PHP/web-server configuration paths, inspect the archive, store its checksum, and protect it root-only. A suppressed missing-path warning is not proof of a good backup.

The RPM list records extensions whose names may not be obvious from application configuration. Add application releases, database state and secrets through their established backup system.

Test restore on a clone or snapshot. A tarball on the same failing disk is rollback convenience, not a disaster-recovery backup.

System changes

  • Creates a timestamped root-only configuration archive and `/root/php-packages-before.txt`; it does not change installed packages or running services.

Syntax explained

tar -C / -czf
Creates a compressed archive with filesystem-root-relative paths.
2>/dev/null || true
Allows optional absent web-server paths but requires the operator to inspect the resulting archive explicitly.
rpm -qa 'php*' | sort
Records the complete installed PHP package-name/version set.
tee /root/php-packages-before.txt
Stores deterministic rollback inventory under root control.
Command
sudo tar -C / -czf /root/php-before-remi-$(date +%F-%H%M).tgz etc/php.ini etc/php.d etc/php-fpm.d etc/httpd etc/nginx 2>/dev/null || true; rpm -qa 'php*' | sort | sudo tee /root/php-packages-before.txt
Example output / evidence
/root/php-before-remi-2026-07-25-1200.tgz

Checkpoint: Checkpoint: backup config

Continue whenA non-empty protected archive lists all existing relevant configuration, its checksum is retained, and the package inventory has the exact prior extension set.

Stop whenArchive is missing/empty, required configuration is absent from it, application/database backup is untested, or no independent recovery session exists.

If this step fails

The archive command prints a filename but required configuration is missing.

Likely causeOptional-path suppression hid absent directories, configuration lives elsewhere, or the current runtime is a parallel/custom build.

Safe checks
  • php --ini
  • sudo tar -tvzf /root/php-before-remi-*.tgz | less
  • rpm -ql php-common | grep /etc

ResolutionDiscover the real configuration paths, rebuild and verify the archive, and document the runtime layout before package changes.

Security notes

  • Configuration archives may contain database credentials, TLS keys or environment values; store mode 0600 and never attach them unredacted.

Alternatives

  • Use an application-consistent VM snapshot plus versioned configuration/package manifests when its restore has been rehearsed and retention is protected.

Stop conditions

  • Archive is missing/empty, required configuration is absent from it, application/database backup is untested, or no independent recovery session exists.
04

command

Enable EPEL and the distribution builder repository

caution

Install the Fedora EPEL release package for the detected major version, then enable CodeReady Builder on registered RHEL or use the CRB helper on compatible clones because Remi dependencies may come from it.

Why this step matters

Remi packages rely on dependencies outside the minimal base; configuring official EPEL and the distribution's builder repository first makes the dependency graph explicit and reviewable.

What to understand

The EPEL release URL is constructed only after the platform gate and points to Fedora infrastructure for the exact EL major.

Registered RHEL uses `subscription-manager` and an architecture-specific CodeReady Builder ID. AlmaLinux/Rocky follow Remi's current `crb install` helper path.

List enabled repository IDs after mutation. Repository availability is not permission to install arbitrary packages from them.

System changes

  • Installs the EPEL repository-release package and enables CodeReady Builder/CRB, changing DNF repository configuration and trusted package sources.

Syntax explained

epel-release-latest-${EL_MAJOR}.noarch.rpm
Selects Fedora's EPEL repository definition for the detected major independent of CPU architecture.
subscription-manager repos --enable
Enables entitled CodeReady Builder content on RHEL.
crb install
Uses the current Remi-documented helper path to configure CRB on supported compatible distributions.
dnf repolist --enabled
Provides concrete post-change repository evidence.
Command
. /etc/os-release; EL_MAJOR="${VERSION_ID%%.*}"; sudo dnf install -y "https://dl.fedoraproject.org/pub/epel/epel-release-latest-${EL_MAJOR}.noarch.rpm"; if [ "$ID" = rhel ]; then sudo subscription-manager repos --enable "codeready-builder-for-rhel-${EL_MAJOR}-$(arch)-rpms"; else sudo crb install; fi; sudo dnf repolist --enabled | grep -Ei 'epel|codeready|crb'
Example output / evidence
codeready-builder-for-rhel-10-x86_64-rpms
epel

Checkpoint: Checkpoint: enable prerepositories

Continue whenOfficial EPEL and the matching CodeReady Builder/CRB repository IDs are enabled alongside the expected base repositories.

Stop whenTLS/signature verification fails, RHEL entitlement is absent, helper/repository ID is unknown, or enabling the repository would violate support policy.

If this step fails

CodeReady Builder/CRB cannot be enabled.

Likely causeRHEL is unregistered, architecture/major ID is wrong, EPEL helper is unavailable, or the clone names its repository differently.

Safe checks
  • subscription-manager status 2>/dev/null || true
  • sudo dnf repolist all | grep -Ei 'codeready|crb'
  • rpm -q epel-release

ResolutionUse the official distribution repository-management path for the detected host and confirm the exact enabled ID; do not substitute an unrelated mirror.

Security notes

  • Never use `--nogpgcheck`, HTTP mirrors, copied `.repo` files, or a broad third-party bootstrap script to bypass a repository failure.

Alternatives

  • Use the distribution-supported PHP stream or a pre-approved internally mirrored/signed repository when external EPEL/Remi access is prohibited.

Stop conditions

  • TLS/signature verification fails, RHEL entitlement is absent, helper/repository ID is unknown, or enabling the repository would violate support policy.
05

command

Install the Remi release package for the detected major version

caution

Use the official rpms.remirepo.net release package and inspect repository state immediately afterward.

Why this step matters

The official Remi release RPM adds repository definitions and signing material for one EL major; installing it as a package makes the supply-chain change visible, versioned and removable.

What to understand

`rpm -E %rhel` is evaluated by the RPM stack after the OS gate and determines the release-package URL. Inspect the downloaded package signature/repository files where policy requires approval.

Listing all `remi` IDs shows safe, modular and versioned channels, but does not prove the desired stream is selected.

Keep default GPG verification. If metadata or signatures fail, repair trust/time/proxy rather than weakening verification.

System changes

  • Installs `remi-release-<major>` and adds `/etc/yum.repos.d/remi*.repo` plus trusted signing configuration; it does not yet switch PHP.

Syntax explained

rpm -E %rhel
Uses the RPM macro for the Enterprise Linux major.
https://rpms.remirepo.net/enterprise/
Uses Remi's official repository host.
dnf repolist all
Displays enabled and disabled Remi repository definitions after installation.
Command
EL_MAJOR="$(rpm -E %rhel)"; sudo dnf install -y "https://rpms.remirepo.net/enterprise/remi-release-${EL_MAJOR}.rpm"; sudo dnf repolist all | grep -E '^remi'
Example output / evidence
remi-safe and versioned Remi repositories are listed.

Checkpoint: Checkpoint: install remi

Continue whenThe installed release package matches the host major, signature verification succeeds, and expected Remi repository IDs are visible without unknown duplicates.

Stop whenThe URL redirects outside approved infrastructure, signature validation fails, release major differs, repository files disable GPG checks, or conflicting Remi definitions already exist.

If this step fails

The Remi release RPM conflicts with an existing repository package.

Likely causeA previous/manual Remi configuration or another vendor package owns the same paths.

Safe checks
  • rpm -q remi-release
  • rpm -V remi-release
  • sudo grep -R -nE '^(\[remi|gpgcheck|baseurl|mirrorlist)' /etc/yum.repos.d

ResolutionReconcile the existing official package/configuration and verify ownership; do not force-overwrite repository files.

Security notes

  • A repository release package changes future software trust and update behavior; treat its files, keys and lifecycle as production configuration.

Alternatives

  • Use a security-reviewed internal mirror that preserves Remi signatures, metadata and update cadence.

Stop conditions

  • The URL redirects outside approved infrastructure, signature validation fails, release major differs, repository files disable GPG checks, or conflicting Remi definitions already exist.
06

command

Switch the system PHP module to Remi 8.5

caution

Use DNF module switching so dependencies move together; review the transaction before accepting it on production.

Why this step matters

The system runtime must move as a coherent package family. `switch-to` synchronizes installed PHP packages with the selected 8.5 stream instead of mixing individual versions and ABIs.

What to understand

First run the same command with `--assumeno` and capture removals, upgrades, downgrades, repository sources, download size and extension compatibility.

The quick path's `-y` is appropriate only after that review and an approved maintenance window. Open sessions/processes keep old code until restarted.

A missing extension or unrelated removal is a hard stop. The parallel SCL guide is safer when one application alone needs PHP 8.5.

System changes

  • Changes the enabled PHP module stream and synchronizes installed unprefixed PHP packages with `php:remi-8.5/common`.

Syntax explained

dnf module switch-to
Selects the target stream and performs a package synchronization transaction.
php:remi-8.5/common
Names Remi's PHP 8.5 stream and common profile.
--assumeno
Safer preview that resolves and prints the transaction without accepting it.
-y
Accepts the reviewed transaction non-interactively; never use it before preview.
Command
sudo dnf module switch-to -y php:remi-8.5/common
Example output / evidence
The transaction selects the php:remi-8.5 stream.

Checkpoint: Checkpoint: switch stream

Continue whenOnly the reviewed PHP family and required dependencies change, no critical extension/unrelated package is removed, and the enabled stream becomes remi-8.5.

Stop whenPreview removes unrelated software, a required extension lacks a build, transaction source is unexpected, downgrade/conflict is unexplained, or rollback stream/package set is unavailable.

If this step fails

DNF reports conflicts or proposes erasing an extension.

Likely causeThe extension is incompatible with PHP 8.5, repository metadata is incomplete, or another repository pins an ABI.

Safe checks
  • sudo dnf module switch-to php:remi-8.5/common --assumeno
  • dnf repoquery --installed --qf '%{name} %{evr} %{repoid}' 'php*' | sort

ResolutionCancel, keep the prior stream, and resolve compatibility in staging or choose a parallel runtime; never use `--allowerasing` blindly.

Security notes

  • Do not weaken dependency or signature checks to force a language-runtime upgrade; inconsistent native modules can crash or expose applications.

Alternatives

  • Install prefixed php85 SCL packages or deploy a pinned container while the system stream remains unchanged.

Stop conditions

  • Preview removes unrelated software, a required extension lacks a build, transaction source is unexpected, downgrade/conflict is unexplained, or rollback stream/package set is unavailable.
07

command

Install the runtime, FPM, and common production extensions

caution

Install only extensions required by the application; this baseline covers database, XML, internationalization, ZIP, and process control.

Why this step matters

An explicit extension allowlist keeps the attack surface and future patch obligations visible; copying a generic mega-list often installs unused interpreters and native code.

What to understand

The baseline includes CLI, FPM, OPcache, database drivers, XML, multibyte, internationalization, ZIP and process functions. Remove packages the application does not require.

Use Composer platform requirements and staging traces to identify additional extensions. Match the FPM and CLI branches and inspect repository provenance.

Installing packages does not securely configure php.ini, pool identity, upload limits, sessions, error display, socket access, SELinux or the web handler.

System changes

  • Installs or upgrades the selected PHP CLI/FPM/OPcache and explicit extension RPMs from the active stream.

Syntax explained

php / php-cli
Provides common configuration and the command-line interface.
php-fpm
Provides the system FastCGI process manager service.
php-opcache
Provides shared bytecode caching that still requires production sizing/invalidation policy.
php-mysqlnd / php-pgsql
Provides database-specific native drivers; install only those used.
php-xml/mbstring/intl/zip/process
Adds common application capabilities and corresponding patch surface.
Command
sudo dnf install -y php php-cli php-fpm php-opcache php-mysqlnd php-pgsql php-xml php-mbstring php-intl php-zip php-process
Example output / evidence
PHP 8.5 packages are installed from a Remi repository.

Checkpoint: Checkpoint: install runtime

Continue whenThe reviewed package set installs from the intended stream, every required extension is present, unused packages are excluded, and DNF completes without unresolved transactions.

Stop whenAny package comes from an unexpected repository, critical extension is absent, disk/inodes are low, transaction scripts fail, or production traffic still depends on untested old processes.

If this step fails

The application reports a missing extension after installation.

Likely causeIts package was not identified, config scans a different directory, or no compatible Remi build exists.

Safe checks
  • php --ini
  • php -m | sort
  • dnf search 'php-*'

ResolutionMap the exact extension to an official compatible package and test it in staging; do not install an arbitrary binary or assume CLI and FPM load the same configuration.

Security notes

  • Every native extension executes in the application process; minimize the set and keep its Remi/PHP lifecycle monitored.

Alternatives

  • Start with the smallest CLI/FPM baseline and add one evidence-backed extension at a time during staging acceptance.

Stop conditions

  • Any package comes from an unexpected repository, critical extension is absent, disk/inodes are low, transaction scripts fail, or production traffic still depends on untested old processes.
08

verification

Start FPM and prove package provenance

read-only

Enable FPM, verify syntax, exact version, loaded configuration, and RPM vendor before connecting a web server.

Why this step matters

Starting the service only after FPM syntax, version and provenance checks prevents an unverified runtime from silently becoming a web handler; package success is not an end-to-end acceptance test.

What to understand

`php -v` and `php --ini` prove the CLI branch and scanned files. `php-fpm -t` validates FPM's own configuration, which can differ.

`dnf info --installed` supplies the `From repo` field that `rpm -qi` does not. Record the exact NEVRA and stream as change evidence.

Enable/start FPM without changing Apache/nginx. Inspect the socket/listener, pool identity and SELinux context before a canary handler references it.

System changes

  • Enables and starts `php-fpm` at boot, creates its runtime socket/log state, and records version/configuration/package provenance evidence.

Syntax explained

systemctl enable --now
Starts the unit immediately and creates the boot-time enablement link.
php --ini
Lists the loaded CLI configuration and scanned fragment directory.
php-fpm -t
Tests FPM configuration syntax without serving application traffic.
dnf info --installed
Reports installed package metadata including `From repo` provenance.
Command
sudo systemctl enable --now php-fpm; php -v; php --ini; sudo php-fpm -t; dnf info --installed php php-fpm | grep -E '^(Name|Version|Release|From repo)'
Example output / evidence
PHP 8.5.x is reported, FPM configuration is successful, and From repo identifies remi-modular.

Checkpoint: Checkpoint: start and prove

Continue whenCLI reports PHP 8.5.x, FPM syntax succeeds and service is active, configuration paths are intentional, and PHP/FPM packages report the Remi repository.

Stop whenFPM syntax/start fails, version branches differ, config paths are unexpected, package source is not Remi, socket conflicts, or an existing web handler is changed implicitly.

If this step fails

php-fpm fails while php -v succeeds.

Likely causeFPM reads a different/old pool directive, an extension fails in service context, socket/user paths conflict, or SELinux denies access.

Safe checks
  • sudo php-fpm -tt
  • systemctl status php-fpm --no-pager
  • sudo journalctl -u php-fpm --since '-15 min' --no-pager -n 150
  • sudo ss -lxnp | grep php

ResolutionLeave web traffic on the prior handler, correct the exact configuration or policy failure, rerun syntax, and start only when evidence is clean.

Security notes

  • Do not publish phpinfo or use the default broad pool as proof. Connect a dedicated least-privilege pool through one reviewed canary site.

Alternatives

  • Keep FPM disabled after package verification and configure/test the dedicated pool offline before the first service start.

Stop conditions

  • FPM syntax/start fails, version branches differ, config paths are unexpected, package source is not Remi, socket conflicts, or an existing web handler is changed implicitly.

Finish line

Verification checklist

Runtime and servicephp -r 'printf("%s %d-bit\n", PHP_VERSION, PHP_INT_SIZE * 8);' && systemctl is-active php-fpmPHP reports 8.5.x with the expected word size and php-fpm is active.
Repository and extension provenancednf repoquery --installed --qf '%{name} %{evr} %{repoid}' 'php*' | sort; php -m | sortPHP packages resolve to the intended Remi stream and required extensions are present.

Recovery guidance

Common problems and safe checks

EPEL or Remi release-package installation fails signature or TLS verification.

Likely causeSystem time/CA trust is wrong, a proxy intercepts TLS, URL/major is incorrect, cached metadata is corrupt, or the package is not from the official host.

Safe checks
  • timedatectl status
  • curl -I https://rpms.remirepo.net/enterprise/remi-release-10.rpm
  • rpm -q epel-release remi-release
  • sudo dnf clean expire-cache

ResolutionCorrect time, trust path, proxy and detected major; use only official release URLs and valid signatures. Never add `--nogpgcheck` as a repair.

DNF cannot resolve `php:remi-8.5` or reports modular filtering conflicts.

Likely causeRequired repositories are disabled, metadata is stale, another stream/repository pins packages, or EL/DNF generation differs from the expected path.

Safe checks
  • sudo dnf repolist --enabled
  • sudo dnf module list php
  • sudo dnf repoquery --installed --qf '%{name} %{evr} %{repoid}' 'php*' | sort
  • sudo dnf check

ResolutionRestore complete official BaseOS/AppStream, builder, EPEL and Remi metadata, remove only documented conflicting repository policy, preview the switch again, and stop if it remains incoherent.

The stream transaction wants to remove a required PHP extension or application package.

Likely causeThat extension has no PHP 8.5-compatible build, a third-party package constrains the old ABI, or the application depends on an obsolete component.

Safe checks
  • rpm -qa 'php*' | sort
  • sudo dnf repoquery --whatrequires php-common
  • sudo dnf module switch-to php:remi-8.5/common --assumeno

ResolutionKeep the current runtime or move the application to a tested parallel/container environment until every required extension has a trusted compatible build.

PHP CLI reports 8.5 but php-fpm fails its configuration test or start.

Likely causeAn old directive or extension is incompatible, multiple pool names/sockets conflict, the service reads different configuration, or SELinux/filesystem permissions block paths.

Safe checks
  • sudo php-fpm -tt
  • php --ini
  • systemctl status php-fpm --no-pager
  • sudo journalctl -u php-fpm --since '-15 min' --no-pager -n 150
  • sudo ss -lxnp | grep php

ResolutionUse the exact failing file/line from `-tt` or the journal, restore/port that configuration in staging, revalidate, and leave the web handler on the prior runtime until FPM is healthy.

After the procedure

Alternatives and next steps

Consider these alternatives

  • Use the distribution-supported PHP branch when PHP 8.5 features are not required and vendor support/lifecycle is the priority.
  • Install Remi's prefixed `php85` Software Collection when PHP 8.5 must run beside an unchanged system runtime.
  • Use a signed, pinned container image when application isolation and immutable rollback are stronger than a host-level system stream, while still patching the image and base OS.
  • Build from source only with a maintained reproducible packaging/signing/update pipeline; an unmanaged `/usr/local` build is not a production shortcut.

Operate it safely

  • Create a dedicated FPM pool for the application with explicit Unix identity, socket ownership, worker capacity, timeouts, logs, status/ping access and pool-scoped PHP limits.
  • Wire only one canary virtual host to the new socket, validate Apache/nginx configuration, test real application login/read/write/background paths and observe errors/latency before broader cutover.
  • Run Composer platform checks and application tests, remove temporary diagnostic scripts, verify OPcache/deployment invalidation, and document extension/lifecycle ownership.
  • Schedule security updates and repository/stream health checks; retest rollback and review the target PHP branch before its support window changes.

Reference

Frequently asked questions

Why not download individual PHP RPM files?

The runtime, FPM and extensions share an ABI and dependencies. A repository plus coherent stream lets DNF resolve and update the package family together.

Does this preserve the old system PHP?

No. Unprefixed Remi packages replace/switch the system stream. Use the separate prefixed `php85` SCL guide for side-by-side operation.

Can I skip EPEL or CRB if installation appears to work?

Do not design around an accidental cache or partial dependency set. Configure the official prerequisites documented by Remi for the detected Enterprise Linux release.

Why stop before configuring nginx or Apache?

Package installation and request routing are separate risk boundaries. A site-specific FPM pool and handler require their own ownership, socket, SELinux, rollback and application tests.

Recovery

Rollback

Restore the previous DNF module stream and configuration during a controlled maintenance window.

  1. Stop php-fpm and restore the archived PHP and web-server configuration.
  2. Use dnf module switch-to with the recorded previous stream, then distro-sync the PHP packages.
  3. Reinstall the exact recorded extension set and validate the older runtime before restoring traffic.
  4. Do not remove repository packages until dependency resolution and application rollback are proven.

Evidence

Sources and review

Verified 2026-07-25Review due 2026-10-23
PHP 8.5 release documentationofficialRemi repository: install PHP 8.5 on Enterprise LinuxofficialRemi repository configuration wizardofficialPHP-FPM installation and configurationofficial