Package Management¶
Every Linux distribution ships with a package manager - the tool responsible for installing, updating, and removing software. Understanding how packages work is fundamental to system administration because nearly everything on a Linux box, from the kernel to the smallest utility, arrived as a package.
Why Package Managers Exist¶
Before package managers, installing software meant downloading tarballs, compiling from source, and manually tracking dependencies. If program A needed library B version 2.3, and library B needed library C, you chased those dependencies by hand. Removing software was even worse - you had to remember every file the build process scattered across the filesystem.
Package managers solve this by maintaining a database of installed software, their files, and their dependencies. When you install a package, the manager resolves the full dependency tree, downloads everything needed, and places files in the correct locations. When you remove a package, it knows exactly which files to delete and whether any other package still needs a shared dependency.
Package Formats and Ecosystems¶
Linux distributions split into two major packaging families, plus a growing set of universal formats.
| Format | Extension | Distributions | High-level Tool | Low-level Tool |
|---|---|---|---|---|
| Debian | .deb |
Debian, Ubuntu, Mint, Pop!_OS | apt |
dpkg |
| RPM | .rpm |
RHEL, Fedora, CentOS, Rocky, openSUSE | dnf (or yum) |
rpm |
| Arch | .pkg.tar.zst |
Arch, Manjaro | pacman |
- |
| Universal | .snap, .flatpak, .AppImage |
Cross-distribution | snap, flatpak |
- |
The high-level tools handle dependency resolution, repository management, and downloading. The low-level tools operate on individual package files and know nothing about repositories.
High-level vs low-level
Think of apt and dnf as the tools you use 95% of the time. You only reach for dpkg or rpm when you need to install a local .deb/.rpm file directly, inspect package metadata, or troubleshoot.
APT (Debian/Ubuntu)¶
apt is the standard package management interface on Debian-based systems. It replaced the older apt-get and apt-cache commands with a single, more user-friendly tool.
Updating the Package Index¶
Before installing anything, update the local cache of available packages:
This downloads the latest package lists from every repository configured in /etc/apt/sources.list and /etc/apt/sources.list.d/. It does not install or upgrade anything - it just refreshes your local view of what's available.
Searching and Inspecting¶
# Search for packages by name or description
apt search nginx
# Show detailed information about a specific package
apt show nginx
# List all installed packages
apt list --installed
# List packages that have updates available
apt list --upgradable
Installing and Removing¶
# Install a package (resolves and installs dependencies automatically)
sudo apt install nginx
# Install a specific version
sudo apt install nginx=1.24.0-1ubuntu1
# Remove a package (keeps configuration files)
sudo apt remove nginx
# Remove a package and its configuration files
sudo apt purge nginx
# Remove packages that were installed as dependencies but are no longer needed
sudo apt autoremove
Upgrading¶
# Upgrade all installed packages (won't remove packages or install new ones)
sudo apt upgrade
# Upgrade with smarter conflict resolution (may remove or install packages)
sudo apt full-upgrade
The difference matters during major version bumps. apt upgrade is conservative - it skips any upgrade that would require removing an existing package. apt full-upgrade (formerly apt-get dist-upgrade) handles those cases.
Holding Packages¶
Sometimes you need to prevent a package from being upgraded - for example, if a newer version introduces a breaking change in production:
# Hold a package at its current version
sudo apt-mark hold nginx
# Show all held packages
apt-mark showhold
# Release the hold
sudo apt-mark unhold nginx
Held packages are skipped during apt upgrade and apt full-upgrade.
DNF (RHEL/Fedora)¶
dnf is the default package manager on Fedora, RHEL 8+, CentOS Stream, Rocky Linux, and AlmaLinux. It replaced yum, though yum still works as an alias on most systems.
Core Operations¶
# Update the package metadata cache
sudo dnf check-update
# Search for packages
dnf search nginx
# Show package details
dnf info nginx
# Install a package
sudo dnf install nginx
# Remove a package
sudo dnf remove nginx
# Upgrade all packages
sudo dnf upgrade
# Remove unneeded dependencies
sudo dnf autoremove
Version Locking¶
DNF uses a plugin for version locking (the dnf-plugins-core package):
# Install the versionlock plugin if not present
sudo dnf install dnf-plugins-core
# Lock a package at its current version
sudo dnf versionlock add nginx
# List locked packages
dnf versionlock list
# Remove a lock
sudo dnf versionlock delete nginx
Transaction History¶
One of DNF's most useful features is its transaction history:
# View recent transactions
dnf history
# Show details of a specific transaction
dnf history info 15
# Undo a transaction (reverse all changes it made)
sudo dnf history undo 15
This is invaluable when an upgrade breaks something - you can undo the exact transaction that caused the problem.
Repository Management¶
Repositories are configured in /etc/yum.repos.d/ as .repo files:
# List all configured repositories
dnf repolist --all
# Enable a disabled repository
sudo dnf config-manager --set-enabled crb
# Add a new repository
sudo dnf config-manager --add-repo https://example.com/repo.repo
Third-party repositories
Adding external repositories means trusting their maintainers with root-level access to your system. Every package installed from a repo runs scripts as root during installation. Only add repositories from sources you trust, and prefer official repositories when possible.
Low-level Tools: dpkg and rpm¶
The high-level tools (apt, dnf) call these under the hood. You use them directly when working with local package files or querying the package database.
dpkg (Debian)¶
# Install a local .deb file (does NOT resolve dependencies)
sudo dpkg -i package.deb
# If dpkg fails due to missing dependencies, fix them with apt
sudo apt install -f
# List all installed packages
dpkg -l
# List files installed by a package
dpkg -L nginx
# Find which package owns a file
dpkg -S /usr/bin/curl
# Show package status and metadata
dpkg -s nginx
rpm (Red Hat)¶
# Install a local .rpm file
sudo rpm -ivh package.rpm
# Upgrade (install or upgrade) a local .rpm file
sudo rpm -Uvh package.rpm
# Query all installed packages
rpm -qa
# Query information about an installed package
rpm -qi nginx
# List files in an installed package
rpm -ql nginx
# Find which package owns a file
rpm -qf /usr/bin/curl
# Query an uninstalled .rpm file
rpm -qpi package.rpm
Repository Management¶
APT Repositories¶
APT repositories are configured in /etc/apt/sources.list and individual files under /etc/apt/sources.list.d/. Modern Ubuntu systems use the DEB822 format in .sources files:
# Traditional one-line format (sources.list)
deb http://archive.ubuntu.com/ubuntu noble main restricted universe multiverse
# DEB822 format (sources.list.d/ubuntu.sources)
Types: deb
URIs: http://archive.ubuntu.com/ubuntu
Suites: noble noble-updates
Components: main restricted universe multiverse
Adding a third-party repository typically involves importing a GPG key and creating a sources file:
# Download and add the repository GPG key
curl -fsSL https://example.com/repo-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/example.gpg
# Add the repository with the key reference
echo "deb [signed-by=/usr/share/keyrings/example.gpg] https://example.com/repo stable main" | \
sudo tee /etc/apt/sources.list.d/example.list
# Refresh package index to include the new repo
sudo apt update
GPG key management
The signed-by field in the repository definition ties a specific GPG key to a specific repository. This prevents a compromised third-party repo from injecting packages that look like they come from the official Ubuntu archives.
DNF Repositories¶
DNF repos are individual .repo files in /etc/yum.repos.d/:
[example-repo]
name=Example Repository
baseurl=https://example.com/repo/el9/$basearch
enabled=1
gpgcheck=1
gpgkey=https://example.com/repo-key.gpg
# Import a GPG key manually
sudo rpm --import https://example.com/repo-key.gpg
# Verify a repo's GPG key is imported
rpm -qa gpg-pubkey*
Universal Package Managers¶
Traditional packages are tied to their distribution's ecosystem. Universal formats aim to work across distributions.
Snap¶
Snap packages are developed by Canonical and come pre-installed on Ubuntu. Each snap runs in a sandboxed environment with its own bundled dependencies:
# Search for a snap
snap find vlc
# Install a snap
sudo snap install vlc
# List installed snaps
snap list
# Update all snaps
sudo snap refresh
# Remove a snap
sudo snap remove vlc
Flatpak¶
Flatpak is distribution-neutral and uses the Flathub repository as its primary app store:
# Add the Flathub repository (one-time setup)
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
# Search for an app
flatpak search gimp
# Install an app
flatpak install flathub org.gimp.GIMP
# Run a flatpak app
flatpak run org.gimp.GIMP
# List installed flatpak apps
flatpak list
# Update all flatpak apps
flatpak update
# Remove an app
flatpak uninstall org.gimp.GIMP
AppImage¶
AppImage files are self-contained executables - no installation required:
# Download an AppImage
wget https://example.com/app.AppImage
# Make it executable and run it
chmod +x app.AppImage
./app.AppImage
Tradeoffs¶
| Aspect | Native (apt/dnf) | Snap | Flatpak | AppImage |
|---|---|---|---|---|
| Dependency sharing | Shared system libraries | Bundled per snap | Shared runtimes | Fully self-contained |
| Disk usage | Lowest | Higher | Moderate | Highest per app |
| Sandboxing | None by default | Strict by default | Configurable | None |
| Update mechanism | System package manager | snap refresh (auto) |
flatpak update |
Manual re-download |
| System integration | Full | Limited (strict confinement) | Good | Varies |
| Startup speed | Fastest | Slower (first launch) | Moderate | Moderate |
For servers, native packages are almost always the right choice - they're smaller, faster, and integrate with the system's update and security infrastructure. Universal formats are primarily useful for desktop applications that need to run across multiple distributions.
Auditing and Maintenance¶
Regular package maintenance keeps systems secure and avoids disk bloat.
Checking What's Installed¶
# Debian/Ubuntu: list all installed packages
dpkg -l | grep ^ii
# RHEL/Fedora: list all installed packages
rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort
# Find which package a file belongs to
dpkg -S /usr/bin/curl # Debian
rpm -qf /usr/bin/curl # RHEL
Security Updates¶
# Debian/Ubuntu: list security updates
apt list --upgradable 2>/dev/null | grep -i security
# RHEL/Fedora: list security updates
dnf updateinfo list security
# RHEL/Fedora: install only security updates
sudo dnf upgrade --security
Cleaning Up¶
# Debian/Ubuntu
sudo apt autoremove # Remove orphaned dependencies
sudo apt autoclean # Remove old cached .deb files
sudo apt clean # Remove ALL cached .deb files
# RHEL/Fedora
sudo dnf autoremove # Remove orphaned dependencies
sudo dnf clean all # Remove all cached data
Unattended Upgrades¶
For production servers, automatic security updates reduce the window of vulnerability:
# Debian/Ubuntu: install and enable unattended-upgrades
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
The configuration lives in /etc/apt/apt.conf.d/50unattended-upgrades. By default it applies security updates only, which is the safest setting for production.
On RHEL/Fedora, dnf-automatic provides similar functionality:
Automatic updates in production
Unattended upgrades are a tradeoff. They keep security patches current, but an update can occasionally break a running service. For critical production systems, many teams apply updates to a staging environment first, then promote to production after verification. At minimum, configure email notifications so you know what changed.
Further Reading¶
- APT man page - official apt command reference
- DNF Documentation - comprehensive DNF command and plugin reference
- dpkg man page - low-level Debian package tool reference
- rpm man page - low-level RPM package tool reference
- Snapcraft Documentation - snap package format and usage
- Flatpak Documentation - flatpak setup, usage, and app distribution
- Debian Wiki: Secure APT - how APT verifies package authenticity with GPG
- Fedora DNF System Upgrade - upgrading between Fedora releases
Previous: Disk and Filesystem | Next: System Services | Back to Index