Linux Package Management & Software Building — apt/dpkg, dnf/rpm, pacman, from-source & kernel build
Parent: DevOps, Infrastructure & Observability · researched 2026-06-01T06:05:11.290Z· 17 sources · 8 concepts · skill linux-package-management
A Linux package is an archive of files plus metadata (name, version, dependencies, scripts,
Overview
- A Linux package is an archive of files plus metadata (name, version, dependencies, scripts, [source]
- signature). A package manager resolves dependencies, fetches packages from repositories, [source]
- verifies their signatures, and applies the change as a transaction recorded in a local database. [source]
- There are two layers in every native stack: [source]
- Low-level tool - operates on a single local package file and the package DB. No dependency [source]
- resolution, no network: dpkg (.deb), rpm (.rpm), pacman -U (.pkg.tar.zst). [source]
- High-level tool - resolves dependencies and talks to repositories: apt, dnf, pacman -S. [source]
- Use the high-level tool for normal work; drop to the low-level tool only to install a downloaded [source]
- file or to inspect/repair the database. The three native ecosystems map cleanly onto each other, [source]
- so once you know the model you mostly translate verbs. Above the native layer sit the [source]
- universal formats (Flatpak, Snap, Nix) which bundle dependencies and are cross-distro. [source]
Core Concepts (the shared branch)
- These ideas are identical across apt, dnf, and pacman - learn them once. [source]
- Package + metadata. Files + a manifest declaring Depends/Requires/depends, [source]
- Conflicts, Provides (virtual packages, e.g. mail-transport-agent), version constraints, [source]
- and pre/post install scripts. [source]
- Dependency resolution. Given a request, the solver computes a consistent set of installs, [source]
- upgrades, and removals. Modern solvers are SAT/backtracking-based (APT's solver3, dnf's [source]
- libsolv, pacman's internal resolver). When no consistent set exists you get a conflict the [source]
- Repositories. Signed collections of packages + an index (Debian Release/Packages, [source]
- RPM repodata/repomd.xml, Arch *.db). The client downloads the index, then packages. [source]
- Metadata cache vs installed DB. Two distinct things: the downloaded repo index (refreshed by [source]
- apt update, dnf makecache, pacman -Sy) and the local installed-package DB [source]
- (/var/lib/dpkg, the rpmdb in /var/lib/rpm or /usr/lib/sysimage/rpm, /var/lib/pacman/local). [source]
- Transaction. An all-or-nothing batch. dnf records every transaction with full undo/rollback; [source]
- dpkg/apt and pacman keep logs (/var/log/dpkg.log, /var/log/pacman.log) but weaker rollback. [source]
- Trust/signing. Repos sign their index; clients verify against a trusted keyring before [source]
- trusting any package hash. This is the security boundary - never disable it casually. [source]
- Explicit vs dependency (orphan tracking). Managers mark whether you asked for a package or it [source]
- came in as a dependency, so orphans can be auto-removed (apt autoremove, dnf autoremove, [source]
apt / dpkg (Debian, Ubuntu, Mint, Pop!_OS)
- APT 3.0+ (Debian 13 "trixie", Ubuntu 25.04+) ships a colorized UI and solver3, a [source]
- backtracking, SAT-solver-inspired resolver with unit propagation - faster, more predictable, [source]
- better at preserving the order of alternatives and explaining conflicts than the classic solver. [source]
- 3.1 added per-repo package excludes; 3.3.1 continued solver tuning. Signature verification moved [source]
- to Sequoia-PGP (sqv) instead of GnuPG. [source]
- Repository config: /etc/apt/sources.list (legacy one-line) or *.list / [source]
- modern deb822 *.sources files in /etc/apt/sources.list.d/. Each repo's signing key goes in [source]
- /usr/share/keyrings/*.gpg (or .pgp) and is bound with Signed-By: (deb822) or [source]
- [signed-by=…] (one-line). apt-key is deprecated - never add keys to the global keyring. [source]
- apt is the human-facing CLI; apt-get/apt-cache are the stable scripting interfaces. [source]
dnf / rpm (Fedora, RHEL, Rocky, Alma, openSUSE uses zypper)
- dnf5 (default in Fedora 41+; the C++ rewrite) is faster and replaces dnf/microdnf. Note [source]
- partial parity gaps: some users hit Unknown argument 'undo' and rollback edge cases on dnf5 [source]
- — verify history subcommands on your version. dnf 5.4 improved transaction history precision. [source]
- RHEL caveat: dnf history undo/rollback is not supported for downgrading core packages [source]
- (kernel, glibc, selinux-policy-*); downgrading to a prior minor version can leave the system [source]
- Verification: repos set gpgcheck=1 and gpgkey= in their .repo. Verify with [source]
- rpm --checksig pkg.rpm; rpm -V audits an installed package against the DB (size, mode, digest, [source]
- ownership drift). rpmdb may live at /usr/lib/sysimage/rpm on newer systems. [source]
pacman (Arch, Manjaro, EndeavourOS)
- Flag grammar: operations are -S sync, -R remove, -Q query, -U upgrade(local); modifiers [source]
- stack (y refresh DB, u upgrade, s search, i info, c clean). So -Syu = refresh + upgrade. [source]
- AUR (Arch User Repository): user-submitted PKGBUILD recipes, not binaries. Workflow: [source]
- git clone the AUR repo → review the PKGBUILD → makepkg -si (build + install with deps). AUR [source]
- helpers (paru, yay) automate this but you own the security review. Popular PKGBUILDs graduate [source]
- to the extra repo as binaries. [source]
- Signing: pacman verifies via the archlinux-keyring (pacman-key). A stale keyring causes [source]
- "invalid or corrupted package (PGP signature)" - fix with sudo pacman -Sy archlinux-keyring [source]
- then retry the upgrade, or sudo pacman-key --refresh-keys. [source]
Universal formats (cross-distro, dependency-bundled)
- Flatpak - sandboxed desktop apps, community-governed via Flathub, shared runtimes to cut [source]
- duplication, fine-grained portal permissions. flatpak install flathub <app-id>, [source]
- flatpak update, flatpak run <app-id>. Best security/disk profile of the three. [source]
- Snap - Canonical's compressed read-only SquashFS images mounted by snapd; auto-updating; [source]
- centralized Snap Store. snap install <name>, snap refresh. Slower cold start (mount cost), [source]
- Nix - declarative, immutable, content-addressed /nix/store; reproducible and rollback-able; [source]
- 122k+ packages (largest, most current repo as of 2025). Not a distro-native verb - it's a different [source]
- model (see the immutable-atomic-linux reference for NixOS-as-OS). nix profile install, flakes. [source]
Building from source
- When no package exists, the version is too old, or you need custom build flags. [source]
The three build systems you'll meet
- Autotools (./configure && make && sudo make install): configure probes the host for [source]
- toolchain/libraries and generates the Makefile; make compiles; make install copies into the [source]
- CMake: `cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr/local && cmake --build build -j$(nproc) [source]
- && sudo cmake --install build`. [source]
- Meson + Ninja: `meson setup build --prefix=/usr/local && meson compile -C build && [source]
- sudo meson install -C build`. [source]
Source-build hygiene (the patterns that keep it maintainable)
- Get the deps first. sudo apt build-dep <pkg> / sudo dnf builddep <spec> / [source]
- pull makedepends via the PKGBUILD. Read the project README/INSTALL - honor its [source]
- recommendation over generic advice. [source]
- Verify the tarball. Download from a trusted origin; check the GPG signature or checksum [source]
- before extracting. Supply-chain risk lives here. [source]
- Never build or run make as root. Build as your user; only make install (the copy step) [source]
- Isolate the prefix for easy removal. Default /usr/local collides nothing with the package [source]
- manager (which owns /usr), but an explicit versioned prefix like /opt/foo-1.2.3 or [source]
- --prefix=$HOME/.local is cleaner and trivially removable. There is usually **no `make [source]
- uninstall`**, so isolation matters. [source]
- Make it removable / trackable. Prefer one of: [source]
- checkinstall - wraps make install to produce a real .deb/.rpm/.tgz so the package [source]
- manager tracks and can cleanly remove it. [source]
- GNU Stow - make install into /usr/local/stow/foo-1.2.3, then stow symlinks it into [source]
- /usr/local; stow -D removes it atomically. [source]
- Building a proper native package (.deb via debuild, .rpm via rpmbuild/.spec, [source]
- .pkg.tar.zst via PKGBUILD) for anything you'll ship. [source]
- Run ldconfig after installing shared libraries to a new path; add the dir to [source]
- /etc/ld.so.conf.d/ if outside the default search path. [source]
Kernel build basics
- Compiling a custom kernel from kernel.org source (or your distro's source) - for new hardware, [source]
- debugging, custom config, or learning. [source]
- Get source + deps. Extract the tarball; install build deps (build-essential/gcc make, [source]
- bison flex libssl-dev libelf-dev bc, ncurses for menuconfig). [source]
- Configure - produce a .config: [source]
- make menuconfig - ncurses menu editor (also nconfig, xconfig, gconfig). [source]
- make localmodconfig - the practical shortcut: reads lsmod and disables every module not [source]
- currently loaded, producing a lean, fast-building config tailored to this machine. (Pass a [source]
- captured lsmod via LSMOD=file to target another machine.) [source]
- make olddefconfig - carry an existing .config forward, defaulting new symbols. [source]
- Common base: cp /boot/config-$(uname -r) .config then make olddefconfig. [source]
- Build. make -j$(nproc) - uses all cores; still typically 1–2+ hours for a full config, [source]
- minutes for a localmodconfig-trimmed one. Produces arch/x86/boot/bzImage (the compressed [source]
- kernel image) and the built modules. [source]
- Install modules. sudo make modules_install → copies into /lib/modules/<version>/. [source]
- Install kernel. sudo make install (distro-friendly: copies bzImage to /boot, generates the [source]
- initramfs, and updates the bootloader on most distros) - or manually copy bzImage to [source]
- /boot/vmlinuz-<ver>, build the initramfs (dracut/update-initramfs), and regenerate GRUB [source]
- (grub-mkconfig -o /boot/grub/grub.cfg or grub2-mkconfig). See linux-boot-init for the [source]
- initramfs + bootloader chain and linux-kernel-architecture for module/ABI internals. [source]
- Reboot and pick the entry; verify with uname -r. Keep the old kernel as a fallback boot [source]
- entry - never delete the working kernel until the new one boots clean. [source]
Anti-patterns
- pacman -Sy <pkg> (partial upgrade). The single most dangerous Arch mistake. It refreshes the [source]
- DB and installs/upgrades one package (pulling new library deps) without upgrading the rest of the [source]
- system. Because Arch is rolling and keeps no old library versions, this breaks other packages [source]
- linked against the now-removed library. Always pacman -Syu - and refusing the upgrade prompt [source]
- after -Sy is just as bad. Never -Sy then -S. [source]
- apt-key add / dropping keys in the global keyring. Deprecated and insecure (one bad repo can [source]
- sign anything). Use a per-repo keyring + Signed-By:. [source]
- sudo make install of an untracked source build into /usr or /. Collides with the package [source]
- manager and is near-impossible to remove. Use /usr/local, an isolated prefix, checkinstall, or [source]
- Mixing repos / "Frankendebian". Pinning packages from a newer release (e.g. Debian [source]
- testing/unstable on stable, or random third-party repos) without proper apt pinning causes [source]
- dependency hell. Use apt-pinning deliberately or not at all. [source]
- Disabling GPG checks (--allow-unauthenticated, gpgcheck=0, --nosignature) to "fix" a key [source]
- error. Fix the key, don't disable the trust boundary. [source]
- rm-ing files instead of removing the package. Leaves the DB believing the package is present. [source]
- Always go through the manager. [source]
- dnf history rollback on RHEL core packages (kernel/glibc/selinux) - unsupported; can brick [source]
- Running a full menuconfig from scratch. Thousands of symbols; you'll misconfigure something. [source]
- Start from the running config or localmodconfig. [source]
References
- APT 3.0 / solver3 - LWN, "What's new in APT 3.0": https://lwn.net/Articles/1017315/ [source]
- Ubuntu Community Hub, "Evaluating the new APT solver in 25.04": https://discourse.ubuntu.com/t/evaluating-the-new-apt-solver-in-25-04/55618 [source]
- Debian Wiki - SecureApt & UseThirdParty (repo signing, deb822, Signed-By): https://wiki.debian.org/SecureApt , https://wiki.debian.org/DebianRepository/UseThirdParty [source]
- Red Hat docs, "Handling package management history" (dnf history undo/rollback): https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/managing_software_with_the_dnf_tool/assembly_handling-package-management-history_managing-software-with-the-dnf-tool [source]
- Baeldung, "DNF: history rollback vs. undo": https://www.baeldung.com/linux/dnf-dnf-history-rollback-vs-undo [source]
- ArchWiki - pacman, PKGBUILD, Arch User Repository, System maintenance: https://wiki.archlinux.org/title/Pacman , https://wiki.archlinux.org/title/PKGBUILD , https://wiki.archlinux.org/title/Arch_User_Repository , https://wiki.archlinux.org/title/System_maintenance [source]
- Arch Forums, "Why is pacman -Sy bad?" (partial upgrade hazard): https://bbs.archlinux.org/viewtopic.php?id=241092 [source]
- unixwiz, "Good practices for building packages from source": http://www.unixwiz.net/techtips/building-source.html [source]
- kernel.org admin-guide README (kernel build): https://www.kernel.org/doc/Documentation/admin-guide/README.rst [source]
- ArchWiki - Kernel/Traditional compilation (menuconfig, localmodconfig, modules_install): https://wiki.archlinux.org/title/Kernel/Traditional_compilation [source]
- Linux Magazine, "Universal Package Formats" (Flatpak/Snap/Nix): https://www.linux-magazine.com/Issues/2025/298/Universal-Package-Formats [source]
- NixOS package count / model (2025): https://nixos.org [source]
Children
- Shared package model (packages, dependencies, repositories, transactions, signing, explicit-vs-dependency) (frontier)
- apt/dpkg on Debian/Ubuntu (APT 3.0 solver3, deb822 + Signed-By keyrings, apt-mark hold, dpkg low-level) (frontier)
- dnf/rpm on Fedora/RHEL (dnf5, transaction history undo/rollback, gpgcheck, rpm -V/--rebuilddb, RHEL core-package caveat) (frontier)
- pacman on Arch (-Syu vs the partial-upgrade hazard, flag grammar, orphans, archlinux-keyring desync, PKGBUILD/makepkg/AUR) (frontier)
- Universal formats — Flatpak/Snap/Nix (dependency-bundled, cross-distro tradeoffs) (frontier)
- Building from source (autotools configure/make, CMake, Meson/Ninja, prefix isolation, checkinstall, GNU Stow, ldconfig) (frontier)
- Linux kernel build (menuconfig/localmodconfig/olddefconfig, make -j, modules_install, bzImage, initramfs + GRUB, fallback boot) (frontier)
- Cross-distro troubleshooting (NO_PUBKEY, dpkg interrupted, broken/held deps, rpmdb corruption, pacman PGP signature, missing -dev headers, kernel won't boot) (frontier)
Frontier under this node: Building from source (autotools configure/make, CMake, Meson/Ninja, prefix isolation, checkinstall, GNU Stow, ldconfig), Cross-distro troubleshooting (NO_PUBKEY, dpkg interrupted, broken/held deps, rpmdb corruption, pacman PGP signature, missing -dev headers, kernel won't boot), Linux kernel build (menuconfig/localmodconfig/olddefconfig, make -j, modules_install, bzImage, initramfs + GRUB, fallback boot), Shared package model (packages, dependencies, repositories, transactions, signing, explicit-vs-dependency), Universal formats — Flatpak/Snap/Nix (dependency-bundled, cross-distro tradeoffs), apt/dpkg on Debian/Ubuntu (APT 3.0 solver3, deb822 + Signed-By keyrings, apt-mark hold, dpkg low-level), dnf/rpm on Fedora/RHEL (dnf5, transaction history undo/rollback, gpgcheck, rpm -V/--rebuilddb, RHEL core-package caveat), pacman on Arch (-Syu vs the partial-upgrade hazard, flag grammar, orphans, archlinux-keyring desync, PKGBUILD/makepkg/AUR)