Why Package Managers Came About
In one line
A package manager is not a tool for unpacking files; it is a tool for solving the graph of "what needs what".
Why this exists
In the days when software was distributed as tarballs, installation went like this. You unpack the archive, run ./configure, find and install the missing libraries one at a time, and when one of those libraries demands something else, you go looking again. This was called "dependency hell".
The essence of the problem was that moving files was not the hard part; nobody knew what had to be moved first. So package formats attached metadata to the bundle of files: what this package provides (Provides), what it requires (Depends), and what it conflicts with (Conflicts). Installation stopped being a file-copying problem and became a graph problem, and a computer solves graph problems better than a person does.
How it works
The details of deb and rpm differ, but the skeleton is the same.
| Concept | What it is | Debian notation | RPM notation |
|---|---|---|---|
| Name and version | Identifies the package | Package, Version |
Name, Version, Release |
| Required dependency | Unusable without it | Depends |
Requires |
| Weak dependency | Nice to have | Recommends, Suggests |
Recommends, Suggests |
| Provides | Satisfies a virtual name | Provides |
Provides |
| Conflict | Cannot coexist | Conflicts, Breaks |
Conflicts |
| Architecture | Which CPU it is for | amd64 / all |
x86_64 / noarch |
Three things trip people up most often here.
First, the unit of a dependency may not be a package name. This is especially true on the RPM side. As in Requires: libnl-3.so.200()(64bit), the soname of a shared library itself becomes the dependency target. That is why a request like "can't you just fetch one package?" turns into half a day of work on an air-gapped network.
Second, there are virtual packages (Provides). If you require mail-transport-agent, both postfix and exim4 satisfy that requirement. That is how situations like "there is no package with this name in the repository, so why does the install work?" arise.
Third, the version comparison rules differ from intuition. In Debian, 1.0~rc1 is less than 1.0 (a tilde sorts lower than any character). In RPM there is an epoch, so 1:1.0 is greater than 2.0. And the epoch does not appear in the file name. It is a quiet and fatal difference.
What it looks like in the field
Import requests into an air-gapped network often arrive as "just fetch me one rpm file". When you bring it in and install, you get an error like nothing provides libnl-3.so.200()(64bit) needed by htop. You go back out and fetch that, and it says something else is missing. After a few round trips with a USB drive, half a day has gone by, and the import review happens only once a day.
So an experienced person goes in from the start carrying the result of solving the whole graph. Where that calculation is done is the subject of the second half of this course.
What a package manager does not do
A package manager places files and solves dependencies, but it does not do most of what comes after. If you do not know this boundary, "I installed it, so why doesn't it work?" keeps recurring.
It does not overwrite configuration files. When a package is updated and we have edited a configuration file, the manager asks instead of overwriting, or leaves the new file next to it under a name such as .dpkg-dist or .rpmnew. So you need a procedure to check whether such files have piled up after an update. Even if the new version needs a configuration entry, our file does not have it, so the service quietly runs on defaults and becomes a problem later.
Whether it restarts the service for you differs by distribution. Some distributions restart automatically after an update and some do not. The automatic side can cut a service at an unexpected moment, and the other side leaves old code running. The point is to know which side you are on and have the matching procedure; this is not something to wave through by trusting the default behavior.
It does not remove what it did not install. Even if you remove a package, the logs, data directories, and user accounts it created usually remain. This is the difference behind remove and purge being separate on Debian-family systems. The fact that things remain is itself a safety device, but if you believe you deleted it, then when you reinstall the same package later, the old configuration comes back to life and causes confusion.
It and the per-language package managers do not know about each other. When a Python library installed as a system package is mixed with one installed by pip, it becomes hard to predict which one is used, and a system update breaks the application. So the principle is to separate application dependencies with a virtual environment or a container, and let the system package manager handle only what belongs to the system.
What we will do next
We move on to hands-on apt operation. Search, install, and remove are only the beginning; you will also get used to holding a version in place with hold and pin.