Packages#
Packages are the standard unit of software installation on Linux.
Every major distribution family ships a package manager that does
the same five things. Install, upgrade, query, remove, and resolve
dependencies against signed repositories. The syntax differs across
apt, dnf, pacman, zypper, and apk; the
architecture is identical.
For the operator, the package manager is the first place to read the box. The installed-package database answers what is on this host. The history log answers what changed and when. The repository configuration answers what could land here next. Each read is faster than reconstructing the same picture from the filesystem.
The same manager is also the operator’s supply chain on every
authorized engagement. A third-party repo, a sideloaded .deb
or .rpm, a vendor install script running with package-manager
trust, all land code into the system with the same authority as
the distro’s own packages. The GPG signing chain is the gate. Read
where the keys live, how the manager verifies a fetched archive,
and which third-party sources have been added before trusting the
state of the box.
Quick orientation:
Question |
Command |
|---|---|
What manager is here? |
|
What distro family? |
|
Is package X installed? |
|
What owns a file? |
|
Install history? |
|
Every package manager does the same five things; the syntax differs, the architecture doesn’t.
sequenceDiagram
participant O as operator
participant M as manager
participant R as repository
participant C as local cache
participant D as package db
O->>M: install PKG
M->>R: fetch index
R-->>M: package list + metadata
M->>M: resolve dep graph
M->>R: download archives
R-->>C: .deb / .rpm / .pkg.tar.zst / .apk
M->>M: verify GPG signatures
M->>D: unpack + run pre/post scripts
M->>D: update package database
D-->>O: install complete
Stage |
What happens |
|---|---|
Repository |
A signed source of packages (URL + GPG key). Configured in |
Resolve |
Compute the full dependency graph for a requested package: what else must be installed, upgraded, or removed. |
Fetch |
Download the resolved set as |
Verify |
Validate each archive’s GPG signature against the trusted-keys store before unpacking. |
Install |
Unpack files onto the filesystem, run pre/post scripts, update the local package database ( |
Five stages, five filesystem locations per manager. A quick map of where each stage’s state lives:
Stage |
apt / dpkg |
dnf / rpm |
pacman |
apk |
zypper |
|---|---|---|---|---|---|
Repos |
|
|
|
|
|
Keys |
|
|
(in |
|
(in |
Cache |
|
|
|
|
|
Database |
|
|
|
|
|
Format |
|
|
|
|
|
Logs |
|
|
|
|
|
Beyond the native managers, three other distribution models coexist:
Universal / sandboxed, Flatpak, Snap, AppImage. Bundle their own runtime; bypass the distro’s libraries.
User-scoped, Homebrew, Nix, language managers (
pip/npm/cargo/go). Install into the user’s home, no root.From source, Autotools, CMake, Meson. Bypass packaging entirely, or build a package and feed it back to the native manager.
Repositories#
A repository is a signed catalog of packages the manager can install from. Three things define one. A URL or directory the manager can read. A signed index listing what is available, who built each package, and how to verify it. A pool (or archive, or cache) of the package files themselves at well-known paths under that URL.
The signed index is the trust anchor. The manager fetches it first, verifies the signature against the keys in the local keyring, and only then trusts the package names, versions, and checksums inside. A package archive copied off a mirror is useless to the manager without the matching index entry, and an index with a key the manager does not trust is refused.
Repository Layout per Manager#
Each ecosystem lays out the metadata differently. The substance is the same.
Manager |
Index file(s) |
Package pool |
|---|---|---|
apt |
|
|
dnf / yum |
|
flat directory per arch ( |
pacman |
|
flat directory per repo, |
apk |
|
flat directory, |
zypper |
|
per-arch |
Official Repository Tiers#
Each distro slices its catalog into tiers by license, support level, and freshness. The operator picks which tiers to enable.
Distro |
Tiers |
Notes |
|---|---|---|
Debian |
|
|
Ubuntu |
|
|
RHEL / Rocky / Alma |
|
|
Fedora |
|
Often paired with |
Arch |
|
|
Alpine |
|
|
Third-Party Channels#
Every ecosystem has an extension channel for software the distro itself does not ship. These bypass the distro’s review process and trust whoever signs them. Treat each one as a separate supply chain.
Channel |
Ecosystem |
What it is |
|---|---|---|
PPA |
Ubuntu |
Personal Package Archive on Launchpad. Per-maintainer
repository the operator adds with |
EPEL |
RHEL family |
Extra Packages for Enterprise Linux. Fedora-maintained overflow for software RHEL does not include. |
COPR |
Fedora / RHEL |
Cool Other Package Repo. Per-maintainer build service hosted by Fedora, similar to PPA. |
AUR |
Arch |
Arch User Repository. PKGBUILD recipes the operator builds
locally ( |
OBS |
openSUSE / cross-distro |
Open Build Service. Repositories built from source for any supported distro. |
RPM Fusion |
Fedora / RHEL |
Non-free codecs, drivers, and content Fedora does not ship. |
Package Formats#
A package is an archive with metadata. The metadata tells the manager what the package needs, what it provides, what scripts to run on install and removal, and where each file goes. The archive holds the files themselves.
Format |
Archive structure |
Metadata layer |
|---|---|---|
|
|
|
|
signed header plus a cpio archive (typically |
the RPM header carries dependencies, scriptlets, the file list, and per-file digests |
|
zstandard-compressed tarball |
|
|
gzipped tar with three concatenated sections (signature, metadata, files) |
|
The operator inspects any of these without installing them.
$ dpkg-deb -c package.deb # list files in a .deb
$ dpkg-deb -e package.deb /tmp/control # extract metadata
$ rpm2cpio package.rpm | cpio -idv # unpack an .rpm
$ rpm -qip package.rpm # show .rpm metadata
$ bsdtar -tf package.pkg.tar.zst # list files in an Arch package
$ tar -tzf package.apk # list files in an Alpine package
The same archive format repeats on the installed side. The package
database (/var/lib/dpkg, /var/lib/rpm, /var/lib/pacman,
/lib/apk/db) is the canonical record of which files came from
which package, with the same digests the archive carried. Tamper
detection (debsums, rpm -V, pacman -Qkk, apk audit)
compares the on-disk files against that record.
apt (Debian / Ubuntu)#
The default package manager on Debian, Ubuntu, Kali, Mint, and any
distribution downstream of Debian. apt is the user-facing
front end; dpkg is the lower-level tool that operates on
.deb files.
Install, remove, search#
Command |
Effect |
|---|---|
|
Refresh package indexes |
|
Upgrade installed packages (no removals) |
|
Upgrade + allow removals to satisfy deps |
|
Install |
|
Install a local |
|
Uninstall (keeps config) |
|
Uninstall + remove config |
|
Remove orphaned dependencies |
|
Search package descriptions |
|
Detailed metadata |
|
List installed packages matching name |
|
List files installed by |
|
Which package owns a file |
$ sudo apt update
$ sudo apt upgrade
$ sudo apt full-upgrade
$ sudo apt install nginx
$ sudo apt install ./local.deb
$ sudo apt remove nginx
$ sudo apt purge nginx
$ sudo apt autoremove
$ apt search redis
$ apt show nginx
$ dpkg -l | grep nginx
$ dpkg -L nginx
$ dpkg -S /usr/sbin/nginx
Repositories and keys#
The modern pattern: download the signing key into
/etc/apt/keyrings/ and reference it from a sources file with
Signed-By:. Never apt-key add; that command is
deprecated and trusts the key for every repository on the
system.
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/debian/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
$ sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
$ Types: deb
$ URIs: https://download.docker.com/linux/debian
$ Suites: $(lsb_release -cs)
$ Components: stable
$ Architectures: amd64
$ Signed-By: /etc/apt/keyrings/docker.gpg
$ EOF
$ echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
$ sudo apt update
$ sudo apt install docker-ce
How apt fetches#
apt does not speak HTTP itself. Each URI scheme in sources.list
dispatches to a method handler under /usr/lib/apt/methods/
(http, https, ftp, file, copy, mirror, cdrom,
store). The parent process pipes URLs to the handler over stdin and
reads bytes back from stdout. apt update fetches index files;
apt install fetches the actual .deb archives the resolver picked.
The pieces involved in a fetch:
flowchart LR
subgraph Client [client host]
direction TB
APT["apt / apt-get"]
SRC["/etc/apt/sources.list*<br/>(repo URIs)"]
CFG["/etc/apt/apt.conf.d/<br/>(proxy, retries, ...)"]
KEYS["/etc/apt/keyrings/<br/>(GPG signing keys)"]
METHODS["/usr/lib/apt/methods/<br/>http · https · ftp · file · ..."]
LISTS["/var/lib/apt/lists/<br/>(index cache)"]
CACHE["/var/cache/apt/archives/<br/>(.deb cache)"]
DPKG["/var/lib/dpkg/<br/>(install db)"]
APT --> SRC
APT --> CFG
APT --> METHODS
APT --> KEYS
METHODS --> LISTS
METHODS --> CACHE
CACHE --> DPKG
end
PROXY["HTTP/HTTPS proxy<br/>(squid, apt-cacher-ng)"]
MIRROR["mirror<br/>archive.ubuntu.com,<br/>deb.debian.org, ..."]
METHODS -->|via $https_proxy<br/>or Acquire::*::Proxy| PROXY
METHODS -->|DIRECT| MIRROR
PROXY --> MIRROR
The dynamic flow for a single fetch:
sequenceDiagram
participant A as apt
participant H as /usr/lib/apt/methods/https
participant P as proxy (optional)
participant R as mirror (e.g. archive.ubuntu.com)
A->>H: GET InRelease, Packages.{gz,xz}
H->>P: TCP / TLS via $https_proxy
P->>R: forward request
R-->>P: signed index + package list
P-->>H: response bytes
H-->>A: cache to /var/lib/apt/lists/
Note over A: verify InRelease signature against /etc/apt/keyrings/
A->>A: resolve dep graph from local indexes
A->>H: GET pool/main/n/nginx/nginx_*.deb
H->>P: TCP / TLS
P->>R: forward
R-->>P: .deb bytes
P-->>H: response
H-->>A: stored in /var/cache/apt/archives/
Note over A: SHA256 + GPG verified before unpack
A->>A: dpkg unpack + maintainer scripts
Each fetch is a separate request; apt pipelines several in parallel
per method handler (Acquire::Queue-Mode "host" + a worker per host).
The on-disk layout the sequence touches:
Path |
Holds |
|---|---|
|
Repository URIs and signing-key references |
|
Per-repo GPG keys (modern |
|
Drop-in config (proxy, retries, timeouts, pinning) |
|
Cached |
|
Downloaded |
|
Installed-package database ( |
Proxies#
apt honors environment variables (http_proxy, https_proxy,
ftp_proxy, no_proxy) but the durable place to set them is a
drop-in under /etc/apt/apt.conf.d/. That way sudo apt update and
unattended-upgrades see the same configuration.
$ sudo tee /etc/apt/apt.conf.d/95proxy >/dev/null <<'EOF'
Acquire::http::Proxy "http://proxy.lan:3128";
Acquire::https::Proxy "http://proxy.lan:3128";
Acquire::ftp::Proxy "http://proxy.lan:3128";
// Bypass the proxy for an internal mirror
Acquire::http::Proxy::mirror.lan "DIRECT";
EOF
For an organization-wide cache, run apt-cacher-ng (or squid-deb-proxy)
on a host inside the network and point every client at it. The cache
de-duplicates downloads of the same .deb across the fleet:
sequenceDiagram
participant C as client apt
participant AC as apt-cacher-ng
participant U as upstream mirror
C->>AC: GET nginx_*.deb
alt cached
AC-->>C: serve from local store
else miss
AC->>U: GET nginx_*.deb
U-->>AC: .deb bytes
AC-->>C: stream to client
Note over AC: kept in cache for the next client
end
Other fetch knobs in apt.conf.d/:
Directive |
Effect |
|---|---|
|
Retry failed downloads |
|
Per-connection timeout (seconds) |
|
Disable HTTP pipelining (some proxies misbehave) |
|
Skip IPv6 mirror records |
|
Refuse unsigned |
|
Drop privileges in the method handler |
Diagnose what apt is actually doing on the wire:
$ sudo apt -o Debug::Acquire::http=true update
$ sudo apt -o Debug::pkgAcquire::Worker=true update
$ /usr/lib/apt/methods/https </dev/null
$ sudo apt-get install --print-uris nginx
dnf (Fedora / RHEL)#
The default package manager on Fedora, RHEL 8+, AlmaLinux, Rocky
Linux, and CentOS Stream. dnf is a rewrite of the older yum
and accepts the same arguments, so transcripts and runbooks written
for either tool generally work on the other.
Install, remove, search#
$ sudo dnf install nginx
$ sudo dnf install ./local.rpm
$ sudo dnf remove nginx
$ sudo dnf upgrade
$ sudo dnf upgrade nginx
$ sudo dnf autoremove
$ dnf search redis
$ dnf info nginx
$ rpm -qa | grep nginx
$ rpm -ql nginx
$ rpm -qf /usr/sbin/nginx
Repositories and keys#
Repos live in /etc/yum.repos.d/*.repo. Keys can be inlined
as URLs in the .repo file (gpgkey=); dnf imports on
first use after asking for confirmation. Or import a key
explicitly with rpm --import.
$ sudo dnf install -y dnf-plugins-core
$ sudo dnf config-manager --add-repo \
https://download.docker.com/linux/fedora/docker-ce.repo
$ sudo dnf install docker-ce
$ sudo tee /etc/yum.repos.d/example.repo >/dev/null <<EOF
$ [example]
$ name=Example Repository
$ baseurl=https://repo.example.com/rhel/9/x86_64
$ enabled=1
$ gpgcheck=1
$ gpgkey=https://repo.example.com/keys/RPM-GPG-KEY-example
$ EOF
$ sudo rpm --import https://repo.example.com/keys/RPM-GPG-KEY-example
$ sudo dnf repolist
$ sudo dnf config-manager --set-enabled example
$ sudo dnf config-manager --set-disabled example
pacman (Arch)#
The Arch package manager. A single config file
(/etc/pacman.conf), a single command for install / remove /
upgrade, and a rolling-release model where pacman -Syu always
pulls the newest packages from the configured mirrors. AUR helpers
like yay add user-contributed packages on top.
Install, remove, search#
$ sudo pacman -Syu
$ sudo pacman -S nginx
$ sudo pacman -U ./local.pkg.tar.zst
$ sudo pacman -R nginx
$ sudo pacman -Rs nginx
$ sudo pacman -Rns nginx
$ pacman -Ss redis
$ pacman -Qs redis
$ pacman -Qi nginx
$ pacman -Ql nginx
$ pacman -Qo /usr/bin/nginx
The Arch User Repository (AUR) is accessed via yay, paru,
or makepkg.
Repositories and keys#
Repos are added as named [section] blocks in
/etc/pacman.conf. Keys go through pacman-key so they end
up signed by the local keyring, which pacman trusts.
$ sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
$ [example]
$ SigLevel = Required DatabaseOptional
$ Server = https://repo.example.com/arch/$arch
$ EOF
$ sudo pacman-key --recv-keys ABCD1234EF567890
$ sudo pacman-key --lsign-key ABCD1234EF567890
$ sudo pacman-key --add example.pub
$ sudo pacman-key --lsign-key 'maintainer@example.com'
$ sudo pacman -Sy
apk (Alpine)#
Alpine’s package manager: tiny, fast, and container-friendly. apk
ships in around a megabyte, which is a major reason Alpine is the
default base image for so many minimal containers. Repositories live
in /etc/apk/repositories; the main, community, and
testing tiers parallel Debian’s archive areas.
Install, remove, search#
$ sudo apk update
$ sudo apk upgrade
$ sudo apk add nginx
$ sudo apk add --no-cache nginx
$ sudo apk del nginx
$ apk search redis
$ apk info nginx
$ apk info -L nginx
$ apk info --who-owns /usr/sbin/nginx
Repositories and keys#
Each line in /etc/apk/repositories is one repo URL. Public
keys go in /etc/apk/keys/ as .rsa.pub files; apk
trusts everything in that directory.
$ echo 'https://repo.example.com/alpine/v3.20/main' | \
sudo tee -a /etc/apk/repositories
$ sudo wget -P /etc/apk/keys/ \
https://repo.example.com/alpine/example.rsa.pub
$ sudo apk update
$ sudo apk add example-pkg
$ sudo sed -i '/community$/s/^#//' /etc/apk/repositories
$ echo 'https://dl-cdn.alpinelinux.org/alpine/edge/testing' | \
sudo tee -a /etc/apk/repositories
zypper (openSUSE)#
Default on openSUSE Leap, Tumbleweed, and SUSE Linux Enterprise.
zypper operates on the same RPM packages as dnf but with its
own repo format (.repo files in /etc/zypp/repos.d/) and a
transactional snapper integration for rollback on Btrfs roots.
Install, remove, search#
$ sudo zypper refresh
$ sudo zypper update
$ sudo zypper dist-upgrade
$ sudo zypper install nginx
$ sudo zypper remove nginx
$ zypper search redis
$ zypper info nginx
$ zypper search --installed-only redis
Repositories and keys#
zypper addrepo writes a .repo file under
/etc/zypp/repos.d/. Keys are imported on first zypper
refresh; zypper prompts before trusting a new key.
$ sudo zypper addrepo -f \
https://download.opensuse.org/repositories/Example/openSUSE_Tumbleweed/Example.repo \
example
$ sudo zypper refresh
$ sudo zypper install example-pkg
$ sudo zypper repos
$ sudo zypper modifyrepo --disable example
$ sudo zypper removerepo example
$ sudo rpm --import https://example.com/repo-key.asc
Universal Formats#
Cross-distribution package formats and language-agnostic managers. Each one bundles its dependencies so the same artifact runs across distros without depending on the host’s libraries, useful for desktop apps with niche requirements, and for any tool an operator wants to carry from one engagement to the next.
Flatpak#
Sandboxed desktop apps; runtime + app split. Best for GUI tools.
$ sudo flatpak remote-add --if-not-exists flathub \
https://flathub.org/repo/flathub.flatpakrepo
$ flatpak install flathub org.mozilla.firefox
$ flatpak update
$ flatpak list
$ flatpak run org.mozilla.firefox
Snap#
A universal package format from Canonical. Auto-updates by default.
$ snap find code
$ sudo snap install code --classic
$ sudo snap refresh
$ snap list
AppImage#
Single-file portable executables. No install, just chmod +x.
$ chmod +x ./MyApp.AppImage
$ ./MyApp.AppImage
Homebrew#
Originally macOS, now first-class on Linux too.
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ brew install ripgrep
$ brew upgrade
$ brew list
Nix#
Declarative, reproducible packages. The package store
(/nix/store/) is content-addressed; multiple versions
coexist.
$ nix-env -iA nixpkgs.ripgrep
$ nix profile install nixpkgs#ripgrep
$ nix-channel --update
$ nix-collect-garbage -d
Building from Source#
When no package exists, or the packaged version is too old, build
from source. Each project picks one of a few standard build systems
(autotools, cmake, meson, language-native ones like
cargo or go build), so the operator’s job is to recognize the
system in use and run the right invocation.
Autotools#
The traditional ./configure && make && make install dance.
--prefix controls where files land; /usr/local is the
unwritten standard for source-built software.
$ ./configure --prefix=/usr/local
$ make -j"$(nproc)"
$ sudo make install
CMake#
Modern cross-platform build generator. -S is the source
directory, -B the build directory.
$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
$ cmake --build build -j"$(nproc)"
$ sudo cmake --install build
Meson#
Faster than autotools, simpler than CMake. Uses ninja as the
build backend.
$ meson setup build --buildtype=release
$ meson compile -C build
$ sudo meson install -C build
Packaging the result#
For anything beyond a one-off, build a real package instead of
make install:
checkinstall, wrapmake installand produce a.deb/.rpm.dpkg-buildpackage(Debian),rpmbuild(RHEL),makepkg(Arch), native packaging from a spec file.fpm, “effing package management”; build.deb/.rpm/.apkfrom a directory tree.
Common Tasks#
Identify the distribution and family. Pick the right tool.
$ cat /etc/os-release
$ command -v apt dnf yum pacman apk zypper
$ lsb_release -a 2>/dev/null
List installed packages. The software inventory.
$ dpkg -l 2>/dev/null | awk 'NR>5{print $2,$3}'
$ rpm -qa --queryformat '%{NAME} %{VERSION}\n' 2>/dev/null
$ pacman -Q 2>/dev/null
$ apk info -v 2>/dev/null
Audit package install history. When was what added.
$ grep -h 'install ' /var/log/dpkg.log* 2>/dev/null | tail -30
$ sudo dnf history list --reverse 2>/dev/null | head
$ grep -i installed /var/log/pacman.log 2>/dev/null | tail
Verify integrity. Find tampered packages.
$ sudo dpkg -V 2>/dev/null
$ sudo rpm -Va 2>/dev/null | head
$ sudo pacman -Qkk 2>/dev/null | grep -v '0 altered'
Identify out-of-repo binaries. Manual installs and side-loads.
$ apt list --installed 2>/dev/null | grep -i local
$ find /usr/local /opt -maxdepth 3 -type f -executable 2>/dev/null
$ ls -la /etc/apt/sources.list.d/ /etc/yum.repos.d/
Update, install, remove, hold. The four daily verbs.
$ sudo apt update && sudo apt -s upgrade
$ sudo apt install --no-install-recommends <pkg>
$ sudo apt remove --purge <pkg>
$ sudo apt-mark hold <pkg>
Search for a package. By name or by description.
$ apt search <term>; apt-cache search <term>
$ dnf search <term> 2>/dev/null
$ pacman -Ss <term> 2>/dev/null
$ apk search <term> 2>/dev/null
Show package details. Version, deps, maintainer, files.
$ apt show <pkg>; dpkg -s <pkg>; dpkg -L <pkg>
$ rpm -qi <pkg>; rpm -ql <pkg>; rpm -qR <pkg>
$ pacman -Qi <pkg>; pacman -Ql <pkg>
Find which package owns a file. The reverse lookup.
$ dpkg -S /usr/bin/curl
$ rpm -qf /usr/bin/curl
$ pacman -Qo /usr/bin/curl
$ apk info --who-owns /usr/bin/curl
Manage repositories and keys. Add, remove, refresh.
$ ls /etc/apt/sources.list.d/ /etc/yum.repos.d/
$ sudo add-apt-repository ppa:<owner>/<ppa>
$ sudo apt-key list 2>/dev/null; ls /etc/apt/trusted.gpg.d/
$ sudo dnf config-manager --add-repo <url> 2>/dev/null
Patch security updates only. Minimum-impact upgrade path.
$ sudo unattended-upgrade --dry-run -d 2>/dev/null
$ sudo apt list --upgradable 2>/dev/null
$ sudo dnf updateinfo list security 2>/dev/null
$ sudo dnf upgrade --security 2>/dev/null
Roll back a bad upgrade. Pin a known-good version.
$ apt list -a <pkg> 2>/dev/null
$ sudo apt install <pkg>=<version>
$ sudo dnf history undo <id> 2>/dev/null
$ sudo pacman -U /var/cache/pacman/pkg/<pkg>-<old>.pkg.tar.zst
Files & paths#
Configuration, repository, key, cache, database, and log locations per package manager. Knowing where each manager stores state is what lets you mirror a repo, swap a key, free disk space, or audit what is configured before installing anything new.
apt / dpkg (Debian / Ubuntu)#
/etc/apt/sources.list, main repository list./etc/apt/sources.list.d/*.list, per-repo extra files./etc/apt/sources.list.d/*.sources, DEB822 format (newer)./etc/apt/preferences/preferences.d/, pinning and priorities./etc/apt/apt.conf/apt.conf.d/*, apt behavior tuning./etc/apt/keyrings/, repository signing keys (modern path)./etc/apt/trusted.gpg.d/, legacy keyring location./var/lib/apt/lists/, downloaded package indexes./var/cache/apt/archives/, downloaded.debfiles./var/lib/dpkg/status, the installed-package database./var/lib/dpkg/info/<pkg>.{conffiles,md5sums,list,...}, per-package metadata./var/log/dpkg.log, install / remove history./var/log/apt/history.log, apt operations./etc/dpkg/dpkg.cfg, dpkg defaults.
dnf / rpm (Fedora / RHEL)#
/etc/yum.repos.d/*.repo, repository definitions./etc/dnf/dnf.conf, dnf configuration./etc/yum.conf, yum configuration (legacy)./etc/pki/rpm-gpg/, repository signing keys./var/cache/dnf/, metadata and downloaded RPMs./var/lib/rpm/, the RPM database./var/log/dnf.log/dnf.rpm.log/dnf.librepo.log, operation logs./var/log/yum.log, yum history (legacy).
pacman (Arch)#
/etc/pacman.conf, pacman configuration./etc/pacman.d/mirrorlist, mirror selection./etc/pacman.d/hooks/, post-transaction hooks./var/cache/pacman/pkg/, downloaded packages./var/lib/pacman/local/, installed package metadata./var/lib/pacman/sync/, repository databases./var/log/pacman.log, transaction log.
apk (Alpine)#
/etc/apk/repositories, repository URLs./etc/apk/world, explicitly-installed packages (the user’s “wishlist”)./etc/apk/keys/, signing keys./var/cache/apk/, package cache./lib/apk/db/, installed-package database.
zypper (openSUSE)#
/etc/zypp/zypp.conf, zypper configuration./etc/zypp/repos.d/*.repo, repositories./var/cache/zypp/, cache./var/log/zypper.log, operations.
Cross-distribution / language managers#
Flatpak,
/var/lib/flatpak/system,~/.local/share/flatpak/user.Snap,
/var/lib/snapd/,/var/snap/<pkg>/data,/snap/mounts.Homebrew (Linux),
/home/linuxbrew/.linuxbrew/.Nix,
/nix/store/,/etc/nixos/configuration.nix(NixOS).pip:~/.config/pip/pip.conf,~/.cache/pip/.npm:~/.npmrc,~/.npm/(cache),node_modules/per project.cargo:~/.cargo/config.toml,~/.cargo/registry/.go:$GOPATH(default~/go),~/go/pkg/mod/.
References#
man 8 apt,man 8 apt-get,man 1 dpkg,man 5 sources.list(Debian / Ubuntu).man 8 dnf,man 8 yum,man 8 rpm,man 5 dnf.conf(Red Hat family).man 8 pacman,man 5 pacman.conf,man 8 makepkg(Arch).man 8 apk(Alpine).man 8 zypper(openSUSE).man 8 emerge,man 5 portage(Gentoo).Distributions for which family ships each manager by default.
Services for systemd timers that drive unattended upgrades.
Hardening for signature verification, third-party-repo posture, and lockdown of unsigned modules.
Python for
pip/uv/poetryecosystem detail.Repology (cross-distro package versions)