Package Management¶
Reference: Debian Wiki — apt · sources.list(5) (deb822 format) · Debian Policy Manual
apt — Core Commands¶
apt is Debian's package manager (Ubuntu inherited it). Debian 13 ships APT 3.0. It's a higher-level frontend to dpkg.
# Update package index (always run before install/upgrade)
sudo apt update
# Upgrade all installed packages
sudo apt upgrade
# Full upgrade — also handles dependency changes and removals
sudo apt full-upgrade
# Install a package
sudo apt install packagename
# Install multiple packages
sudo apt install nginx curl git htop
# Remove a package (keep config files)
sudo apt remove packagename
# Remove a package and its config files
sudo apt purge packagename
# Remove unused dependencies
sudo apt autoremove
# Remove unused dependencies and purge configs
sudo apt autoremove --purge
# Clean downloaded package cache
sudo apt clean # removes all cached .deb files
sudo apt autoclean # removes only outdated cached .deb files
Searching & Inspecting¶
# Search for a package by name or description
apt search keyword
# Show package details (version, dependencies, description)
apt show packagename
# List installed packages
apt list --installed
# List upgradable packages
apt list --upgradable
# Find which package provides a file
dpkg -S /usr/bin/curl
# List files installed by a package
dpkg -L packagename
# Check if a package is installed
dpkg -l packagename
Pinning & Held Packages¶
Pinning prevents a package from being upgraded — useful when a newer version breaks something.
# Hold a package at current version
sudo apt-mark hold packagename
# Unhold a package
sudo apt-mark unhold packagename
# List all held packages
apt-mark showhold
For more granular pinning, create a preferences file:
Sources & Repositories¶
Debian 13 uses the deb822 format: one .sources file per repository in /etc/apt/sources.list.d/, with the
signing key referenced by Signed-By. The old one-line .list format still works, but new guides and the release
notes use deb822.
# View current sources
ls /etc/apt/sources.list.d/
cat /etc/apt/sources.list.d/*.sources
cat /etc/apt/sources.list 2>/dev/null # legacy file, if present
# Convert legacy sources.list / *.list files to deb822
sudo apt modernize-sources
Add a third-party repository¶
This is the pattern Docker, Tailscale and most vendors use. Download the key into /etc/apt/keyrings/ and point only
that repository at it (never apt-key, which is gone):
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://repo.example.com/gpg.asc -o /etc/apt/keyrings/example.asc
sudo chmod a+r /etc/apt/keyrings/example.asc
sudo tee /etc/apt/sources.list.d/example.sources <<EOF
Types: deb
URIs: https://repo.example.com/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: main
Signed-By: /etc/apt/keyrings/example.asc
EOF
sudo apt update
PPAs are an Ubuntu thing
add-apt-repository ppa:user/repo adds Ubuntu Launchpad PPAs. Their packages are built for Ubuntu releases, so
don't add them to Debian. Use the vendor's Debian repository or Debian's own package instead.
Unattended Upgrades¶
Automatically install security updates. The Debian installer usually installs unattended-upgrades (check with
dpkg -l unattended-upgrades), and by default it applies Debian security updates only.
# Install / turn on
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades # writes /etc/apt/apt.conf.d/20auto-upgrades
# What would it do right now?
sudo unattended-upgrade --dry-run -d
Don't edit 50unattended-upgrades; put overrides in a later file such as 52unattended-upgrades-local so package
upgrades never conflict with your changes. On my servers it also installs stable point releases and
*-updates, holds Docker packages back (an upgrade restarts every container), and never reboots by itself: a separate
timer reboots in a weekly window only when /run/reboot-required exists. The full setup is in
Host Maintenance.
dpkg — Low-Level Package Tool¶
dpkg is the underlying package manager. Use it when dealing with .deb files directly.
# Install a .deb file
sudo dpkg -i package.deb
# Fix broken dependencies after manual dpkg install
sudo apt install -f
# Remove a package
sudo dpkg -r packagename
# List all installed packages
dpkg -l
# Query package status
dpkg -s packagename
# Extract contents of a .deb without installing
dpkg -x package.deb /tmp/extracted/
Useful Combinations¶
# Full system update in one line
sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y
# Install a package non-interactively (scripts/automation)
sudo DEBIAN_FRONTEND=noninteractive apt install -y packagename # set after sudo, or sudo drops it
# Simulate an install without actually doing it
sudo apt install --dry-run packagename
# Download a package without installing
apt download packagename