Manage Software Packages
Master software management using DNF/YUM. Learn to install, update, remove packages, manage repositories, work with package groups, and handle AppStream module streams on RHEL 9.
📋 Table of Contents
🎯 Introduction
Package management is a core skill for Red Hat administrators. RHEL uses RPM (Red Hat Package Manager) format packages managed by DNF (Dandified YUM) - the successor to YUM. DNF handles dependency resolution, repository management, and transaction history.
Key Concepts
- RPM Package: Pre-compiled software bundle (.rpm file)
- Repository: Collection of packages with metadata
- DNF/YUM: High-level package managers (handle dependencies)
- rpm: Low-level tool (no automatic dependency resolution)
- AppStream: RHEL 9 repository with multiple software versions
- BaseOS: Core operating system packages
On RHEL 9, yum is a symbolic link to dnf. Both commands work identically.
DNF is faster, more efficient, and has better dependency resolution than YUM.
RHEL 9 Repository Structure
| Repository | Content |
|---|---|
| BaseOS | Core OS packages (kernel, systemd, bash) |
| AppStream | Applications, languages, databases (multiple versions) |
| Extras | Additional tools and utilities |
📦 DNF/YUM Basics
Installing Packages
# Install a package
sudo dnf install httpd
# Install multiple packages
sudo dnf install httpd mariadb-server php
# Install without confirmation
sudo dnf install -y nginx
# Install specific version
sudo dnf install httpd-2.4.51
# Download package without installing
sudo dnf download httpd
# Install downloaded RPM with dependencies
sudo dnf install ./httpd-2.4.51-7.el9.x86_64.rpm
# Reinstall a package
sudo dnf reinstall httpd
Updating Packages
# Check for updates
sudo dnf check-update
# Update all packages
sudo dnf update
# Update specific package
sudo dnf update httpd
# Update to latest security patches only
sudo dnf update --security
# Update without updating kernel
sudo dnf update --exclude=kernel*
# Download updates without installing
sudo dnf update --downloadonly
Removing Packages
# Remove a package
sudo dnf remove httpd
# Remove with dependencies
sudo dnf autoremove httpd
# Clean up unused dependencies
sudo dnf autoremove
# Remove old kernel versions (keep latest 3)
sudo dnf remove --oldinstallonly --setopt installonly_limit=3
Searching and Querying
# Search for package
dnf search nginx
dnf search web server
# Find which package provides a file
dnf provides /usr/sbin/httpd
dnf provides */semanage
# Show package information
dnf info httpd
# List all packages
dnf list all
# List installed packages
dnf list installed
# List available packages
dnf list available
# List recent packages
dnf list recent
# Show package groups
dnf group list
# Check if package is installed
dnf list installed httpd
Package Information
# Display package details
dnf info httpd
# Show dependencies
dnf repoquery --requires httpd
# Show what depends on this package
dnf repoquery --whatrequires httpd
# List files in package
dnf repoquery -l httpd
# Show changelog
dnf changelog httpd
DNF History
# Show transaction history
sudo dnf history
# Show details of specific transaction
sudo dnf history info 5
# Undo a transaction
sudo dnf history undo 5
# Redo a transaction
sudo dnf history redo 5
# Rollback to specific transaction
sudo dnf history rollback 10
# List all transaction IDs
sudo dnf history list
Cleaning Up
# Clean cache
sudo dnf clean all
# Clean only metadata
sudo dnf clean metadata
# Clean packages
sudo dnf clean packages
# Remove duplicate packages
sudo dnf remove --duplicates
# Check for problems
sudo dnf check
- Use
dnf whatprovidesto find which package provides a command - Add
-yto skip confirmation prompts in scripts - Use
dnf historyto track and undo package changes - The
dnf repoquerycommand is powerful for package research
🗄️ Managing Repositories
Viewing Repositories
# List all enabled repositories
dnf repolist
# List all repositories (enabled and disabled)
dnf repolist all
# Show detailed repo information
dnf repoinfo
# Show specific repository
dnf repoinfo baseos
Repository Configuration Files
Repository configurations are stored in:
/etc/yum.repos.d/*.repo- Repository definition files/etc/dnf/dnf.conf- Main DNF configuration
Repository File Format
# Example: /etc/yum.repos.d/example.repo
[repository-id]
name=Repository Name
baseurl=https://repo.example.com/rhel9/
# or
metalink=https://mirrors.example.com/metalink?repo=rhel9
# or
mirrorlist=https://mirrors.example.com/mirrorlist?repo=rhel9
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-example
Common Repository Operations
# Enable a repository temporarily (one command)
sudo dnf install httpd --enablerepo=extras
# Disable a repository temporarily
sudo dnf install httpd --disablerepo=appstream
# Enable a repository permanently
sudo dnf config-manager --set-enabled extras
# Disable a repository permanently
sudo dnf config-manager --set-disabled extras
# Add a new repository
sudo dnf config-manager --add-repo https://example.com/repo/rhel9.repo
# Install config-manager if not present
sudo dnf install dnf-plugins-core
Procedure: Adding EPEL Repository
- Install EPEL release package:
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm - Verify repository is enabled:
dnf repolist | grep epel - Search for EPEL packages:
dnf search htop - Install package from EPEL:
sudo dnf install htop
Creating a Local Repository
# Install required tools
sudo dnf install createrepo
# Create directory for packages
sudo mkdir -p /var/local-repo
# Copy RPM files
sudo cp *.rpm /var/local-repo/
# Create repository metadata
sudo createrepo /var/local-repo/
# Create repo file
sudo vi /etc/yum.repos.d/local.repo
[local]
name=Local Repository
baseurl=file:///var/local-repo
enabled=1
gpgcheck=0
# Clean and update cache
sudo dnf clean all
sudo dnf repolist
Repository Priority
# Install priority plugin
sudo dnf install dnf-plugin-priorities
# Set priority in repo file (lower number = higher priority)
[high-priority-repo]
name=High Priority Repo
baseurl=https://repo.example.com/
enabled=1
priority=1
[normal-repo]
name=Normal Repo
baseurl=https://other.example.com/
enabled=1
priority=10
GPG Key Management
# Import GPG key
sudo rpm --import https://example.com/RPM-GPG-KEY
# List imported keys
rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n'
# Verify package signature
rpm --checksig package.rpm
# Install package without GPG check (not recommended)
sudo dnf install --nogpgcheck package.rpm
📚 Package Groups
Package groups are collections of related packages that can be installed together.
Working with Groups
# List all groups
dnf group list
# List all groups (including hidden)
dnf group list --hidden
# Show group information
dnf group info "Development Tools"
# Install a group
sudo dnf group install "Development Tools"
# Install group without optional packages
sudo dnf group install --with-optional "Server with GUI"
# Remove a group
sudo dnf group remove "Development Tools"
# Update a group
sudo dnf group update "System Tools"
# Mark group as installed (without installing packages)
sudo dnf group mark install "Development Tools"
Common Package Groups
| Group Name | Purpose |
|---|---|
| Development Tools | Compilers, make, gcc, git |
| System Tools | Administrative tools |
| Server with GUI | Graphical environment for servers |
| Workstation | Desktop applications |
| Virtualization Host | KVM, libvirt, QEMU |
Environment Groups
# List environments
dnf group list --ids
# Show environment details
dnf group info "Server with GUI"
# Install environment
sudo dnf install @"Server with GUI"
# Switch to graphical target
sudo systemctl set-default graphical.target
🔧 AppStream Modules
AppStream provides multiple versions of software through module streams. This allows you to choose specific versions of applications (e.g., Python 3.9 vs 3.11, PostgreSQL 13 vs 15).
Module Concepts
- Module: Collection of packages (e.g., postgresql)
- Stream: Version of the module (e.g., 13, 15)
- Profile: Subset of packages for a use case (e.g., server, client)
Working with Modules
# List all modules
dnf module list
# List specific module streams
dnf module list postgresql
# Show module information
dnf module info postgresql
# Show specific stream
dnf module info postgresql:15
# List installed modules
dnf module list --installed
Enabling and Installing Modules
# Enable a module stream (doesn't install packages)
sudo dnf module enable postgresql:15
# Install default profile of enabled stream
sudo dnf module install postgresql:15
# Install specific profile
sudo dnf module install postgresql:15/server
# Enable and install in one command
sudo dnf install @postgresql:15/server
# Install multiple profiles
sudo dnf module install postgresql:15/{server,client}
Switching Module Streams
# Check current stream
dnf module list postgresql
# Reset module
sudo dnf module reset postgresql
# Switch to different stream
sudo dnf module enable postgresql:13
sudo dnf distro-sync
# Alternative: remove and install different stream
sudo dnf module remove postgresql:15
sudo dnf module reset postgresql
sudo dnf module install postgresql:13
Module Management
# Disable a module
sudo dnf module disable postgresql
# Remove installed module
sudo dnf module remove postgresql:15
# Reset module state
sudo dnf module reset postgresql
# Show module profiles
dnf module info --profile postgresql:15
Procedure: Installing Python 3.11 Module
- List available Python versions:
dnf module list python3* - View Python 3.11 module details:
dnf module info python39:3.11 - Enable Python 3.11 stream:
sudo dnf module enable python39:3.11 - Install Python 3.11:
sudo dnf install python3 - Verify installation:
python3 --version
Common Modules
| Module | Common Streams |
|---|---|
| postgresql | 13, 15 |
| python39 | 3.9, 3.11 |
| nodejs | 16, 18, 20 |
| ruby | 3.0, 3.1 |
Only one stream of a module can be enabled at a time. To switch streams, you must first reset or disable the current stream.
⚙️ RPM Commands
The rpm command is the low-level package manager. It doesn't handle dependencies automatically.
Querying Packages
# List all installed packages
rpm -qa
# Query specific package
rpm -q httpd
# Show package information
rpm -qi httpd
# List files in package
rpm -ql httpd
# List documentation files
rpm -qd httpd
# List configuration files
rpm -qc httpd
# Show package dependencies
rpm -qR httpd
# Find which package owns a file
rpm -qf /usr/sbin/httpd
# Query package file (not installed)
rpm -qip package.rpm
rpm -qlp package.rpm
Installing/Removing with RPM
# Install RPM package (no dependency resolution)
sudo rpm -ivh package.rpm
# i = install, v = verbose, h = hash marks (progress)
# Upgrade package
sudo rpm -Uvh package.rpm
# U = upgrade (install if not present)
# Freshen (upgrade only if already installed)
sudo rpm -Fvh package.rpm
# Remove package
sudo rpm -e httpd
# Force remove (ignore dependencies - dangerous!)
sudo rpm -e --nodeps httpd
# Install without running scripts
sudo rpm -ivh --noscripts package.rpm
Verifying Packages
# Verify all installed packages
sudo rpm -Va
# Verify specific package
sudo rpm -V httpd
# Verify files from package
sudo rpm -Vf /usr/sbin/httpd
# Output codes:
# S = Size differs
# M = Mode differs (permissions)
# 5 = MD5 sum differs
# D = Device differs
# L = Link differs
# U = User ownership differs
# G = Group ownership differs
# T = mTime differs
# P = capabilities differ
Extracting RPM Contents
# Extract files from RPM without installing
rpm2cpio package.rpm | cpio -idmv
# Extract specific file
rpm2cpio package.rpm | cpio -idmv ./usr/bin/command
Use DNF when: Installing, updating, or removing packages (handles dependencies)
Use RPM when: Querying installed packages, verifying, or low-level operations
📝 Practice Questions
Question 1: What command installs httpd and all its dependencies?
DNF (and YUM) automatically resolve and install dependencies. RPM commands (rpm -ivh) do NOT handle dependencies automatically and will fail if dependencies are missing.
Question 2: How do you find which package provides the /usr/sbin/semanage command?
dnf provides (or dnf whatprovides) searches for which package provides a specific file. rpm -qf only works if the package is already installed. You can also use: dnf provides */semanage
Question 3: What's the correct way to switch from PostgreSQL 13 to PostgreSQL 15?
To switch module streams, you must first reset the current stream, then install the new one. Alternatively: dnf module remove postgresql:13, then reset, then install postgresql:15.
Question 4: How do you list all files installed by the httpd package?
rpm -ql (query list) shows all files from a package. You can also use: dnf repoquery -l httpd. rpm -qa lists all installed packages, not files.
Question 5: What does 'dnf group install "Development Tools"' do?
Package groups bundle related packages. "Development Tools" includes compilers (gcc), build tools (make), version control (git), and libraries needed for software development.