Edit

Manage Azure Linux packages with DNF5

This article covers common package management tasks on Azure Linux, including:

  • Where repository configuration lives.
  • How legacy package-manager commands map to DNF5.
  • How DNF caches metadata and resolves packages.
  • How kernels and other install-only packages are handled.
  • How to enable unattended updates.
  • The most commonly used DNF commands.

Note

Azure Linux 4.0 is now in preview and is strictly limited to evaluation and testing purposes. It's not suitable for production use.

Repository configuration

DNF5 reads repository definitions from /etc/yum.repos.d/. The directory name is preserved from YUM for compatibility; DNF5 reads from this directory.

Each .repo file in that directory is a plain-text configuration file that tells DNF where to find packages, whether to verify them with GPG, and whether the repository is enabled by default. The main DNF configuration file is /etc/dnf/dnf.conf, which controls global behavior such as cache settings, the install-only limit, and proxy configuration.

Azure Linux ships compatibility symlinks so that legacy commands (yum, dnf (DNF4), microdnf, tdnf) all dispatch to DNF5:

lrwxrwxrwx.  1 root root       4  yum -> dnf5
lrwxrwxrwx.  1 root root       4  microdnf -> dnf5
-rwxr-xr-x.  1 root root 1614408  dnf5
lrwxrwxrwx.  1 root root       4  dnf -> dnf5
lrwxrwxrwx.  1 root root       4  tdnf -> dnf5

The common subcommands all work through the symlinks. Edge cases that depended on DNF4 internals or microdnf-specific behavior might not. For details on what changed, see the following resources:

How DNF5 resolves packages

When you run a DNF command, DNF5 performs the following steps to determine what packages to install, upgrade, or remove:

  1. Loads every .repo file in /etc/yum.repos.d/ and selects the repositories marked as enabled.
  2. Refreshes repository metadata, caching it locally under /var/cache/libdnf5. Cached metadata includes the package list, version and dependency information, checksums, and signatures.
  3. Resolves the requested install, remove, or upgrade against the enabled repositories, picks package versions, and verifies integrity and signatures before applying the transaction.

Disabled repositories are ignored unless you enable them explicitly with --enablerepo=<repo-id> for a single command.

The /var/cache/libdnf5 cache exists so DNF doesn't have to re-download metadata on every invocation. Run dnf clean all to empty it (see Frequently used DNF commands).

Install-only packages and multiple installed versions

Some packages, most notably the kernel, are installed side by side rather than upgraded in place. DNF5 controls this through two settings in /etc/dnf/dnf.conf:

  • installonlypkgs: List of package names that are never upgraded in place. Kernel packages are the canonical entry.
  • installonly_limit: Maximum number of versions of an install-only package that might coexist on the system. The default is 3.

When a new version is installed and the limit is exceeded, DNF removes the oldest version automatically.

For the kernel, this gives you:

  • Fallback: If a new kernel fails to boot, GRUB can still launch a previous, known-working kernel.
  • Validation: You can install and test a new kernel without removing the running one.
  • Variant coexistence: You can install different kernel builds (for example, with different feature sets) at the same time.

Each kernel version is a separate RPM, so DNF tracks and removes them like any other package.

Unattended updates with dnf-automatic

dnf-automatic is a service that periodically checks for, downloads, and optionally applies package updates. It's driven by a systemd timer rather than running as a long-lived daemon.

Install dnf-automatic

Install dnf-automatic using the following command:

sudo dnf install -y dnf-automatic

Enable the dnf5-automatic timer

Enable the dnf5-automatic timer immediately and across reboots using the following command:

sudo systemctl enable --now dnf5-automatic.timer
  • enable configures the timer to start at boot.
  • --now starts the timer in the current session.

Check status of the dnf5-automatic timer

Check that the timer is active and see when it last ran using the following command:

systemctl status dnf5-automatic.timer

Typical output looks like the following example:

● dnf5-automatic.timer - dnf-automatic timer
     Loaded: loaded (/usr/lib/systemd/system/dnf5-automatic.timer; enabled; preset: disabled)
     Active: active (waiting) since Thu 2026-03-26 14:36:54 UTC; 13min ago
 Invocation: f6984eeceb7c40df99bca243f3da728c
    Trigger: Fri 2026-03-27 06:34:18 UTC; 15h left
   Triggers: ● dnf5-automatic.service

Active: active (waiting) is expected: the underlying service is a one-shot that runs only when the timer fires, then exits. The Trigger: line shows the next scheduled run.

List the next scheduled run of the dnf5-automatic timer

List the next run alongside any other timers using the following command:

systemctl list-timers dnf5-automatic.timer

Example output:

NEXT                        LEFT LAST PASSED UNIT                 ACTIVATES
Fri 2026-03-27 06:34:18 UTC  15h -         - dnf5-automatic.timer dnf5-automatic.service

1 timers listed.
Pass --all to see loaded but inactive timers, too.

Frequently used DNF commands

The following commands cover the bulk of day-to-day package management on Azure Linux.

dnf clean all

dnf clean all removes everything DNF has cached under /var/cache/libdnf5. Use it to:

  • Recover from corrupted or stale metadata that's causing transaction errors.
  • Shrink container images by stripping the package cache after installs in the same RUN layer.
  • Reclaim disk space.

Container example:

RUN dnf install -y package1 package2 \
    && dnf clean all

dnf search matches keywords against package names and summaries. For example:

dnf search lsof

Example output:

Updating and loading repositories:
Repositories loaded.
Matched fields: name (exact)
 lsof.x86_64                    A utility which lists open files on a Linux/UNIX system
Matched fields: name, summary
 lsof-debuginfo.x86_64           Debug information for package lsof
 lsof-debugsource.x86_64         Debug sources for package lsof

dnf provides

dnf provides finds the package that owns a given file, command, or capability. For example:

dnf provides lsof

Example output:

Updating and loading repositories:
Repositories loaded.
lsof-4.98.0-8.azl4.20260303.x86_64 : A utility which lists open files on a Linux/UNIX system
Repo         : @System
Matched From :
Provide      : lsof = 4.98.0-8.azl4.20260303

dnf install

dnf install installs one or more packages along with their runtime dependencies:

sudo dnf install lsof

Example output:

Updating and loading repositories:
Repositories loaded.
Package           Arch     Version                  Repository    Size
Installing:
 lsof             x86_64   4.98.0-8.azl4.20260303   azurelinux  578.5 KiB

Transaction Summary:
 Installing:         1 package

Total size of inbound packages is 226 KiB. Need to download 226 KiB.
After this operation, 579 KiB extra will be used (install 579 KiB, remove 0 B).
Is this ok [y/N]: y
[1/1] lsof-0:4.98.0-8.azl4.20260303.x86_64                100% | 641.9 KiB/s | 226.0 KiB |  00m00s
[1/1] Total                                               100% | 640.1 KiB/s | 226.0 KiB |  00m00s
Running transaction
[1/3] Verify package files                                100% | 500.0   B/s |   1.0   B |  00m00s
[2/3] Prepare transaction                                 100% |  23.0   B/s |   1.0   B |  00m00s
[3/3] Installing lsof-0:4.98.0-8.azl4.20260303.x86_64     100% |   3.0 MiB/s | 580.2 KiB |  00m00s
Complete!

dnf remove

dnf remove uninstalls a package along with any dependencies that were pulled in solely for it:

sudo dnf remove -y lsof

Example output:

Package           Arch     Version                  Repository    Size
Removing:
 lsof             x86_64   4.98.0-8.azl4.20260303   azurelinux  578.5 KiB

Transaction Summary:
 Removing:           1 package

After this operation, 579 KiB will be freed (install 0 B, remove 579 KiB).
Is this ok [y/N]: y
Running transaction
[1/2] Prepare transaction                                 100% |  27.0   B/s |   1.0   B |  00m00s
[2/2] Removing lsof-0:4.98.0-8.azl4.20260303.x86_64       100% |  72.0   B/s |  11.0   B |  00m00s
Complete!

dnf upgrade

dnf upgrade updates installed packages to their latest available versions.

sudo dnf upgrade

When everything is current, the output is short. For example:

Updating and loading repositories:
Repositories loaded.
Nothing to do.

Tip

Pass -y to install, remove, or upgrade in non-interactive contexts such as scripts, CI pipelines, and container builds. Any DNF operation that modifies the system requires root, so run it under sudo or as root.