Skip to content

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:

# /etc/apt/preferences.d/pin-nginx
Package: nginx
Pin: version 1.24.*
Pin-Priority: 1001

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

Package Version Management

# Install a specific version
sudo apt install nginx=1.24.0-1

# List all available versions of a package
apt-cache policy packagename

# Show what version is currently installed vs available
apt-cache showpkg packagename