2026
Linux Package Managers: apt, yum and dnf
Every piece of software on a Linux server arrived through a package manager. Here is how apt and dnf work, how repositories are structured and what to reach for when something needs installing, updating or rolling back.
Installing software on Linux is not like downloading an installer and running it. The package manager is the mechanism through which software arrives on the system, gets updated and gets removed. It tracks what is installed, resolves dependencies and communicates with repositories that hold the actual packages.
The two dominant families are apt on Debian-based distributions like Ubuntu, and dnf on Red Hat-based distributions like Fedora, RHEL and CentOS Stream. An older tool called yum predates dnf on the Red Hat side. You will still encounter it on older systems, but dnf is its direct successor and the two share most of their command syntax.
Understanding your package manager is not optional knowledge. It is the first thing you reach for when setting up a new server, debugging a missing library or tracking down why a service stopped working after an update.
How it works
A package manager works in two layers. The first is the local index, a cached snapshot of what packages exist in your configured repositories and which versions are available. The second is the package database, a record of what is actually installed on the machine right now.
When you ask the package manager to install something, it checks the index for a match, resolves the full dependency tree, downloads the relevant packages from the repository and records the installation in its database. When you remove something, it marks it gone in the database and optionally removes the files from disk. None of this requires internet access for the resolution step, only for the download.
Update the index first
On apt-based systems, the local index goes stale quickly. Running apt install without a prior apt update means you are working from whatever snapshot was cached last time someone ran an update. On a fresh server that might be days or weeks old. Always run apt update before installing packages. DNF handles this automatically on each operation, so explicit index refreshes are less common there.
apt
apt is the primary package management tool on Debian and Ubuntu. It builds on top of a lower-level library called dpkg, which handles the actual installation and removal of .deb packages. You will occasionally see references to apt-get, the older command-line interface for the same underlying system. The two are largely interchangeable in daily use, but apt has cleaner output and is preferred for interactive work.
apt updateRefresh the local package index by fetching updated metadata from the configured repositories. This does not install or upgrade anything.
apt upgradeUpgrade all installed packages to their latest available versions. Packages are not removed to satisfy dependencies.
apt full-upgradeUpgrade installed packages and also remove packages that block the upgrade. Use this when apt upgrade reports held-back packages.
apt install nginxInstall the nginx package along with any required dependencies.
apt install nginx=1.24.0-1Install a specific version of a package. Useful when you need to pin a particular release.
apt remove nginxRemove the nginx package but leave its configuration files in place. The config survives so reinstalling picks up from the same state.
apt purge nginxRemove nginx and delete all its configuration files. Nothing is left behind.
apt autoremoveRemove packages that were installed as dependencies but are no longer needed by anything. Safe to run after removing software.
apt search nginxSearch the package index for packages whose name or description contains the search term.
apt show nginxPrint detailed information about a package: version, dependencies, size, maintainer and description.
apt list --installedList every package currently installed on the system.
The distinction between apt remove and apt purgematters more than it first appears. Leaving configuration files behind with remove is useful when you might reinstall the same package and want to pick up from the same state. Using purge makes sense when you are done with a service entirely and want a clean slate.
dnf and yum
dnf is the package manager on Fedora, RHEL 8 and later, CentOS Stream and related distributions. It works with .rpm packages and handles dependency resolution, repository management and transaction history. yum was its predecessor and is still the primary tool on older RHEL 7 and CentOS 7 systems.
The practical difference for most day-to-day tasks is minimal. If you are on a system with yum, substituting yum for dnf in most commands will work. Where dnf genuinely improves on yum is in dependency resolution speed and the transaction history system, which lets you inspect and roll back past operations.
dnf check-updateList packages that have updates available. Does not apply any changes.
dnf upgradeUpgrade all installed packages to their latest versions. Equivalent to apt full-upgrade in scope.
dnf install nginxInstall the nginx package along with its dependencies.
dnf remove nginxRemove the nginx package. DNF is more aggressive than apt remove about pulling out unused dependencies at the same time.
dnf search nginxSearch package names and summaries for the given term.
dnf info nginxShow detailed package information including version, repository and description.
dnf list installedList all installed packages.
dnf historyShow a log of past dnf transactions. You can inspect or undo previous installs and upgrades by transaction ID.
dnf history undo 12Roll back transaction 12. Removes packages that were installed in that transaction and reinstates anything that was removed.
dnf group install "Development Tools"Install a predefined group of packages. Groups bundle commonly used software for a purpose, such as build toolchains or desktop environments.
Repositories
Every package the manager installs comes from a repository. A repository is just a structured collection of packages hosted somewhere accessible, usually a web server, along with metadata that describes what is available. The package manager reads from configuration files to know where to look.
Debian / Ubuntu
/etc/apt/sources.list
/etc/apt/sources.list.d/*.list
Each line declares a repository. The format is: deb [options] url distribution components. Drop-in files in sources.list.d keep third-party repos isolated from the main config.
RHEL / Fedora / CentOS
/etc/yum.repos.d/*.repo
Each .repo file can declare one or more repositories using INI-style sections. The baseurl or metalink points to the repository root. Repositories can be enabled or disabled per file.
Third-party software often comes with instructions to add a repository before installing. On Debian-based systems this typically means adding a signed repository key with gpg and dropping a source file into /etc/apt/sources.list.d/. On Red Hat-based systems it usually means installing an RPM that drops a .repo file into /etc/yum.repos.d/. Both approaches mean the package manager can keep the software updated through normal upgrade operations.
Pinning versions
Sometimes you need a package to stay at a specific version and not move during a system upgrade. A library that a critical application depends on, a kernel version known to be stable for a particular workload, a database package that requires careful manual migration before it can be upgraded.
apt-mark hold nginxMark nginx as held. It will not be upgraded during apt upgrade operations.
apt-mark unhold nginxRemove the hold so nginx can be upgraded normally again.
apt-mark showholdList all packages currently on hold.
dnf install 'nginx-1.24.0'Install a specific version explicitly.
dnf versionlock add nginxLock nginx to its currently installed version. Requires the dnf-plugins-core package for the versionlock plugin.
dnf versionlock delete nginxRemove the version lock so nginx can be upgraded again.
dnf versionlock listShow all packages currently version-locked.
Inspecting packages
The package database is queryable. When something breaks after an update, or when you need to know which package owns a particular file, the tools below let you answer those questions without guessing.
dpkg -lList all packages installed on a Debian-based system with their version and status. Pipe through grep to filter.
dpkg -L nginxList every file that the nginx package installed on disk.
dpkg -S /usr/sbin/nginxFind out which package owns the file at the given path. Useful when a binary appears from somewhere unexpected.
rpm -qaList all installed RPM packages. The equivalent of dpkg -l on Red Hat-based systems.
rpm -ql nginxList every file installed by the nginx RPM package.
rpm -qf /usr/sbin/nginxFind out which RPM package owns a particular file.
dnf provides /usr/sbin/nginxFind which package in the repository provides a given file or capability. Useful when you know what you need but not what package it lives in.
Security updates
Both package management families distinguish between security updates and general updates. On production systems it is common to apply only security patches automatically rather than pulling in every new feature release.
apt-get upgrade --with-new-pkgs -sSimulate an upgrade to see what would change without making any modifications. The -s flag is dry-run.
unattended-upgrade --dry-runPreview what the unattended-upgrades daemon would install. The daemon applies security updates automatically on a schedule when configured.
dnf upgrade --securityUpgrade only packages for which security advisories exist. Leaves other updates untouched.
dnf updateinfo list securityList available security advisories without applying anything.
On Debian and Ubuntu, the unattended-upgrades package handles automated security patching. It reads from a configuration file that specifies which update categories to apply automatically. Enabling it on production servers is common practice because keeping up with security patches manually is unreliable over time.
Where it fits
Package managers sit at the foundation of how Linux systems are provisioned and maintained. Configuration management tools like Ansible, Chef and Puppet all call the underlying package manager to install software. Container image builds almost always start with a layer of package installations. Server setup scripts run apt install before anything else happens.
In a production context, the package manager connects to everything around it. Security scanning tools check installed package versions against known vulnerability databases. Compliance frameworks want evidence that systems are kept patched. Deployment pipelines need consistent package versions across environments so that what works in staging reflects what runs in production.
The recurring failure mode is treating package management as a one-time setup step rather than an ongoing concern. Software accumulates on servers over time. Packages go unupdated. Dependencies drift between machines that were set up at different points. The package manager gives you the tools to audit that state, correct it and keep it consistent. Using those tools regularly is what separates a well-maintained system from one that surprises you at the worst possible moment.