APT and dpkg on Debian-Based Systems
Operate Debian and Ubuntu package systems safely with APT for repository-aware transactions and dpkg tools for installed-state inspection, files, versions, and recovery evidence.
Learning objectives
By the end of this lesson
- Explain the responsibilities of APT, dpkg, repository indexes, and the dpkg status database.
- Use APT to search, inspect candidates, simulate transactions, install, upgrade, remove, and purge packages deliberately.
- Use dpkg-query and dpkg-deb for installed-state and archive inspection.
- Distinguish metadata refresh, package upgrade, full dependency transitions, autoremove, and cache cleanup.
- Capture an APT transaction preview and package inventory suitable for change review.
1. APT plans; dpkg records and applies
On Debian-based systems, APT reads configured package sources,
downloads repository indexes, chooses candidate versions, solves
dependencies, retrieves archives, and coordinates transactions. The
dpkg system handles Debian package archives and the
installed package database. In normal administration, use APT for
installation, upgrade, and removal; use dpkg tools to inspect
installed state, file ownership, archive metadata, and carefully
diagnosed failures.
flowchart TD S["sources.list and .sources files"] --> U["apt update"] U --> C["Local package indexes"] C --> P["APT policy and dependency solver"] D["dpkg installed-state database"] --> P P --> T["Transaction preview"] T --> A["Download .deb archives"] A --> V["Archive and repository verification"] V --> K["dpkg unpack and configure"] K --> D
The command apt update refreshes local metadata; it
does not upgrade installed packages. A package becomes installed or
upgraded only when a transaction command is applied.
2. Inspect sources and policy before changing packages
APT sources may be defined in /etc/apt/sources.list,
traditional files under /etc/apt/sources.list.d/*.list,
or deb822-style .sources files. Each source selects
repository URIs, suites, components, architectures, and trust
configuration. On production systems, source changes deserve the
same review as code changes.
# Read configured source declarations without exposing comments as commands.
grep -RhsE '^[[:space:]]*(deb |Types:|URIs:|Suites:|Components:|Signed-By:)' \
/etc/apt/sources.list /etc/apt/sources.list.d 2>/dev/null || true
# Inspect candidate selection for a known package.
apt-cache policy bash
apt-cache show bash | sed -n '1,30p'
# Search names and descriptions.
apt-cache search '^curl$|command line.*URL' | head -20
apt-cache policy shows the installed version, candidate
version, source versions, and priorities. Use it whenever an
unexpected version or repository origin appears.
3. Preview every meaningful transaction
Interactive apt is convenient for humans.
apt-get provides a more stable command interface for
scripts and automation. Both can simulate many actions without
changing the system.
package=${1:-jq}
# Refreshing indexes requires privileges and network access.
# sudo apt-get update
# Preview installation without changing state.
apt-get --simulate install "$package"
# Preview ordinary upgrades.
apt-get --simulate upgrade
# Preview dependency-changing upgrades and removals.
apt-get --simulate dist-upgrade
# Download a package archive without installing it.
apt-get download "$package" 2>/dev/null || apt download "$package"
4. Query installed state with dpkg tools
dpkg-query reads installed package information.
dpkg-deb inspects a .deb archive without
installing it. These tools are valuable for incident evidence and
packaging diagnostics.
# Installed status, version, architecture, and description.
dpkg-query -W -f='${binary:Package}\t${db:Status-Abbrev}\t${Version}\t${Architecture}\n' bash
# List files installed by a package.
dpkg-query -L bash | sed -n '1,30p'
# Find which installed package owns a path.
dpkg-query -S /bin/bash 2>/dev/null || dpkg-query -S /usr/bin/bash
# Show conffiles and recorded checksums where available.
dpkg-query -W -f='${Conffiles}\n' openssh-client 2>/dev/null || true
# Inspect a downloaded archive without installation.
deb=$(find . -maxdepth 1 -name '*.deb' -print -quit)
if [ -n "$deb" ]; then
dpkg-deb --info "$deb"
dpkg-deb --contents "$deb" | head -30
fi
The dpkg status abbreviations reveal desired action, current state, and error conditions. A package can be unpacked but not configured; dependency repair should be based on the specific state and logs rather than repeated blind commands.
5. Removal, purge, holds, and automatic marks
Package state includes more than “installed” or “absent.” A package may be marked manually installed or automatically installed as a dependency. It may be held to prevent automatic version changes. Configuration files declared as conffiles have special upgrade and removal behavior.
# Review manually installed packages and holds.
apt-mark showmanual | sort | head -40
apt-mark showhold
# Inspect why a package is installed when apt-rdepends is available.
package=${1:-libc6}
apt-cache rdepends --installed "$package" | sed -n '1,60p'
# Preview removal and purge; neither command below changes state.
apt-get --simulate remove "$package"
apt-get --simulate purge "$package"
# Preview autoremove before considering it.
apt-get --simulate autoremove
A hold can be a temporary compatibility control, but it also suppresses fixes. Record the owner, reason, scope, review date, and removal condition.
6. Hands-on lab: produce an APT change-review bundle
This lab performs read-only queries and a simulated install. It captures enough evidence for a reviewer to understand sources, candidate policy, dependencies, installed state, and proposed changes.
lab="$HOME/devops-academy/linux/chapter09/lesson02"
mkdir -p "$lab"
package=${1:-jq}
if ! command -v apt-get >/dev/null 2>&1; then
printf 'This lab requires a Debian-family APT system.\n' >&2
exit 1
fi
{
printf '=== os ===\n'
cat /etc/os-release
printf '\n=== package policy ===\n'
apt-cache policy "$package"
printf '\n=== package metadata ===\n'
apt-cache show "$package" | sed -n '1,80p'
printf '\n=== reverse dependencies ===\n'
apt-cache rdepends --installed "$package" | sed -n '1,80p'
printf '\n=== transaction simulation ===\n'
apt-get --simulate install "$package"
printf '\n=== holds ===\n'
apt-mark showhold
printf '\n=== dpkg audit ===\n'
dpkg --audit || true
} > "$lab/apt-review.txt"
less "$lab/apt-review.txt"
Verification checklist
7. Common mistakes
Using apt output as a scripting API
Prefer apt-get, apt-cache, and
dpkg-query with explicit formats in automation.
Running autoremove without preview
Automatic marks may not reflect current application ownership. Simulate and inspect the package list first.
Deleting APT or dpkg lock files
A lock usually indicates another package operation. Identify the owner and wait or recover the interrupted transaction correctly.
Mixing Debian and Ubuntu repositories
Similar package formats do not guarantee compatible dependency graphs, policies, or support lifecycles.
8. Knowledge check
Question 1. What does apt update change?
Question 2. What is the practical difference between remove and purge?
Question 3. Why inspect apt-cache policy?
9. Summary
APT is the repository-aware transaction planner for Debian-family systems, while dpkg maintains installed package state and applies Debian archives. Safe operation means inspecting sources and candidate policy, simulating meaningful changes, distinguishing update from upgrade, understanding remove versus purge, and preserving evidence for holds, automatic packages, and recovery conditions.
10. Further reading
-
Debian
apt(8),apt-get(8),apt-cache(8), andsources.list(5). -
Debian
dpkg(1),dpkg-query(1), anddpkg-deb(1). - APT User's Guide and Debian Reference package-management chapter.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.