Learn to manage Linux packages effectively with apt, dnf, and yum across Ubuntu, Debian, and RHEL-based distributions. Master installation, updates, repository management, and troubleshooting for reliable system maintenance.
Prerequisites
- Root or sudo access
- Active internet connection
What this solves
Linux package managers handle software installation, updates, and dependency resolution across different distributions. Understanding apt (Ubuntu/Debian), dnf (Fedora/newer RHEL), and yum (older RHEL systems) ensures you can maintain secure, up-to-date systems regardless of your distribution choice.
Understanding Linux package managers
Package managers automate software installation by handling dependencies, version conflicts, and system integration. Each distribution family uses different tools but follows similar principles.
| Distribution | Package Manager | Package Format | Repository Config |
|---|---|---|---|
| Ubuntu/Debian | apt | .deb | /etc/apt/sources.list |
| Fedora/RHEL 8+ | dnf | .rpm | /etc/yum.repos.d/ |
| CentOS 7/RHEL 7 | yum | .rpm | /etc/yum.repos.d/ |
Step-by-step configuration
Update package databases
Always start by refreshing your package manager's database to ensure you get the latest package versions and security updates.
sudo apt update
sudo apt list --upgradable
Upgrade system packages
Apply available updates to keep your system secure and stable. This updates all installed packages to their latest versions.
sudo apt upgrade -y
sudo apt full-upgrade -y
full-upgrade on apt removes packages if needed for upgrades, while upgrade is more conservative.Install new packages
Install software packages with automatic dependency resolution. This example installs common system monitoring tools.
sudo apt install -y htop curl wget git vim
sudo apt install --no-install-recommends nginx
Search for packages
Find available packages before installation using search functionality.
apt search nginx
apt show nginx
apt list --installed | grep nginx
Remove packages
Uninstall packages cleanly, with options to remove configuration files and unused dependencies.
sudo apt remove package-name
sudo apt purge package-name
sudo apt autoremove
Package repository management
View configured repositories
Check which repositories your system uses for package installation.
cat /etc/apt/sources.list
ls /etc/apt/sources.list.d/
apt policy
Add external repositories
Add third-party repositories for additional software packages. This example adds the official Docker repository.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update
Manage repository GPG keys
Repository GPG keys ensure package authenticity and prevent tampering.
apt-key list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys KEY_ID
apt-key finger
Advanced package operations
Hold packages from updates
Prevent specific packages from being automatically updated, useful for maintaining compatibility.
sudo apt-mark hold nginx
apt-mark showhold
sudo apt-mark unhold nginx
Install specific package versions
Install or downgrade to specific package versions when needed for compatibility.
apt list -a nginx
sudo apt install nginx=1.18.0-6ubuntu14.4
apt-cache policy nginx
Clean package cache
Free disk space by cleaning downloaded package files and metadata.
sudo apt clean
sudo apt autoclean
du -sh /var/cache/apt/archives/
Automated updates and security
Configure automatic security updates
Enable automatic installation of security patches to keep your system secure without manual intervention.
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
Configure automatic update settings
Customize which updates get installed automatically and notification preferences.
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id} ESMApps:${distro_codename}-apps-security";
"${distro_id} ESM:${distro_codename}-infra-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
Verify your setup
Check that your package management system is working correctly and configured properly.
sudo apt update && apt list --upgradable
sudo systemctl status unattended-upgrades
ls -la /var/log/unattended-upgrades/
For dnf/yum systems:
sudo dnf check-update
sudo systemctl status dnf-automatic.timer
journalctl -u dnf-automatic.service
You can also integrate this with system monitoring tools like process monitoring with htop and service management with systemctl for comprehensive system oversight.
Troubleshooting common package issues
| Symptom | Cause | Fix |
|---|---|---|
| Package has unmet dependencies | Broken package relationships | sudo apt --fix-broken install or sudo dnf distro-sync |
| Hash Sum mismatch errors | Corrupt package cache | sudo apt clean && sudo apt update |
| Repository not found | Invalid repository URL or missing GPG key | Check /etc/apt/sources.list or remove invalid repo |
| Package locked by another process | Multiple package managers running | Wait for other process to finish or kill if hung |
| Disk space errors during install | Full filesystem | sudo apt autoremove && sudo apt autoclean |
| GPG signature verification failed | Missing or expired repository key | Import correct GPG key from official source |
Next steps
- Configure automatic security updates for hands-off security maintenance
- Set up shell aliases to speed up common package management tasks
- Monitor package updates across multiple systems
- Set up local package mirrors for air-gapped environments
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Global variables
PKG_MGR=""
PKG_INSTALL=""
PKG_UPDATE=""
PKG_UPGRADE=""
PKG_SEARCH=""
PKG_REMOVE=""
PKG_AUTOREMOVE=""
REPO_CONFIG_DIR=""
UPDATE_TOOL=""
# Cleanup function
cleanup() {
echo -e "${RED}[ERROR] Script failed. Cleaning up...${NC}"
# Remove any temporary files if they exist
rm -f /tmp/package_mgr_*.tmp
}
# Set trap for cleanup on error
trap cleanup ERR
# Function to print colored messages
print_info() {
echo -e "${BLUE}[INFO] $1${NC}"
}
print_success() {
echo -e "${GREEN}[SUCCESS] $1${NC}"
}
print_warning() {
echo -e "${YELLOW}[WARNING] $1${NC}"
}
print_error() {
echo -e "${RED}[ERROR] $1${NC}"
}
# Function to show usage
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Configure Linux package management and perform system updates"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
echo " -u, --update-only Only update package databases"
echo " -i, --install-tools Install common system tools"
echo " -s, --skip-upgrade Skip system upgrade"
echo ""
echo "Example: $0 --install-tools"
exit 1
}
# Check prerequisites
check_prerequisites() {
print_info "Checking prerequisites..."
if [[ $EUID -ne 0 ]] && ! sudo -n true 2>/dev/null; then
print_error "This script requires root privileges or passwordless sudo"
exit 1
fi
if [ ! -f /etc/os-release ]; then
print_error "/etc/os-release not found. Cannot detect distribution"
exit 1
fi
print_success "Prerequisites check passed"
}
# Detect distribution and set package manager variables
detect_distro() {
print_info "Detecting distribution..."
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
PKG_UPGRADE="apt upgrade -y"
PKG_SEARCH="apt search"
PKG_REMOVE="apt remove -y"
PKG_AUTOREMOVE="apt autoremove -y"
REPO_CONFIG_DIR="/etc/apt/sources.list.d"
UPDATE_TOOL="apt"
;;
almalinux|rocky|centos|rhel|ol)
if command -v dnf >/dev/null 2>&1; then
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf check-update || true"
PKG_UPGRADE="dnf upgrade -y"
PKG_SEARCH="dnf search"
PKG_REMOVE="dnf remove -y"
PKG_AUTOREMOVE="dnf autoremove -y"
REPO_CONFIG_DIR="/etc/yum.repos.d"
UPDATE_TOOL="dnf"
else
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum check-update || true"
PKG_UPGRADE="yum update -y"
PKG_SEARCH="yum search"
PKG_REMOVE="yum remove -y"
PKG_AUTOREMOVE="yum autoremove -y"
REPO_CONFIG_DIR="/etc/yum.repos.d"
UPDATE_TOOL="yum"
fi
;;
fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf check-update || true"
PKG_UPGRADE="dnf upgrade -y"
PKG_SEARCH="dnf search"
PKG_REMOVE="dnf remove -y"
PKG_AUTOREMOVE="dnf autoremove -y"
REPO_CONFIG_DIR="/etc/yum.repos.d"
UPDATE_TOOL="dnf"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum check-update || true"
PKG_UPGRADE="yum update -y"
PKG_SEARCH="yum search"
PKG_REMOVE="yum remove -y"
PKG_AUTOREMOVE="yum autoremove -y"
REPO_CONFIG_DIR="/etc/yum.repos.d"
UPDATE_TOOL="yum"
;;
*)
print_error "Unsupported distribution: $ID"
exit 1
;;
esac
print_success "Detected distribution: $PRETTY_NAME using $PKG_MGR"
}
# Update package databases
update_packages() {
print_info "[1/5] Updating package databases..."
if [[ "$PKG_MGR" == "apt" ]]; then
sudo $PKG_UPDATE
sudo apt list --upgradable 2>/dev/null | head -20 || true
else
sudo $PKG_UPDATE
sudo $UPDATE_TOOL list --updates 2>/dev/null | head -20 || true
fi
print_success "Package databases updated"
}
# Upgrade system packages
upgrade_system() {
print_info "[2/5] Upgrading system packages..."
sudo $PKG_UPGRADE
if [[ "$PKG_MGR" == "apt" ]]; then
# Also run full-upgrade for Debian-based systems
sudo apt full-upgrade -y
fi
print_success "System packages upgraded"
}
# Install common system tools
install_tools() {
print_info "[3/5] Installing common system tools..."
# Define common tools that should be available on all distributions
local tools="curl wget git vim htop"
# Add distribution-specific tools
if [[ "$PKG_MGR" == "apt" ]]; then
tools="$tools software-properties-common apt-transport-https ca-certificates gnupg lsb-release"
else
tools="$tools epel-release"
fi
sudo $PKG_INSTALL $tools
print_success "Common system tools installed"
}
# Configure repository management
configure_repos() {
print_info "[4/5] Configuring repository management..."
# Ensure repository configuration directory exists with proper permissions
if [ ! -d "$REPO_CONFIG_DIR" ]; then
sudo mkdir -p "$REPO_CONFIG_DIR"
sudo chmod 755 "$REPO_CONFIG_DIR"
sudo chown root:root "$REPO_CONFIG_DIR"
fi
# Display current repository configuration
echo "Current repository configuration:"
if [[ "$PKG_MGR" == "apt" ]]; then
echo "Main sources:"
sudo head -10 /etc/apt/sources.list 2>/dev/null || echo " No main sources file"
echo "Additional repositories:"
sudo ls -la "$REPO_CONFIG_DIR"/ 2>/dev/null || echo " No additional repositories"
else
echo "Configured repositories:"
sudo $UPDATE_TOOL repolist 2>/dev/null | head -20
fi
print_success "Repository configuration displayed"
}
# Verify installation and show system status
verify_installation() {
print_info "[5/5] Verifying installation and showing system status..."
# Show package manager version
echo "Package manager information:"
if [[ "$PKG_MGR" == "apt" ]]; then
apt --version 2>/dev/null || echo " apt version not available"
else
$UPDATE_TOOL --version 2>/dev/null || echo " $UPDATE_TOOL version not available"
fi
# Show installed common tools
echo -e "\nCommon tools status:"
for tool in curl wget git vim htop; do
if command -v "$tool" >/dev/null 2>&1; then
echo -e " ${GREEN}✓${NC} $tool: $(command -v $tool)"
else
echo -e " ${RED}✗${NC} $tool: not found"
fi
done
# Show system update status
echo -e "\nSystem update status:"
if [[ "$PKG_MGR" == "apt" ]]; then
local updates
updates=$(sudo apt list --upgradable 2>/dev/null | grep -c upgradable || echo "0")
echo " Available updates: $updates"
else
local updates
updates=$(sudo $UPDATE_TOOL list --updates 2>/dev/null | grep -c "Available Upgrades" || echo "0")
echo " Available updates: $updates"
fi
print_success "System verification completed"
}
# Main function
main() {
local update_only=false
local install_tools_flag=false
local skip_upgrade=false
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
usage
;;
-u|--update-only)
update_only=true
shift
;;
-i|--install-tools)
install_tools_flag=true
shift
;;
-s|--skip-upgrade)
skip_upgrade=true
shift
;;
*)
print_error "Unknown option: $1"
usage
;;
esac
done
echo -e "${BLUE}Starting Linux Package Management Configuration${NC}"
echo "=============================================="
check_prerequisites
detect_distro
update_packages
if [ "$update_only" = false ]; then
if [ "$skip_upgrade" = false ]; then
upgrade_system
else
print_warning "Skipping system upgrade as requested"
fi
if [ "$install_tools_flag" = true ]; then
install_tools
fi
configure_repos
verify_installation
fi
echo ""
print_success "Package management configuration completed successfully!"
# Show next steps
echo -e "\n${BLUE}Next steps:${NC}"
echo "• Run 'sudo $PKG_UPDATE && sudo $PKG_UPGRADE' regularly for updates"
echo "• Use '$PKG_SEARCH <package>' to find available packages"
echo "• Repository configs are in: $REPO_CONFIG_DIR"
echo "• For security updates, consider setting up unattended upgrades"
}
# Run main function with all arguments
main "$@"
Review the script before running. Execute with: bash install.sh