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 True if 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.

TaskDNF (RHEL/Rocky/Alma)APT (Debian/Ubuntu)
Install a packagednf install nginxapt install nginx
Remove a packagednf remove nginxapt remove nginx
Update package indexdnf check-updateapt update
Upgrade all packagesdnf upgradeapt upgrade
Search packagesdnf search nginxapt search nginx
Show package infodnf info nginxapt show nginx
List installed packagesdnf list installedapt list --installed
Find which package owns a filednf provides /usr/bin/digdpkg -S /usr/bin/dig
Remove unused dependenciesdnf autoremoveapt autoremove
Clean package cachednf clean allapt clean
View transaction historydnf historycat /var/log/apt/history.log
Rollback a changednf history undo <id>No direct equivalent
Install package groupdnf group install "Name"apt install taskname
Download without installingdnf download nginxapt 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.

LEAVE A REPLY

Please enter your comment!
Please enter your name here