Package management: apt, dnf & snap
Install, update and remove software, manage repositories, and use dpkg, rpm, Snap and Flatpak.
On Linux you rarely download installers from websites. Instead, software comes as packages from your distribution's repositories, which are curated, signed collections of thousands of programs. A package manager downloads them, resolves dependencies (other packages they need), installs files to the right places, and later updates or removes everything cleanly.
Plus there are distro-independent formats: Snap, Flatpak and AppImage.
apt on Ubuntu and Debian#
Installing and removing software changes the system, so these commands need sudo:
A typical install looks like this:
💡 Always
updatebeforeinstallorupgrade. apt works from a local copy of the package lists. If that copy is old, you'll get old versions or "404 Not Found" errors.
apt upgrade never removes packages. sudo apt full-upgrade may remove or replace packages when dependencies change (that's what you want for big updates). Moving to a new release (e.g. Ubuntu 24.04 → 26.04) is a separate step: sudo do-release-upgrade.
Searching and inspecting (no sudo needed)
apt is the friendly interactive command. In scripts, apt-get and apt-cache have a stable output format, so you'll see apt-get install -y ... in Dockerfiles and CI.
dpkg: the low-level tool
dpkg works on individual .deb files and the database of installed packages:
(dpkg -l also prints a header, which is omitted here. ii means "desired: install, status: installed".)
To install a downloaded .deb, use apt with a path so dependencies get resolved too:
(sudo dpkg -i file.deb also works, but leaves missing dependencies for you to fix with sudo apt -f install.)
Repositories#
apt's sources are listed in /etc/apt/sources.list.d/. Modern Ubuntu (24.04+) and Debian 13 use the deb822 format, like /etc/apt/sources.list.d/ubuntu.sources:
Ubuntu's components are main (supported by Canonical), universe (community), restricted (proprietary drivers) and multiverse (non-free). Debian uses main, contrib, non-free and non-free-firmware.
Adding a third-party repository
Vendors like Docker, PostgreSQL, Node.js (NodeSource) and Microsoft publish their own repos. The modern, safe pattern is to download the vendor's signing key to /etc/apt/keyrings/ and reference it with signed-by, so that key is trusted only for that repo:
Always follow the vendor's current official instructions; the URLs above are Docker's. On Ubuntu, PPAs (Personal Package Archives) are added with sudo add-apt-repository ppa:owner/name.
⚠️ Every repository you add can install software as root on your machine. Only add sources you trust, and avoid the old
apt-key addmethod (it trusted the key for all repos and is deprecated).
Keeping a version: holds
Automatic security updates
Ubuntu servers ship with unattended-upgrades, which installs security updates automatically. Configure it with sudo dpkg-reconfigure unattended-upgrades. On Debian, install it with sudo apt install unattended-upgrades.
dnf on Fedora, RHEL, Rocky and AlmaLinux#
dnf mirrors apt closely. Fedora 41+ ships dnf5, which is faster but uses the same commands:
Repos live in /etc/yum.repos.d/*.repo. On RHEL-family servers you'll often enable EPEL (Extra Packages for Enterprise Linux): sudo dnf install epel-release.
Snap and Flatpak#
These formats bundle an app with its dependencies, run it in a sandbox, and work across distributions:
When to use what:
- Server tools and libraries (nginx, PostgreSQL, git, Python): use the native package manager.
- Desktop apps you want in their latest version (browsers, editors, chat apps): Flatpak or Snap are great.
- Language libraries (Python, Node.js packages): use the language's own tool inside a project (
pipin a virtual environment,npm), notsudo pip install. Modern Ubuntu and Debian block system-widepip installwith an "externally-managed-environment" error for exactly this reason.
Common mistakes#
- Forgetting
sudo apt updateand then wondering why a package can't be found or is out of date. - Mixing package sources for the same software (e.g. the distro's nodejs plus a NodeSource repo plus a snap), which leaves several versions fighting over
PATH. - Installing random
.deb/.rpmfiles from the web. Prefer the official repo or the vendor's signed repository. - Interrupting an upgrade. If apt says "Could not get lock /var/lib/dpkg/lock-frontend", another apt process (often unattended-upgrades) is running. Wait for it; don't delete the lock files. If an upgrade really was interrupted, run
sudo dpkg --configure -a. - Using
sudo pip installto install system-wide Python packages. Usepython3 -m venvorpipx.
What's next#
Installed software runs as processes. Next you'll learn to inspect them, send them signals and control jobs in your terminal.
Check your understanding
Quick quiz
1.On Ubuntu, what is the difference between
apt updateandapt upgrade?2.Which command shows which installed package a file belongs to on Debian/Ubuntu?
3.What is the Fedora/RHEL equivalent of
sudo apt install nginx?
Finished reading?
Mark this lesson complete to track your progress.