DNF is the default package manager on RHEL 10, Rocky Linux 10, AlmaLinux 10, and Fedora. It replaced YUM (v3) years ago, and what many still call “yum” is actually DNF running behind the scenes. This guide covers everything you need for day-to-day package management – from basic commands through module streams, transaction history, local repository creation, and automated updates.
DNF Basics
Every sysadmin needs these commands committed to muscle memory. The examples below work identically on RHEL 10, Rocky Linux 10, and AlmaLinux 10.
Install a Package
sudo dnf install -y httpd
The -y flag auto-confirms the transaction. Without it, DNF will prompt you before proceeding.
Verify the installation:
rpm -q httpd
Remove a Package
sudo dnf remove httpd
DNF will list dependent packages that would also be removed. Review the list before confirming. To also remove packages that were installed as dependencies and are no longer needed:
sudo dnf autoremove
Update Packages
Update all installed packages:
sudo dnf upgrade --refresh
The --refresh flag forces DNF to re-download repository metadata before checking for updates. This ensures you get the latest available versions.
Update a single package:
sudo dnf upgrade httpd
Check for available updates without installing them:
dnf check-update
Search for Packages
dnf search nginx
This searches package names and descriptions. For a broader search that includes package summaries:
dnf search all nginx
View Package Information
dnf info nginx
This displays the package version, release, architecture, size, repository, license, and description – useful for checking what version is available before installing.
List Packages
List all installed packages:
dnf list installed
List all available packages:
dnf list available
List packages with updates pending:
dnf list updates
Find Which Package Provides a File
dnf provides /usr/bin/dig
This tells you which package owns a particular file or command. Extremely useful when a script fails because a binary is missing. You can also use glob patterns:
dnf provides "*/dig"
Package Groups
DNF organizes related packages into groups. List available groups:
dnf group list
Install a group:
sudo dnf group install "Development Tools"
View what a group contains before installing:
dnf group info "Development Tools"
Remove a group:
sudo dnf group remove "Development Tools"
DNF Module Streams
Module streams let you choose between different versions of software from the same repository. This is particularly useful for programming languages and application stacks where you might need a specific version.
List available modules:
dnf module list
Check available streams for a module:
dnf module list nodejs
Enable a specific stream:
sudo dnf module enable nodejs:20
Install from the enabled stream:
sudo dnf module install nodejs:20/common
To switch streams (for example, moving from Node.js 18 to 20):
sudo dnf module reset nodejs
sudo dnf module enable nodejs:20
sudo dnf module install nodejs:20/common
Verify the active stream:
dnf module list --enabled
DNF History and Rollback
Every DNF transaction is recorded, giving you the ability to review and undo changes. This is one of DNF’s most valuable features for production systems.
View transaction history:
dnf history
Get details on a specific transaction:
dnf history info 15
Undo a transaction (rolls back the changes):
sudo dnf history undo 15
Redo a previously undone transaction:
sudo dnf history redo 15
Rollback to the state before a specific transaction (undoes that transaction and all newer ones):
sudo dnf history rollback 12
This is particularly useful when an update causes problems. You can roll back to the last known good state in a single command.
Creating a Local Repository
Local repos are useful in air-gapped environments, for caching packages, or for distributing custom RPMs internally.
Install the createrepo tool:
sudo dnf install -y createrepo_c
Create a directory structure and copy your RPM files into it:
sudo mkdir -p /var/local/repo
sudo cp /path/to/packages/*.rpm /var/local/repo/
Generate the repository metadata:
sudo createrepo /var/local/repo
Create a repo configuration file:
sudo tee /etc/yum.repos.d/local.repo <<'EOF'
[local-repo]
name=Local Repository
baseurl=file:///var/local/repo
enabled=1
gpgcheck=0
EOF
Verify the repository is available:
dnf repolist
When you add new RPMs, regenerate the metadata:
sudo createrepo --update /var/local/repo
sudo dnf clean metadata
DNF Automatic for Unattended Updates
For servers that need to stay patched without manual intervention, dnf-automatic handles scheduled updates.
Install it:
sudo dnf install -y dnf-automatic
Edit the configuration file:
sudo vi /etc/dnf/automatic.conf
Key settings to configure:
[commands]
# Options: default, security
upgrade_type = security
apply_updates = yes
[emitters]
emit_via = email
[email]
email_from = root@localhost
email_to = [email protected]
email_host = localhost
Setting upgrade_type = security limits automatic updates to security patches only, which is the safest approach for production. Set apply_updates = yes to actually install the updates (the default is to only download them).
Enable and start the timer:
sudo systemctl enable --now dnf-automatic.timer
Verify the timer is active:
systemctl status dnf-automatic.timer
Tuning dnf.conf
The main DNF configuration file at /etc/dnf/dnf.conf has several options worth adjusting.
[main]
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=True
best=True
skip_if_unavailable=False
max_parallel_downloads=10
fastestmirror=True
defaultyes=True
keepcache=False
Explanation of the most impactful settings:
- max_parallel_downloads=10 – Downloads up to 10 packages simultaneously instead of one at a time. This dramatically speeds up large updates.
- fastestmirror=True – Tests mirror speeds and selects the fastest one. Saves time on every metadata refresh and package download.
- installonly_limit=3 – Keeps only the 3 most recent kernel versions. Prevents /boot from filling up.
- defaultyes=True – Makes “yes” the default answer for prompts. Convenient for interactive use but does not affect scripts using
-y. - keepcache=False – Removes downloaded RPMs after installation to save disk space. Set to
Trueif you want to keep them for offline use. - clean_requirements_on_remove=True – Automatically removes orphaned dependencies when you remove a package.
DNF vs APT Command Comparison
If you work across both RHEL-family and Debian-family distributions, this reference table helps translate between the two package managers.
| Task | DNF (RHEL/Rocky/Alma) | APT (Debian/Ubuntu) |
|---|---|---|
| Install a package | dnf install nginx | apt install nginx |
| Remove a package | dnf remove nginx | apt remove nginx |
| Update package index | dnf check-update | apt update |
| Upgrade all packages | dnf upgrade | apt upgrade |
| Search packages | dnf search nginx | apt search nginx |
| Show package info | dnf info nginx | apt show nginx |
| List installed packages | dnf list installed | apt list --installed |
| Find which package owns a file | dnf provides /usr/bin/dig | dpkg -S /usr/bin/dig |
| Remove unused dependencies | dnf autoremove | apt autoremove |
| Clean package cache | dnf clean all | apt clean |
| View transaction history | dnf history | cat /var/log/apt/history.log |
| Rollback a change | dnf history undo <id> | No direct equivalent |
| Install package group | dnf group install "Name" | apt install taskname |
| Download without installing | dnf download nginx | apt download nginx |
Conclusion
DNF is a mature, capable package manager that handles everything from basic installs to complex module stream management and transactional rollbacks. Taking a few minutes to tune dnf.conf with parallel downloads and fastest mirror selection makes a noticeable difference in daily work. Setting up dnf-automatic on production servers keeps them patched with minimal effort. And if you manage mixed environments, the comparison table above should help you switch between DNF and APT without losing your rhythm.

























































