Package Management Basics: Getting Started with apt and yum

Package Management Basics: Getting Started with apt and yum

What you'll be able to do

  • Map apt and dnf commands and pick each one with a reason
  • Check the impact before installing so changes stay safe
  • Work through the standard package-management errors step by step

Prerequisites (read these first)

What You'll Learn

  • You can map apt and yum/dnf commands side by side.
  • You can search, install, update, and remove packages with a reliable workflow.
  • You can check the impact before installing so the change stays safe.
  • You can decide between yum and dnf, and tell update apart from upgrade.
  • You can diagnose common errors such as Unable to locate package and NO_PUBKEY.

Quick Summary

  • apt (Debian / Ubuntu / Mint) and dnf (RHEL 9 / Rocky / AlmaLinux / Fedora) are the current standards
  • yum is only native on CentOS 7 / RHEL 7. On RHEL 8+ yum is a compatibility symlink to dnf
  • Always refresh the index first (apt update / dnf makecache), then install
  • Never install from memory — confirm the exact package name with search or info first

Assumed Environment

  • Debian-family: Ubuntu 20.04 / 22.04 / 24.04, Debian 11 / 12
  • RHEL-family: CentOS 7 (yum), Rocky Linux 8/9, AlmaLinux 8/9, RHEL 8/9 (dnf)
  • All commands run as a regular user with sudo. Direct root login is not assumed.

0. Six Terms to Settle First

Conclusion: Package, repository, index, and dependency unlock most error messages.

Package-management error messages are unreadable without the vocabulary. Here are the six words worth defining up front.

Term One-line meaning Other names you'll see
package One piece of software bundled into a distributable file ".deb" and ".rpm" mean the same thing
repository The server that hosts and distributes packages Also "repo" or "source"
index The catalog of what a repository currently offers Also "package list" or "cache"
dependency Another package that must be present for this one to run Also "dependent package"
metapackage An empty shell package that pulls in a whole group of packages Also "bundle package"
GPG key The signing key used to verify a repository is genuine Also "signing key" or "public key"

apt update refreshes the index. It does not upgrade any installed software. Upgrading the software itself is apt upgrade. Mixing up these two is the most common misunderstanding.

1. apt vs yum/dnf Command Map

Conclusion: install, remove, and search match; only index refresh and purge wording differ.

The single most useful table you can keep handy.

Operation Debian (apt) RHEL (dnf / yum)
Refresh the package index sudo apt update sudo dnf makecache
List upgradable packages apt list --upgradable dnf check-update
Install a package sudo apt install <pkg> sudo dnf install <pkg>
Upgrade everything sudo apt upgrade sudo dnf upgrade
Remove (keep config) sudo apt remove <pkg> sudo dnf remove <pkg>
Remove + purge configs sudo apt purge <pkg> (no direct equivalent)
Search apt search <kw> dnf search <kw>
Show details apt show <pkg> dnf info <pkg>
List installed apt list --installed dnf list installed
Remove orphaned dependencies sudo apt autoremove sudo dnf autoremove
Clean cache sudo apt clean sudo dnf clean all
List repositories apt policy dnf repolist

Memory hook: install / remove / search are identical. The differences live in how you refresh the index and how you "purge" configuration files.

2. apt: Minimum Viable Workflow

Conclusion: With apt, run update first, then install, search, upgrade, and remove or purge.

From here on, the commands change the system. Know what changes and how to undo it before you run them.

Command What it changes How to undo Safer way to try it
update Only the package index is refreshed Nothing to undo (the system is untouched) Safe to run as-is
install The package and its dependencies are added remove deletes it apt-get install -s <pkg> previews the plan
upgrade Installed packages move to newer versions Pin each version back by hand (laborious) List targets first with apt list --upgradable
remove Binaries go away; config files under /etc/ stay install puts it back apt-get remove -s <pkg> previews the scope
purge Binaries and config files under /etc/ are deleted Configs cannot be restored without a backup Copy the config files somewhere first
autoremove Every dependency judged "no longer needed" is deleted at once Reinstall each package individually Read the deletion list before confirming

2-1. Refresh → Install

$ sudo apt update
$ sudo apt install nginx

Skipping apt update is the #1 cause of install failures on fresh VMs (stale index hits 404s on the mirror). Always refresh before install on new or long-idle systems.

2-2. Search (when you only remember part of the name)

$ apt search nginx
$ apt show nginx

apt search does full-text search across descriptions, which is why "search for nginx" returns dozens of results. To narrow down to actual names, use a glob:

$ apt list 'nginx*'
Listing... Done
nginx/jammy-updates 1.18.0-6ubuntu14.4 amd64
nginx-common/jammy-updates 1.18.0-6ubuntu14.4 all
nginx-core/jammy-updates 1.18.0-6ubuntu14.4 amd64

The columns read: package name and source, version, then architecture.

To see only what is already installed:

$ apt list --installed 2>/dev/null | grep nginx

2-3. Upgrade

$ sudo apt update
$ sudo apt upgrade           # Bump installed packages
$ sudo apt full-upgrade      # Allow removals to resolve deps (kernels, etc.)

apt upgrade and apt full-upgrade (formerly dist-upgrade) are not the same. Kernel and systemd jumps may need full-upgrade. Review the proposed changes before running on production.

2-4. Remove

$ sudo apt remove nginx      # Binary gone; /etc/ configs remain
$ sudo apt purge nginx       # Configs deleted too
$ sudo apt autoremove        # Drop orphaned dependencies

apt remove leaves files in /etc/ behind. If a reinstall "remembers" old settings unexpectedly, run purge to wipe them.

3. yum / dnf: Minimum Viable Workflow

Conclusion: On RHEL 8+ dnf is native and yum is a symlink, so write dnf directly in scripts.

3-1. yum vs dnf — Which One Do I Use?

  • CentOS 7 / RHEL 7: yum is native
  • CentOS 8+ / Rocky 8+ / AlmaLinux 8+ / RHEL 8+ / Fedora: dnf is native; the yum command is a compatibility wrapper around dnf

On RHEL 8+, typing yum install ... still works — but you're really invoking dnf. For scripts that need to survive future OS jumps, write dnf directly.

3-2. Core Operations

$ sudo dnf check-update            # Show available updates
$ sudo dnf install nginx
$ sudo dnf upgrade                 # Upgrade all
$ sudo dnf remove nginx
$ dnf search nginx
$ dnf info nginx
$ dnf list installed | grep nginx

dnf remove <pkg> also queues up any package that depends on the one you named. Read the deletion list it prints and confirm nothing unexpected is in it. On RHEL-family systems, dnf history undo <ID> rolls the last transaction back (covered below).

3-3. Group Install (a dnf strength)

Install a bundle of related packages in one step.

$ dnf grouplist
$ sudo dnf groupinstall "Development Tools"

Debian-family achieves the same outcome through meta-packages instead:

$ sudo apt install build-essential

Conclusion: Search by name pattern, reverse-lookup by file, then verify the official name.

"I forgot the exact package name" is the most common stumbling block. These three patterns cover almost every case.

4-1. Narrow by Name Pattern

# Debian
$ apt list 'php*' 2>/dev/null

# RHEL
$ dnf list 'php*'

4-2. Reverse Lookup from a Binary or File

When you know the command name but not the package, use apt-file / dnf provides.

# Debian (apt-file is not installed by default)
$ sudo apt install apt-file
$ sudo apt-file update
$ apt-file search /usr/bin/htop

# RHEL (built in)
$ dnf provides /usr/bin/htop
$ dnf provides '*/sshd_config'

When command not found strikes, starting with dnf provides or apt-file search is the fastest path to "which package do I need to install?".

4-3. Verify You Have the Right Package

$ apt show nginx
$ dnf info nginx

Check Version, Source, and Homepage to distinguish the package you want from a same-named impostor.

5. Repository Inspection

Conclusion: List active repos, add only vendor repos, and verify the GPG key fingerprint.

5-1. List Active Repositories

# Debian
$ apt policy                              # Per-package source priorities
$ ls /etc/apt/sources.list.d/             # Extra repo definitions
$ cat /etc/apt/sources.list

# RHEL
$ dnf repolist                            # Enabled repos
$ dnf repolist --all                      # Include disabled
$ ls /etc/yum.repos.d/

5-2. Adding a Third-Party Repository — Caveats

Third-party repos expand your trust boundary.

  • Only add repos from vendors with a published security process (Docker, PostgreSQL, NodeSource, etc.)
  • Verify the GPG key fingerprint against the vendor's official documentation
  • Avoid blind curl ... | sudo bash on production servers — read the script first

5-3. Modern Repo-Add Pattern (Debian-family)

Ubuntu 22.04+ deprecates apt-key. The recommended pattern is to place GPG keys under /etc/apt/keyrings/ and reference them from each source list with signed-by=.

# Stage the key (follow vendor instructions)
$ sudo install -d -m 0755 /etc/apt/keyrings
$ curl -fsSL https://download.example.com/key.gpg \
    | sudo tee /etc/apt/keyrings/example.gpg > /dev/null

# Repo definition
$ echo "deb [signed-by=/etc/apt/keyrings/example.gpg] https://download.example.com/apt stable main" \
    | sudo tee /etc/apt/sources.list.d/example.list
$ sudo apt update

5-4. How to Verify the Fingerprint

A fingerprint is a short identifier that summarizes a key. The same key always produces the same value, so comparing it tells you whether the key really came from the vendor.

Print the fingerprint of the key you placed and compare it character by character against the value published on the vendor's official site. The command only displays, so run it as often as you like.

$ gpg --show-keys --fingerprint /etc/apt/keyrings/example.gpg

If it does not match, the key is not the official one. Stop the setup and delete the files you placed under /etc/apt/keyrings/ and /etc/apt/sources.list.d/.

6. Troubleshooting the Common Errors

Conclusion: Missing package, lock, GPG, and disk space each have a set diagnosis path.

6-1. Unable to locate package <pkg> (apt)

Diagnose in this order:

  1. You skipped apt update
  2. The package name is wrong (python vs python3, etc.)
  3. The right repository component is disabled (e.g. universe / multiverse)
$ sudo apt update
$ apt search <approximate-keyword>
$ apt-cache policy <pkg>

6-2. No match for argument (dnf)

Same diagnosis. Frequently fixed by rebuilding metadata:

$ sudo dnf clean all
$ sudo dnf makecache
$ dnf search <approximate-keyword>

6-3. Could not get lock /var/lib/dpkg/lock

Another apt process is running, or a previous run crashed. Confirm first, then recover.

The lock files are empty. apt and dpkg do not check whether the file exists — they take a flock (an exclusive lock held on the file). So "the file is there, delete it" is the wrong instinct. Deleting is the last resort, only after confirming nobody holds them.

First check whether any process holds the four lock files. lsof only displays; it changes nothing.

$ sudo lsof /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock \
    /var/cache/apt/archives/lock /var/lib/apt/lists/lock

Empty output means nothing holds them. Only then is removal safe.

$ sudo rm /var/lib/dpkg/lock-frontend
$ sudo rm /var/lib/dpkg/lock
$ sudo rm /var/cache/apt/archives/lock
$ sudo rm /var/lib/apt/lists/lock
$ sudo dpkg --configure -a

6-4. GPG Errors (NO_PUBKEY / Signature couldn't be verified)

A third-party repo's signing key expired or was rotated.

$ sudo apt update
# -> NO_PUBKEY ABCD1234...

Fix by fetching the vendor's current key and placing it under /etc/apt/keyrings/. Avoid --allow-unauthenticated and never blindly run apt-key del.

6-5. Install Fails Due to Disk Space

$ df -h /var /usr
$ sudo apt clean        # Drop downloaded .deb files
$ sudo dnf clean all    # Same for dnf cache

/var/cache/apt/archives/ and /var/cache/dnf/ are the usual suspects.

7. Production Rules That Save Pain

Conclusion: On production avoid blind upgrade or curl-to-bash; review changes and keep undo.

Don't:

  • Run apt upgrade on production without first reviewing apt list --upgradable
  • Pipe untrusted install scripts into sudo bash
  • Reflexively add --force-yes / --allow-downgrades
  • Pull the same package from multiple repositories — priority conflicts get messy

Safe-operation checklist:

  1. Always refresh first: apt update / dnf makecache
  2. Simulate apt changes before applying: apt-get install -s <pkg>
  3. RHEL has transaction history you can roll back:
$ dnf history list
$ sudo dnf history undo <ID>
  1. Review upgrade scope with apt list --upgradable before running upgrade
  2. Verify GPG fingerprints whenever you add a new repository

8. Copy-Paste Templates

Conclusion: Ready-made command sets for Debian and RHEL families from setup to rollback.

Debian / Ubuntu

# First-time setup
sudo apt update && sudo apt upgrade -y

# Search -> inspect -> install
apt list 'nginx*'
apt show nginx
sudo apt install nginx

# Preview upgrades before applying
apt list --upgradable
sudo apt upgrade

# Remove including configs
sudo apt purge nginx && sudo apt autoremove

RHEL / Rocky / AlmaLinux

# First-time setup
sudo dnf upgrade -y

# Search -> inspect -> install
dnf search nginx
dnf info nginx
sudo dnf install nginx

# Preview updates
dnf check-update

# Roll back a transaction
dnf history list
sudo dnf history undo <ID>

Next Reading