Debian package management cheatsheet

2025-06-18 — debian, apt, dpkg

Comprehensive-ish reference for apt and dpkg. Mostly things I use regularly but keep half-forgetting the exact flags for.

apt — everyday commands

# Update package index (always do this first)
apt update

# Upgrade installed packages (keeps held packages back)
apt upgrade

# Upgrade everything including held packages, remove obsolete deps
apt full-upgrade

# Install a package
apt install nginx

# Remove a package (keeps config files)
apt remove nginx

# Remove a package and its config files
apt purge nginx

# Remove orphaned dependencies
apt autoremove

# Remove orphaned deps + clean up downloaded package files
apt autoremove --purge && apt clean

Searching and inspecting

# Search package names and descriptions
apt search nginx

# Show package details (version, deps, description)
apt show nginx

# List all installed packages
apt list --installed

# List packages with available upgrades
apt list --upgradable

# Show candidate version and where it comes from
apt-cache policy nginx

dpkg — working with individual packages

# List all installed packages (pipe to grep to filter)
dpkg -l | grep nginx

# List files installed by a package
dpkg -L nginx

# Which package owns a file
dpkg -S /usr/sbin/nginx

# Install a .deb file directly
dpkg -i package.deb

# Show package info from a .deb file before installing
dpkg -I package.deb

# Fix interrupted installs (run after dpkg errors)
dpkg --configure -a

Held packages

Holding a package prevents apt from upgrading it. Useful when you need a specific version or when an upgrade would break something you depend on.

# Hold a package at its current version
apt-mark hold nginx

# Release a hold
apt-mark unhold nginx

# List held packages
apt-mark showhold

apt upgrade respects holds. apt full-upgrade will still skip them but warn. dpkg ignores holds entirely — be careful with dpkg -i on held packages.

Managing sources

Package sources live in /etc/apt/sources.list and files in /etc/apt/sources.list.d/. Prefer the .d/ directory for third-party repos so they're isolated and easy to remove.

# Modern format (DEB822) — one file per repo in /etc/apt/sources.list.d/
# /etc/apt/sources.list.d/example.sources
Types: deb
URIs: https://packages.example.com/debian
Suites: bookworm
Components: main
Signed-By: /usr/share/keyrings/example-archive-keyring.gpg
# Download and store a signing key properly
curl -fsSL https://packages.example.com/key.gpg \
  | gpg --dearmor \
  | sudo tee /usr/share/keyrings/example-archive-keyring.gpg > /dev/null
The old pattern of apt-key add and keys in /etc/apt/trusted.gpg is deprecated. Use per-repo keyring files in /usr/share/keyrings/ with Signed-By: in the source definition.

Cleaning up disk space

# Remove cached package files (.deb files in /var/cache/apt/archives/)
apt clean

# Remove only packages that can no longer be downloaded (obsolete)
apt autoclean

# See how much space the package cache is using
du -sh /var/cache/apt/archives/

Useful one-liners

# List explicitly installed packages (not pulled in as deps)
apt-mark showmanual

# Reinstall a package (useful when config files get mangled)
apt install --reinstall nginx

# Download a package without installing it
apt-get download nginx

# Find which package provides a command
dpkg -S $(which nginx)
# or if not installed yet:
apt-file search bin/nginx   # requires apt-file package