Package Management (dnf & apt)¶
Almost everything you install on Linux comes from a package delivered through a repository. This page covers dnf and rpm on AlmaLinux 9 / RHEL 9, the apt/dpkg equivalents on Debian/Ubuntu, and how to keep a system patched.
Tested on
AlmaLinux 9.4 (dnf/rpm) and Ubuntu 22.04 LTS (apt/dpkg).
Packages vs repositories¶
- A package is a single bundled archive of files plus metadata (name, version, dependencies). On RHEL-family systems these are
.rpmfiles; on Debian-family systems they are.debfiles. - A repository is a server-hosted collection of packages plus an index. Your package manager downloads the index, resolves dependencies, and pulls in everything needed.
dnf(andapt) are the high-level tools that talk to repositories and resolve dependencies.rpm(anddpkg) are the low-level tools that operate on individual package files already on disk — they do not resolve dependencies from the network.
RHEL / AlmaLinux: dnf¶
dnf is the default package manager on RHEL 8/9, AlmaLinux, Rocky, and Fedora. (yum still exists as a symlink to dnf for compatibility.)
Installing, removing, updating¶
# Install a package (and its dependencies)
sudo dnf install httpd
# Install without the yes/no prompt
sudo dnf install -y httpd
# Remove a package (leaves dependencies that other packages still need)
sudo dnf remove httpd
# Update a single package to the latest available version
sudo dnf update httpd
# Update EVERYTHING on the system (the most common patching command)
sudo dnf update
update vs upgrade on dnf
On dnf, update and upgrade are aliases — they do the same thing. (This differs from apt, where they are very different commands.) dnf upgrade is the modern preferred spelling.
Searching and inspecting¶
# Search package names and summaries for a keyword
dnf search nginx
# Show detailed info about a package (version, size, license, description)
dnf info httpd
# List installed packages, or available packages
dnf list installed
dnf list available
dnf list installed 'php*' # glob match
# Which package provides a given file or command?
dnf provides /usr/sbin/httpd
dnf provides '*/semanage' # find the package owning a missing command
Repositories¶
# List enabled repositories
dnf repolist
# List ALL repos including disabled ones
dnf repolist --all
Repository definitions live in /etc/yum.repos.d/ as *.repo files:
# /etc/yum.repos.d/example.repo
[example]
name=Example Repository
baseurl=https://repo.example.com/el9/$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.example.com/RPM-GPG-KEY-example
Enable or disable a repo for a single command, or permanently:
# Use a disabled repo just for this transaction
sudo dnf install --enablerepo=crb some-package
# Skip a repo just for this transaction
sudo dnf update --disablerepo=epel
# Permanently enable/disable a repo
sudo dnf config-manager --set-enabled crb
sudo dnf config-manager --set-disabled epel
EPEL (Extra Packages for Enterprise Linux)¶
EPEL is a community repository with thousands of packages not shipped in the base RHEL repos (e.g. htop, fail2ban, nginx modules).
# Enable EPEL on AlmaLinux/Rocky/RHEL 9
sudo dnf install epel-release
# Some EPEL packages also need the CRB (CodeReady Builder) repo
sudo dnf config-manager --set-enabled crb
# Now EPEL packages are available
sudo dnf install htop
Package groups¶
Groups bundle related packages (e.g. a whole desktop or development toolset).
# List available groups
dnf group list
# See what a group contains
dnf group info "Development Tools"
# Install a group
sudo dnf group install "Development Tools"
History and undo¶
dnf records every transaction, and you can roll one back — extremely useful when an update breaks something.
ID | Command line | Date and time | Action(s) | Altered
-------------------------------------------------------------------------------
14 | install nginx | 2026-06-07 09:12 | Install | 3
13 | update | 2026-06-06 22:01 | Upgrade | 47
12 | install epel-release | 2026-06-05 14:33 | Install | 1
# Inspect what a specific transaction did
dnf history info 14
# Undo a transaction (reverse it)
sudo dnf history undo 14
# Redo a transaction
sudo dnf history redo 14
Cleaning the cache¶
# Remove cached package metadata and downloaded packages
sudo dnf clean all
# Rebuild the metadata cache
sudo dnf makecache
Low-level: rpm¶
rpm queries and operates on packages directly. It does not resolve dependencies — use dnf for installs. rpm is mainly for inspection.
# List ALL installed packages
rpm -qa
# Is a specific package installed?
rpm -qa | grep httpd
rpm -q httpd
# Detailed info about an installed package
rpm -qi httpd
# List all files a package installed
rpm -ql httpd
# Which package owns a given file? (q-uery the f-ile)
rpm -qf /etc/httpd/conf/httpd.conf
Mnemonic
-qa = query all, -qi = query info, -ql = query list of files, -qf = query owning file.
Debian / Ubuntu: apt¶
On Debian, Ubuntu, and derivatives, the high-level tool is apt and the low-level tool is dpkg.
# Refresh the package index (ALWAYS run this first — apt does NOT auto-refresh)
sudo apt update
# Upgrade installed packages, but never remove anything
sudo apt upgrade
# Upgrade, allowing packages to be removed/added if needed (kernel jumps, etc.)
sudo apt full-upgrade
# Install / remove / fully remove (incl. config files)
sudo apt install nginx
sudo apt remove nginx # leaves config files behind
sudo apt purge nginx # removes config files too
# Remove no-longer-needed dependencies
sudo apt autoremove
# Search and show
apt search nginx
apt show nginx
apt update is not apt upgrade
On Debian/Ubuntu these are completely different: apt update only refreshes the index of available versions; apt upgrade actually installs them. You must run update before upgrade or you'll install stale versions. (On dnf a single dnf upgrade does both.)
Low-level: dpkg¶
# List installed packages
dpkg -l
dpkg -l | grep nginx
# List files installed by a package
dpkg -L nginx
# Which package owns a file?
dpkg -S /usr/sbin/nginx
Adding repositories and PPAs¶
# Add an extra repository component, then refresh
sudo add-apt-repository universe
sudo apt update
# Add a PPA (Personal Package Archive — Ubuntu only)
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.12
Repository definitions live in /etc/apt/sources.list and /etc/apt/sources.list.d/*.list (or modern .sources files). GPG keys typically live in /etc/apt/keyrings/.
dnf ↔ apt cheat sheet¶
| Task | dnf (RHEL/AlmaLinux) | apt (Debian/Ubuntu) |
|---|---|---|
| Refresh index | (automatic) | apt update |
| Install | dnf install pkg |
apt install pkg |
| Remove | dnf remove pkg |
apt remove pkg |
| Remove + config | dnf remove pkg |
apt purge pkg |
| Update everything | dnf upgrade |
apt update && apt upgrade |
| Search | dnf search term |
apt search term |
| Package info | dnf info pkg |
apt show pkg |
| List installed | dnf list installed / rpm -qa |
apt list --installed / dpkg -l |
| Files in a package | rpm -ql pkg |
dpkg -L pkg |
| Which package owns a file | rpm -qf /path |
dpkg -S /path |
| Clean unused deps | dnf autoremove |
apt autoremove |
| List repos | dnf repolist |
cat /etc/apt/sources.list* |
Keeping a system patched¶
A patched system is your single biggest security win. A simple routine:
# AlmaLinux/RHEL — apply all security and bugfix updates
sudo dnf upgrade --refresh
# Apply ONLY security updates
sudo dnf upgrade --security
# Check whether a reboot is needed (e.g. after a kernel update)
dnf needs-restarting -r
# Ubuntu/Debian
sudo apt update && sudo apt full-upgrade
# Was a reboot required? (file exists = yes)
ls -l /var/run/reboot-required 2>/dev/null
Automate security patches
On RHEL/AlmaLinux install dnf-automatic to apply updates on a timer. On Ubuntu, unattended-upgrades does the same. Always test updates on a staging host before production, and ensure you have a rollback path (dnf history undo, snapshots, or backups).
Reboots and the kernel
dnf upgrade may install a new kernel, but you keep running the old one until you reboot. Schedule reboots for kernel and glibc updates. Manage which services restart automatically with care — see systemd Service Management.
Verify your work¶
# RHEL/AlmaLinux: confirm a package is installed and at the expected version
rpm -q httpd
dnf list installed httpd
# Confirm your repos are healthy
dnf repolist
# Confirm there are no pending updates (exit code 0 = up to date)
dnf check-update; echo "exit: $?"
A patched system shows no pending updates and a clean dnf repolist with all expected repos enabled.
Summary¶
dnf(RHEL/AlmaLinux) andapt(Debian/Ubuntu) are high-level managers that resolve dependencies from repositories;rpmanddpkgare low-level tools for inspecting installed packages.- Install/remove/update with
dnf install|remove|upgrade; search and inspect withdnf search|info|list|provides; manage repos withdnf repolistandconfig-manager. dnf historylets you review and undo transactions — a lifesaver after a bad update.- Enable EPEL with
dnf install epel-release(pluscrb) for community packages. - On
apt, alwaysapt updatebeforeapt upgrade; usepurgeto drop config files andautoremoveto clean orphans. - Keep systems patched regularly (
dnf upgrade/apt full-upgrade), reboot for kernel updates, and consider automated security updates.