Package Management with yum and rpm on CentOS: Install, Remove, and Manage Repositories

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

A Real-World Story: Why You Need to Understand yum and rpm

When CentOS 8 announced its EOL at the end of 2021, I had to urgently migrate 5 servers to Rocky Linux within a week. The biggest headache wasn’t the new OS — it was the entire list of packages running in production that needed to be reinstalled, version-checked, and verified for missing dependencies. That’s when I realized: just knowing how to type yum install and move on simply isn’t enough.

If you’re managing a CentOS server (or Rocky, AlmaLinux), yum is the tool you use every day. And rpm is the underlying layer — when yum isn’t enough, you need to drop down to rpm and do things manually.

Background: What’s the Difference Between yum and rpm?

A simple way to think about it: rpm is like installing an app from an .exe file on Windows — you have the file, you install it, done. If the app needs an additional library that isn’t on the machine? That’s your problem. yum is more like an App Store — it automatically finds, downloads, and installs everything needed, including all dependencies.

  • rpm: operates directly on .rpm files, does not resolve dependencies automatically
  • yum: high-level package manager, connects to online repositories, handles dependencies automatically

In practice, yum covers 90% of day-to-day work. But there are situations where you’re forced to drop down to rpm: installing packages offline, tracing which package owns a particular file, or removing a stubborn package that refuses to uninstall through yum.

Essential yum Commands to Know

Installing and Removing Packages

# Install a new package
yum install nginx

# Install multiple packages at once
yum install nginx mysql-server php-fpm

# Remove a package (keep dependencies)
yum remove nginx

# Remove the package along with unused dependencies
yum autoremove nginx

Updating Packages

# Update all packages
yum update

# Update a single package
yum update nginx

# List available updates without applying them
yum check-update

A small tip: before updating a production server, I always run yum check-update first to see what’s changing. If I spot the kernel or glibc in the list, I’ll think twice rather than blindly updating everything.

Searching and Getting Package Information

# Search for a package by name
yum search nginx

# View detailed package information
yum info nginx

# Find which package provides a specific file or command
yum provides /usr/bin/python3
yum provides "*/nginx.conf"

Managing Repositories with yum

A repository (repo) is a package store. CentOS ships with a few official repos by default, but many popular software packages like Nginx stable, Node.js LTS, or MariaDB have their own repos maintained by the developers — offering newer versions that are better tested than the default repos.

Listing Enabled Repositories

# List all active repos
yum repolist

# List all repos including disabled ones
yum repolist all

# View details for a specific repo
yum repoinfo base

Adding a New Repository

EPEL is the most popular extended repo for RHEL-based systems, providing over 8,000 packages not available in the default repos (htop, iftop, fail2ban, etc.):

# Install the EPEL repository
yum install epel-release

# Confirm EPEL has been added
yum repolist | grep epel

If you need to add a repo manually, create a .repo file in /etc/yum.repos.d/:

# Create a repo file for Nginx stable
cat > /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
EOF

# Install nginx from the newly added repo
yum install nginx

Temporarily Enabling or Disabling a Repo

# Install a package from a specific repo (does not permanently affect config)
yum --enablerepo=epel install htop

# Disable a repo during install (e.g., to avoid conflicts)
yum --disablerepo=epel install nginx

Working Directly with rpm

Installing a Package from an .rpm File

The most common use case is when you’ve downloaded an .rpm file from a vendor’s website and need to install it offline or install a specific version that isn’t available in any repo.

# Install from a local .rpm file
rpm -ivh package.rpm

# Common flags:
# -i = install
# -v = verbose (show details)
# -h = show progress bar (#####)

# Upgrade (if an older version is already installed)
rpm -Uvh package.rpm

# Install while skipping dependency checks (NOT recommended)
rpm -ivh --nodeps package.rpm

Querying Installed Packages

# List all installed packages
rpm -qa

# Search for a package by name
rpm -qa | grep nginx

# View detailed package information
rpm -qi nginx

# List all files belonging to a package
rpm -ql nginx

# Find out which package owns a specific file
rpm -qf /etc/nginx/nginx.conf

rpm -qf is incredibly useful for debugging. During that 5-server migration, I used this command to trace config files back to their package names, then compiled a complete list of everything that needed to be reinstalled on the new Rocky Linux servers.

Removing a Package with rpm

# Remove a package (exact name required)
rpm -e nginx

# Remove while skipping dependency checks
rpm -e --nodeps nginx

Using --nodeps when removing is a double-edged sword. I once removed a shared library with this flag and brought down a whole set of applications that depended on it — it took 2 hours to clean up. Only use it when you know exactly what you’re doing.

Handling Common Scenarios

Dependency Errors When Installing a Package

# View a package's dependencies before installing
yum deplist nginx

# If you hit a dependency error, try clearing the cache and reinstalling
yum clean all
yum makecache
yum install nginx

Rolling Back After an Update

# View the history of yum transactions
yum history

# View details for transaction #5
yum history info 5

# Undo transaction #5 (rollback)
yum history undo 5

yum history undo has saved me several times when a kernel or glibc update left the server unable to boot. My habit: before updating production, note the current transaction ID. When something goes wrong, the rollback takes less than 30 seconds.

Downloading a Package Without Installing It

# Download a package (and its dependencies) to the current directory
yum install --downloadonly --downloaddir=/tmp/packages nginx

# Then install offline
rpm -ivh /tmp/packages/*.rpm

Verifying and Maintaining Your Package System

Verifying the Integrity of Installed Packages

# Verify checksums and permissions of all files in a package
rpm -V nginx

# Empty output = nothing has changed (good)
# Any output lines = files have been modified since installation

# Verify all installed packages (takes a while to run)
rpm -Va 2>/dev/null | grep -v "^.....UG"

Cleaning Up the Cache

# Remove downloaded package cache
yum clean packages

# Remove all cache (headers + metadata + packages)
yum clean all

# Rebuild the metadata cache
yum makecache

Exporting the Package List for Reinstallation

A trick I use every time I’m preparing for a migration — it saves at least an hour compared to trying to remember every package from scratch:

# Export the list of installed packages (names only)
rpm -qa --qf "%{NAME}\n" | sort > installed-packages.txt

# On the new server, reinstall from the list
yum install $(cat installed-packages.txt)

Not every package will install right away — some require additional repos to be added first. But at least you have a complete list and won’t miss anything.

Quick Summary

Going back to that 5-server migration: if I hadn’t known rpm -qf, yum history undo, and how to export a package list, the whole thing could have taken twice as long. Truly understanding yum and rpm isn’t about memorizing commands — it’s about knowing which tool to reach for when things don’t go according to plan.

One note if you’re on CentOS Stream 9 or Rocky/Alma: yum is actually an alias for dnf — the syntax is similar, but dnf adds module streams and a better dependency solver. All the commands in this article work just fine either way.

Share: