Enterprise Linux Lifecycle
- "CentOS" today means CentOS Stream, which is upstream of RHEL — not downstream. This reversed in late 2020.
- For a stable production clone of RHEL, you now want AlmaLinux, Rocky Linux, or Oracle Linux.
- Paid RHEL means
subscription-managerand access to extra repos, support, and errata. - EPEL is an additional repo — not a replacement for the base distribution.
- Pinning to a point release (
--releasever=9.3) is legitimate but has a cost: you stop getting errata after that release rotates out. - Major upgrades (8 → 9) go through
leapp, notdnf upgrade. Back up first. Actually back up first.
The 2020 landscape shift
Until December 2020, the "I want RHEL without the bill" answer was simple: CentOS Linux. CentOS was a downstream rebuild of RHEL — same binaries, no support, ten-year lifecycle. Then Red Hat announced CentOS Linux 8 would end in 2021 and CentOS would become CentOS Stream: a rolling upstream that feeds into the next RHEL minor release.
Three practical consequences:
- "CentOS" no longer means "RHEL-compatible production stable". Stream is closer to a public beta of the next RHEL minor.
- Alma and Rocky sprung up to fill the RHEL-downstream gap. Both produce bit-for-bit (or very close) rebuilds from RHEL sources and offer 10-year lifecycles.
- Oracle Linux, which had always existed as a RHEL clone, gained fresh relevance.
Picking a distribution
| Distro | Relationship to RHEL | Support model | Lifecycle | Good for |
|---|---|---|---|---|
| RHEL | Source | Paid subscription, vendor support | ~10 years | Regulated workloads, when "call Red Hat" is the right answer |
| AlmaLinux | Downstream rebuild (ABI-compatible) | Community + AlmaLinux Foundation | ~10 years | Free, most-similar-to-RHEL workhorse |
| Rocky Linux | Downstream rebuild (ABI-compatible) | Community (RESF) | ~10 years | Drop-in replacement for old CentOS |
| Oracle Linux | Downstream rebuild + Oracle's UEK | Free binaries; paid support optional | ~10 years | Oracle DB/middleware shops, unbreakable kernel |
| CentOS Stream | Upstream of RHEL | Community | ~5 years | Developers testing against the next RHEL minor |
Unless you specifically want to live slightly ahead of RHEL, do not run CentOS Stream in production. It is by design a moving target.
subscription-manager on RHEL
RHEL hosts register against the Red Hat content delivery network. Without a subscription attached you have no repositories enabled.
sudo subscription-manager register --username you@example.com
sudo subscription-manager refresh
sudo subscription-manager attach --auto
# See what's enabled:
sudo subscription-manager repos --list-enabled
# Enable extra content sets:
sudo subscription-manager repos --enable=rhel-9-for-x86_64-supplementary-rpms
sudo subscription-manager repos --enable=codeready-builder-for-rhel-9-x86_64-rpms
# Status:
sudo subscription-manager status
sudo subscription-manager facts --list | head
In cloud marketplaces (AWS, Azure, GCP) the RHEL images are usually pre-registered via Red Hat Update Infrastructure (RHUI), not the public CDN. You can swap from RHUI to a regular subscription if you have a BYOS entitlement.
auto-attach at registration and forget it. For golden images use subscription-manager clean before snapshotting so the new clones register themselves on boot.
EPEL
EPEL (Extra Packages for Enterprise Linux) is a Fedora-maintained repo of extra software for EL-family distros. Things like htop, ncdu, mosh, monit, jq (on older releases), nagios-plugins, etc.
# On RHEL 9 / Alma / Rocky / Oracle 9:
sudo dnf install -y epel-release
sudo dnf install -y epel-next-release # optional: rolls a little ahead
# On RHEL, you typically also need:
sudo subscription-manager repos --enable=codeready-builder-for-rhel-9-x86_64-rpms
# EPEL depends on packages from CodeReady Linux Builder (CRB).
# On Alma/Rocky/Oracle the equivalent is:
sudo dnf config-manager --set-enabled crb
Modularity and AppStreams
RHEL 8 introduced modularity: the ability to install different, independently-versioned "streams" of an app within the same release. Want Node 18 on one box and Node 20 on another, on the same RHEL 8? That's modularity.
dnf module list # every available module
dnf module list nodejs # just nodejs
dnf module info nodejs:20
# Enable a stream and install a profile:
sudo dnf module enable nodejs:20 -y
sudo dnf module install nodejs:20/common -y
# Swap streams (dnf will remove the old one):
sudo dnf module reset nodejs -y
sudo dnf module enable nodejs:22 -y
sudo dnf module install nodejs:22/common -y
RHEL 9 kept the mechanism but shipped far fewer modules — Red Hat acknowledged modularity was more friction than value for most users. RHEL 10 has essentially retired it in favour of plain versioned packages.
| Term | Meaning |
|---|---|
| BaseOS | Core OS — kernel, libc, coreutils. Single stream per major release. |
| AppStream | Applications and runtimes. Multiple streams can exist; only one enabled at a time. |
| Module | A grouping (e.g. postgresql) with multiple streams (10, 12, 13, 15, 16). |
| Stream | A specific version of a module (e.g. postgresql:16). |
| Profile | A curated package set within a stream (server, client, common). |
Pin a release vs follow the stream
By default dnf update tracks the latest minor release (9.5, 9.6, …) for your major. You can pin a host to a specific minor release — useful when you need to match production exactly, or when a vendor certifies against a specific point release.
# One-off install at a specific minor:
sudo dnf install -y --releasever=9.4 some-package
# Pin permanently by writing the releasever:
echo "9.4" | sudo tee /etc/dnf/vars/releasever
# or on RHEL specifically:
sudo subscription-manager release --set=9.4
# Inspect:
subscription-manager release --show
# Back to tracking the latest:
sudo subscription-manager release --unset
Major version upgrades with leapp
dnf upgrade moves you between minor releases. Going from 8 to 9 is a major upgrade and goes through leapp, which swaps repos, migrates package sets, and replays on reboot.
# RHEL 8 → RHEL 9 (abridged):
sudo subscription-manager release --unset
sudo dnf -y upgrade # fully up to date on 8 first
sudo dnf install -y leapp-upgrade
sudo leapp preupgrade # analyses and reports blockers
# Read every "inhibitor" in /var/log/leapp/leapp-report.txt and resolve them.
sudo leapp upgrade # schedules the upgrade
sudo reboot # upgrade runs in a special boot target
# System comes back on RHEL 9. Verify:
cat /etc/os-release
uname -r
sudo subscription-manager release --set=9.4 # if pinning to a minor
On Alma and Rocky the equivalent tooling is called elevate (AlmaLinux's fork of leapp with support for non-RHEL paths). Oracle Linux uses its own leapp fork.
| Before you press enter |
|---|
| Filesystem snapshot or full image backup. Non-negotiable. |
| All third-party repos disabled (EPEL, vendor, your own mirror) for the preupgrade pass. |
| The host is fully up-to-date on its current major. |
Every inhibitor in leapp preupgrade report resolved, not ignored. |
| Out-of-band console access in case the upgrade boot wedges. |
| A plan for rollback: restore snapshot, not "fix forward". |
| Tested the whole path on a staging VM that mirrors the prod host. |
Backups before upgrades
There is no graceful rollback from an interrupted leapp upgrade. Your insurance policy is a backup you can restore without the machine being available.
# On LVM — a thin snapshot is almost free to create, expensive only if you keep it:
sudo lvcreate --size 20G --snapshot --name preupgrade /dev/vg00/root
# On ZFS / btrfs — native snapshots:
sudo zfs snapshot rpool/ROOT/rhel@preupgrade
sudo btrfs subvolume snapshot / /.snapshots/preupgrade
# On cloud: just make an image/snapshot of the disk(s):
aws ec2 create-snapshot --volume-id vol-abc --description "preupgrade rhel9"
Also back up state that's not on the root disk: database dumps, /etc if you don't already version it, any long-lived secrets, SSH host keys (so clients don't warn on reconnect).
Release timeline reference
| Release | GA | Full support | Maintenance ends |
|---|---|---|---|
| RHEL 7 | Jun 2014 | ended 2019 | Jun 2024 (extended paid beyond) |
| RHEL 8 | May 2019 | ended May 2024 | May 2029 |
| RHEL 9 | May 2022 | May 2027 | May 2032 |
| RHEL 10 | May 2025 | May 2030 | May 2035 |
AlmaLinux, Rocky, and Oracle track the same majors with comparable (often identical) end-of-life dates. For authoritative dates, check the specific distribution's lifecycle page each planning cycle — these do shift.
See also: SELinux, OpenSCAP Hardening.