AlmaLinux 10:从 module stream 到版本化包名
- EL9 侧:
almalinux:9容器,AppStream 模块元数据完整; - EL10 侧:AlmaLinux 10.2 虚拟机(dnf 4.20.0)与
almalinux:10容器。
两侧都执行了 dnf module list、dnf module list nodejs、dnf module enable,并用 dnf list --available 找替代包。
日志:plans/content-expansion/evidence/logs/module-streams-el9-el10.log。
EL9:一个软件,多条版本轨
Section titled “EL9:一个软件,多条版本轨”$ dnf module listmariadb 10.11 client, galera, server [d] MariaDB Modulemariadb 11.8 client, galera, server [d] MariaDB Modulemysql 8.4 api, client, filter, server [d]nginx 1.22 / 1.24 / 1.26 common [d]nodejs 18 / 20 / 22 / 24 common [d], development, minimal, s2iphp 8.1 / 8.2 / 8.3 common [d], devel, minimal[d] 表示默认 profile。装出来的包带模块构建标记:
$ rpm -q nodejsnodejs-22.23.2-2.module_el9.8.0+322+f4aa738c.x86_64EL10:命令还在,功能没了
Section titled “EL10:命令还在,功能没了”$ dnf module listWARNING: modularity is deprecated, and functionality will be removed in a future release of DNF5.
$ dnf module list nodejsWARNING: modularity is deprecated, and functionality will be removed in a future release of DNF5.Error: No matching Modules to list
$ dnf module enable nodejs:20Error: Problems in request:missing groups or modules: nodejs:20注意 EL10 仍是 dnf 4.20,不是 dnf5——所以这不是「新版 dnf 还没实现」,而是模块化本身被放弃了。

多版本改由包名承担
Section titled “多版本改由包名承担”$ dnf -q list --available 'php8*'php8.4.x86_64 8.4.24-1.el10_2 appstreamphp8.4-bcmath.x86_64 8.4.24-1.el10_2 appstream| EL9 | EL10 |
|---|---|
php 的 8.1 / 8.2 / 8.3 stream | 默认 php = 8.3;另装 php8.4 并行 |
nodejs 18/20/22/24 stream | 只有 nodejs(22.x)一个轨 |
dnf module enable X:Y | 不存在,改为装对应包名 |
好处是简单:包名即版本,dnf list 一眼看清;代价是没有「同一包名切版本」的机制,脚本要重写。
迁移时先跑这三条
Section titled “迁移时先跑这三条”grep -rn "module \(enable\|install\|reset\)" /etc/ansible /opt/scripts 2>/dev/null | headdnf list --installed | grep -c module_el || truednf -q list --available 'php8*' nodejs 2>/dev/null | head -5第一条找出需要改的脚本,第二条确认旧系统里有没有模块包(rpm -q 里的 .module_el9 标记),第三条看新系统提供了哪些版本化包名。
- 以为
dnf module list静默是没配仓库:其实警告后面什么都不列才是 EL10 的正常输出; - 照抄 EL9 的 Ansible role:
dnf: name=@nodejs:20/common在 EL10 直接失败; - 用
--enablerepo找 stream:EL10 仓库里没有模块元数据,换仓库也找不到; - 升级后对比包清单发现「包名变了」:带
.module_el9…和不带,本质是同一软件的两种打包路径。
练习:验证「EL10 没有 stream」
Section titled “练习:验证「EL10 没有 stream」”dnf module list 2>&1 | tail -3dnf module enable nodejs:20 2>&1 | tail -2dnf -q list --available nodejs 2>/dev/null | head -3检查:
- 第一条只看到 WARNING,没有表格;
- 第二条报
missing groups or modules; - 第三条能列出
nodejs的具体版本; - 结论:EL10 用包名表达版本,不再用 stream。
常见问题
为什么要去掉模块化?
上游 RHEL 10 移除了模块化,理由是多版本轨增加了仓库与升级复杂度;改由并行安装的版本化包名承担。
EL9 上的 stream 还能装吗?
在 EL9 生命周期内可以;一旦升级到 EL10,这些命令必须替换。
需要 nodejs 18 但 EL10 只有 22 怎么办?
用容器跑 18,或从 NodeSource 等第三方仓库装;EL10 官方仓库不提供旧大版本。
- 仓库审计:/repo-priority/
- 离线安装:/offline-updates/
- 升级前评估:/versions/