Understanding Linux Packages and Repositories

Understanding Linux Packages and Repositories

On Windows and macOS, installing software usually means downloading an installer from a website and running it. On Linux, the standard method is the opposite: you ask the package manager for software by name and it fetches, verifies, and installs it from a trusted repository. The result is that updating every piece of software on a Linux system takes one command, dependency conflicts are caught automatically, and nothing installs itself without your knowledge.

Understanding how packages and repositories work makes the whole system predictable rather than magical.

What a package actually is

A package is a compressed archive with two parts: the files to be installed and a metadata file describing the package.

The metadata includes the package name and version, the maintainer, a description, a list of dependencies (other packages that must be installed first), and optional pre/post-install scripts that run during installation.

On Debian-based systems, packages use the .deb format. On Red Hat-based systems, the format is .rpm. Despite the different formats, both contain the same categories of information.

# Inspect a .deb package without installing it
dpkg-deb --info curl_8.5.0-2_amd64.deb
dpkg-deb --contents curl_8.5.0-2_amd64.deb

# Inspect a .rpm package
rpm -qip package.rpm    # info
rpm -qlp package.rpm    # list files

# See full metadata for an installed package
apt show curl           # Debian/Ubuntu
dnf info curl           # Fedora/RHEL

What a repository is

A repository is a structured collection of packages hosted on a server. It contains the package files themselves plus index files that list every package, its version, and its location. The entire index is signed with a GPG key so your package manager can verify it has not been tampered with.

When you run apt update, your package manager downloads the current index from each configured repository and stores it locally. When you install a package, it looks in that local index to find the download URL, fetches the package, checks its signature, and installs it.

On Debian and Ubuntu, repositories are listed in /etc/apt/sources.list and files under /etc/apt/sources.list.d/:

# View configured repos on Debian/Ubuntu
cat /etc/apt/sources.list
ls /etc/apt/sources.list.d/

# A typical sources.list entry
# deb https://deb.debian.org/debian bookworm main contrib non-free

# View configured repos on Fedora/RHEL
cat /etc/yum.repos.d/*.repo
dnf repolist

The components at the end of a Debian sources entry (main, contrib, non-free) indicate the licensing status of the packages:

  • main: fully free software maintained by Debian
  • contrib: free software that depends on non-free packages
  • non-free: proprietary or non-free software (firmware, drivers)
  • non-free-firmware: split out from non-free in Debian 12; firmware blobs for hardware

apt: the Debian and Ubuntu package manager

apt is the command you use day-to-day on Debian, Ubuntu, Linux Mint, and their derivatives.

# Update the local package index from all repos
sudo apt update

# Upgrade all installed packages to their latest versions
sudo apt upgrade

# Full upgrade: also handles changing dependencies and removing obsolete packages
sudo apt full-upgrade

# Install a package
sudo apt install nginx

# Install multiple packages at once
sudo apt install nginx postgresql redis-server

# Remove a package (keep config files)
sudo apt remove nginx

# Remove a package and its config files
sudo apt purge nginx

# Remove packages that were installed as dependencies and are no longer needed
sudo apt autoremove

# Search for a package by name or description
apt search "web server"

# Show package details
apt show nginx

# List installed packages
apt list --installed

# List packages with available upgrades
apt list --upgradable

The underlying low-level tool is dpkg, which handles the actual file operations:

# Install a .deb file directly
sudo dpkg -i package.deb

# List all installed packages
dpkg -l

# Find which package owns a file
dpkg -S /usr/bin/curl

# List files installed by a package
dpkg -L curl

# Check package status
dpkg -s curl

dnf: the Fedora and RHEL package manager

dnf (Dandified YUM) is the package manager for Fedora, RHEL, AlmaLinux, Rocky Linux, and CentOS Stream. It replaced the older yum command, though yum often still works as an alias on older systems.

# Update package index and upgrade all packages
sudo dnf upgrade

# Install a package
sudo dnf install nginx

# Remove a package
sudo dnf remove nginx

# Search for a package
dnf search "web server"

# Show package information
dnf info nginx

# List installed packages
dnf list installed

# Find which package provides a file
dnf provides /usr/bin/curl

# List configured repositories
dnf repolist

# Clean the local cache
sudo dnf clean all

The underlying low-level tool on RPM systems is rpm:

# Install an .rpm file directly
sudo rpm -i package.rpm

# Query which package owns a file
rpm -qf /usr/bin/curl

# List files installed by a package
rpm -ql curl

# List all installed packages
rpm -qa

# Show package info
rpm -qi curl

pacman: the Arch Linux package manager

Arch Linux and its derivatives (Manjaro, EndeavourOS) use pacman:

# Sync database and upgrade everything
sudo pacman -Syu

# Install a package
sudo pacman -S nginx

# Remove a package and its dependencies
sudo pacman -Rs nginx

# Search for a package
pacman -Ss web server

# Show package information
pacman -Si nginx

# List installed packages
pacman -Q

# Find which package owns a file
pacman -Qo /usr/bin/curl

# List files installed by a package
pacman -Ql curl

Arch also has the AUR (Arch User Repository), a community-maintained collection of build scripts for software not in the official repos. Tools like yay or paru wrap pacman to handle AUR packages alongside official ones.

Adding third-party repositories

The default repositories for any distribution contain thousands of packages, but not everything. When you need software outside the official repos, you add a third-party repository.

On Debian and Ubuntu, the modern approach uses .sources files with explicit signed-by entries:

# Example: adding the nginx mainline repo on Ubuntu
# 1. Download and store the signing key
curl -fsSL https://nginx.org/keys/nginx_signing.key | \
  sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg

# 2. Add the repo source file
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
  http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" | \
  sudo tee /etc/apt/sources.list.d/nginx.list

# 3. Update and install
sudo apt update
sudo apt install nginx

On Fedora/RHEL, third-party repos are commonly added with a single RPM that configures everything:

# Example: adding RPM Fusion repos on Fedora
sudo dnf install \
  https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \
  https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm

# Example: adding a COPR (community) repo
sudo dnf copr enable username/reponame

Universal package formats: Flatpak, Snap, and AppImage

Traditional .deb and .rpm packages are tied to a specific distribution and version. Universal formats solve this by bundling an application with its own dependencies and running it in isolation.

Flatpak

Flatpak packages run in a sandbox and are distributed through any Flatpak repository. Flathub (https://flathub.org) is the primary source and contains thousands of desktop applications.

# Install Flatpak support
sudo apt install flatpak            # Debian/Ubuntu
sudo dnf install flatpak            # Fedora

# Add Flathub
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

# Install a Flatpak application
flatpak install flathub org.libreoffice.LibreOffice

# Update all Flatpak apps
flatpak update

# List installed Flatpak apps
flatpak list

# Remove a Flatpak app
flatpak uninstall org.libreoffice.LibreOffice

# Run a Flatpak app
flatpak run org.libreoffice.LibreOffice

Snap

Snap is Canonical’s universal package format, integrated into Ubuntu by default. Packages come from the Snap Store and update automatically.

# Install a Snap package
sudo snap install vlc

# Update all snaps
sudo snap refresh

# List installed snaps
snap list

# Remove a snap
sudo snap remove vlc

# Find snaps
snap find "video player"

Snaps are enabled by default on Ubuntu. On other distributions, you need to install snapd first.

AppImage

AppImages are single executable files that contain everything an application needs. No installation required: download, make executable, run.

# Make an AppImage executable and run it
chmod +x SomeApp-x86_64.AppImage
./SomeApp-x86_64.AppImage

# Optionally integrate it with the desktop
# (AppImageLauncher handles this automatically if installed)

AppImages do not integrate with the system package manager and do not update automatically, which makes them convenient for one-off use but less suited for software that needs regular security updates.

Building from source

When a package is not available in any repository or format, building from source is the fallback. The typical pattern for C/C++ projects:

# Install build tools
sudo apt install build-essential     # Debian/Ubuntu
sudo dnf groupinstall "Development Tools"  # Fedora/RHEL

# The classic configure, make, install pattern
./configure --prefix=/usr/local
make
sudo make install

# Install build dependencies for a package (Debian/Ubuntu)
sudo apt build-dep nginx

# Download source and build it
apt source nginx
cd nginx-*/
dpkg-buildpackage -us -uc

Software installed this way goes into /usr/local by convention and is invisible to the package manager. It will not appear in apt list --installed and will not receive automatic updates.

Repository security

Every package and repository index is signed. When you add a repository, you also add its GPG public key. Your package manager verifies every downloaded package against that key before installing it. This means a compromised mirror cannot inject malicious packages: the signature would fail.

# List trusted repository keys on Debian/Ubuntu
apt-key list    # deprecated but still works
ls /usr/share/keyrings/
ls /etc/apt/trusted.gpg.d/

# Verify a .deb package signature manually
dpkg-sig --verify package.deb

# On RPM systems, check GPG keys
rpm --import https://example.com/key.gpg
rpm -K package.rpm

The security model assumes you trust the key you add when you add a third-party repo. Adding a repository from an unknown source grants that source the ability to install software on your system. Treat third-party repository keys with the same caution as giving someone root access.

Practical reference

# Find where a package installed its files
dpkg -L packagename          # Debian/Ubuntu
rpm -ql packagename          # Fedora/RHEL

# Check if a file came from a package
dpkg -S /path/to/file        # Debian/Ubuntu
rpm -qf /path/to/file        # Fedora/RHEL

# Reinstall a package (fixes missing/corrupted files)
sudo apt install --reinstall packagename
sudo dnf reinstall packagename

# Hold a package at its current version (prevent upgrades)
sudo apt-mark hold packagename
sudo dnf versionlock add packagename

# See the changelog for a package
apt changelog packagename    # Debian/Ubuntu
rpm -q --changelog packagename | head -40

# Check package integrity
sudo debsums packagename     # Debian/Ubuntu (install debsums first)
sudo rpm -V packagename      # Fedora/RHEL

The package management layer is one of the features that makes Linux systems reliable to administer at scale. One command to update everything, cryptographically verified downloads, and a clear record of what is installed and where it came from. Once you understand the model, the commands follow logically.

Frequently Asked Questions

What is a Linux package?

A Linux package is a compressed archive that contains the files for a piece of software, along with metadata describing the software version, its dependencies, and instructions for where files should be installed. The two dominant formats are .deb (used by Debian, Ubuntu, and derivatives) and .rpm (used by Fedora, RHEL, and derivatives). Package managers install, update, and remove packages while automatically handling dependencies.

What is a Linux repository?

A repository (repo) is a server hosting a collection of packages, along with index files and cryptographic signatures that package managers use to verify authenticity. When you run apt update or dnf check-update, your package manager downloads the latest index from each configured repository. When you install software, the package is downloaded from the repo and verified against its signature before being installed.

What is the difference between apt and dpkg?

dpkg is the low-level tool that installs, removes, and queries .deb package files directly. It does not resolve dependencies. apt is the high-level tool that uses dpkg under the hood but adds dependency resolution, repository management, and a cleaner interface. In everyday use you interact with apt; dpkg is useful when you have a .deb file you want to inspect or install directly.

What is the difference between apt and apt-get?

apt and apt-get do most of the same things. apt is the newer, user-friendly frontend with a progress bar and cleaner output, designed for interactive terminal use. apt-get is the older tool recommended in scripts because its output format is stable across versions. In practice, both work for interactive use, but scripts and automated tasks should use apt-get to avoid output format surprises.

What is the difference between Flatpak and Snap?

Both Flatpak and Snap are universal package formats that bundle an application with its dependencies and run it in a sandbox, making them distribution-independent. Flatpak is decentralised: the primary source is Flathub but anyone can host a Flatpak repo. Snap is centralised: packages must go through Canonical