CentOS Stream: Managing Multiple Software Versions Safely on a Rolling‑Release Platform
Learn how CentOS Stream’s AppStream module streams let you install parallel software versions, choose lightweight profiles, and plan upgrades without breaking production.
10 Sept 2026, 01:57 UTC

Problem: You need different software versions on the same server without breaking existing services.
In many environments a legacy application still runs on Python 3.9 while a new project requires Python 3.12. Updating the system package manager would replace the old binary, causing downtime. Traditional package managers treat the entire distribution as a single versioned set, so you cannot install two parallel streams of the same software.
Why traditional package managers struggle
The base dnf repository provides one package per name. When a new upstream release appears, the old binary is replaced, and any dependent service that still expects the previous soname may fail. This makes side‑by‑side execution impossible without containerization or manual symlink juggling.
Thesis: CentOS Stream’s AppStream module streams give you curated, versioned collections that can coexist safely.
AppStream modules are not just “packages”. They are module streams — curated sets of RPMs that share a common version qualifier (e.g., nodejs:20). Each stream declares one or more profiles (default, server, client, devel, minimal) that select a subset of the RPMs. This design lets you pull a full development stack or a tiny runtime image from the same stream without conflicting with the base OS packages.
How module streams work
When you run dnf module install nodejs:20/devel, dnf resolves the devel profile, which includes compilers, headers, and documentation. The minimal profile installs only the runtime binary, keeping the footprint small and the attack surface reduced. The stream’s lifecycle is tied to the upstream RHEL minor release cadence, so Red Hat publishes an EOL date for each stream (for example, nodejs:18 is supported until RHEL 9.4 reaches end‑of‑life). This gives teams a predictable upgrade window rather than a single OS‑wide deadline.
Worked example: installing nodejs:20/devel and nodejs:20/minimal
- Check current module availability:
dnf module list - Install the development profile (requires root):
dnf module install -y nodejs:20/devel - Verify the installed packages:
rpm -ql nodejs | grep '/usr/bin' - Now install the minimal runtime profile in a separate container or chroot:
dnf module install -y nodejs:20/minimal - Confirm that both profiles coexist without overwriting each other:
dnf module list nodejs
These commands assume you have sudo or root privileges. The dnf module install step pulls packages from the nodejs:20 stream, while the profile suffix tells dnf which set of RPMs to select. Because each profile lives under its own stream, you can upgrade nodejs:20 to nodejs:22 later without touching the installed binaries of other streams.
Trade‑off and limitation
Module streams do not isolate libraries at runtime. Two streams cannot provide the same soname in the same process, so a single application cannot load libfoo from stream A while another thread uses libfoo from stream B. For true side‑by‑side execution you still need containerization (Docker, Podman) or environment variable manipulation such as LD_LIBRARY_PATH. Additionally, the dnf module CLI output changed between Stream 8 and Stream 9; automation that parses dnf module list must be validated on the target Stream version.
Actionable closing: verify your Stream version, pin modules, plan upgrades
Follow these steps to ensure a stable deployment:
- Confirm the exact Stream compose ID:
cat /etc/os-release rpm -q centos-stream-release - List current module streams to see what is available:
dnf module list - Review Red Hat’s lifecycle page for module‑stream EOL dates mapped to RHEL minor releases (e.g., nodejs:20 supported until RHEL 9.4 EOL).
- Test a module switch in a disposable VM to verify clean replacement:
dnf module reset postgresql dnf module enable postgresql:16 dnf distro-sync - If you need immutable infrastructure, pin the module stream using
dnf versionlockor lock the compose ID in your CI pipeline.
By treating software as versioned streams rather than as a monolithic package set, CentOS Stream gives you the flexibility to run multiple language runtimes, databases, or toolchains on a single host while still benefiting from the rolling‑release model. The key is to verify your Stream version, choose the appropriate profile, and plan upgrades around the published EOL dates.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.