The apt Package Manager: A Complete Guide for Ubuntu and Debian

Short answer

The four commands you will use every week: refresh the package lists, upgrade everything, install something, and clean up afterwards.

sudo apt update
sudo apt upgrade
sudo apt install <package>
sudo apt autoremove

How apt works

apt is the high-level package manager on Debian, Ubuntu, Linux Mint, Pop!_OS, Raspberry Pi OS, Kali and every other Debian-based distribution. It downloads .deb packages from repositories, works out dependencies, and hands the actual unpacking to dpkg, the low-level tool underneath. If you understand that split, most apt errors make sense: problems with lists, keys and dependencies are apt's; problems with half-installed packages and maintainer scripts are dpkg's.

Three pieces of state matter:

  • Sources — which repositories apt reads, defined in /etc/apt/sources.list and files in /etc/apt/sources.list.d/.
  • Package lists — the downloaded index of what each repository offers, in /var/lib/apt/lists/. apt update refreshes these.
  • The dpkg database — what is actually installed, in /var/lib/dpkg/.

apt and apt-get/apt-cache share all of this. Use apt interactively and apt-get in scripts, because apt warns that its output format may change. For a side-by-side with dnf, pacman and zypper, see Linux package managers compared.

Everyday commands

CommandWhat it does
sudo apt updateDownload fresh package lists from every configured repository.
sudo apt upgradeUpgrade installed packages; may install new dependencies but never removes packages.
sudo apt full-upgradeUpgrade and also remove packages if that is needed to resolve changed dependencies (same as apt-get dist-upgrade).
sudo apt install pkg1 pkg2Install one or more packages and their dependencies.
sudo apt install ./file.debInstall a local .deb and pull its dependencies from the repositories (the ./ matters).
sudo apt install --reinstall pkgReinstall a package, restoring deleted or corrupted files.
sudo apt remove pkgRemove a package but keep its system-wide configuration files.
sudo apt purge pkgRemove a package and its configuration in /etc.
sudo apt autoremoveRemove dependencies nothing needs any more, including old kernels.
apt search keywordSearch names and descriptions.
apt show pkgVersion, size, dependencies and description.
apt list --installedList installed packages (pipe to grep).
apt list --upgradableShow what upgrade would change.
apt policy pkgInstalled and candidate versions and which repository each comes from.
sudo apt cleanDelete downloaded .deb files from /var/cache/apt/archives.

Add -y to skip the confirmation prompt, but only when you already know what the command will do. When you install, apt prints the full list of new, upgraded and removed packages: read the "will be REMOVED" line before you answer yes, because that is where a bad repository shows up first.

Finding which package provides a file or command

# which installed package owns a file
dpkg -S /usr/bin/dig
# which package (installed or not) contains a file
sudo apt install apt-file
sudo apt-file update
apt-file search bin/dig

Ubuntu also prints a suggestion when you type a missing command; if it doesn't, see bash: command not found.

Upgrades: upgrade vs full-upgrade

A plain apt upgrade is conservative: if a new version needs a package removed, apt keeps the old version back and tells you "The following packages have been kept back". That is normal and not an error. Ubuntu also holds some updates back on purpose while they roll out in phases to a percentage of machines.

# see why a package is held back
apt list --upgradable
apt policy <package>
# accept removals/new dependencies when you've read the list
sudo apt full-upgrade

Moving to a new release is a different operation. Use do-release-upgrade on Ubuntu (see how to upgrade Ubuntu) and edit the suite names then full-upgrade on Debian (see upgrading Debian 12 to 13). Never mix suites from different releases in your sources to "get a newer version" of one package; that is the most common way to end up with held broken packages.

Repositories and sources files

Current releases describe repositories in the deb822 format, one file per source:

  • Ubuntu 23.04 and later: /etc/apt/sources.list.d/ubuntu.sources
  • Debian 13: /etc/apt/sources.list.d/debian.sources on new installs, or the classic one-line /etc/apt/sources.list on upgraded systems
  • Linux Mint: /etc/apt/sources.list.d/official-package-repositories.list, managed by the Software Sources tool

Example debian.sources for Debian 13:

Types: deb
URIs: http://deb.debian.org/debian
Suites: trixie trixie-updates
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Types: deb
URIs: http://security.debian.org/debian-security
Suites: trixie-security
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

The equivalent one-line format is deb [signed-by=/path/key.gpg] URI suite component.... Both formats work; apt 3.x (Debian 13, Ubuntu 26.04) can convert old files with sudo apt modernize-sources, which keeps a backup of the originals.

Enabling Ubuntu components

Ubuntu splits its archive into main, restricted, universe and multiverse. Many "missing" packages live in universe:

sudo add-apt-repository universe
sudo apt update

If a package still can't be found, work through E: Unable to locate package.

Adding a third-party repository the right way

apt-key put every key into one global keyring, which meant any key could sign any repository. It is deprecated on Debian and removed in Ubuntu 26.04. The replacement is to store each key in its own file and tie it to exactly one repository with Signed-By.

# 1. create the keyring directory
sudo install -d -m 0755 /etc/apt/keyrings
# 2. download the vendor's key (check the URL against the vendor's own docs)
curl -fsSL https://repo.example.com/key.asc | sudo tee /etc/apt/keyrings/example.asc > /dev/null
# 3. add the source
sudo tee /etc/apt/sources.list.d/example.sources > /dev/null <<'EOF'
Types: deb
URIs: https://repo.example.com/apt
Suites: stable
Components: main
Signed-By: /etc/apt/keyrings/example.asc
EOF
# 4. refresh
sudo apt update

apt accepts ASCII-armoured keys if the file ends in .asc; binary keys need a .gpg extension (convert with gpg --dearmor). Real-world examples of this pattern are on the Docker installation and Firefox Mozilla APT repository pages.

Third-party repositories run as root

Packages from any repository you add install with root privileges and can replace system packages. Add only vendors you trust, prefer the vendor's documented instructions, and remove the .sources file and key when you stop using the software.

If apt update complains about NO_PUBKEY, the key file is missing or the Signed-By path is wrong: see fixing NO_PUBKEY errors. A "does not have a Release file" message usually means the repository doesn't support your release yet: see no Release file.

PPAs (Ubuntu and Mint)

sudo add-apt-repository ppa:owner/name
sudo apt update
# remove it again, then downgrade to official versions
sudo add-apt-repository --remove ppa:owner/name
sudo apt install ppa-purge
sudo ppa-purge ppa:owner/name

PPAs are built for Ubuntu releases only. Don't add them on Debian.

Holding, pinning and downgrading

# stop a package from being upgraded
sudo apt-mark hold <package>
apt-mark showhold
sudo apt-mark unhold <package>
# install a specific version
apt list -a <package>
sudo apt install <package>=<version>

To prefer one repository over another, create a file in /etc/apt/preferences.d/:

Package: *
Pin: origin repo.example.com
Pin-Priority: 900

Priorities above 1000 allow downgrades; 500 is the default for normal repositories; below 0 blocks a package entirely. apt policy shows the effective priorities, which is the fastest way to check a pin did what you meant.

Cleaning up disk space

sudo apt autoremove --purge
sudo apt clean
du -sh /var/cache/apt/archives
# list removed packages whose config files are still on disk
dpkg -l | awk '/^rc/ {print $2}'

Old kernels are removed by autoremove; Ubuntu keeps the running kernel plus one fallback. If /boot or / is already full and apt can't run, see No space left on device.

Fixing broken installs

Most apt breakage falls into a handful of patterns. Work through them in this order:

  1. Another process holds the lock (often the automatic updater). Wait a few minutes, then see Could not get lock /var/lib/dpkg/lock-frontend. Do not delete lock files while apt is running.
  2. An interrupted install: finish it.
    sudo dpkg --configure -a
    Details: dpkg was interrupted.
  3. Missing dependencies: let apt complete them.
    sudo apt --fix-broken install
  4. A package's install script fails: the real error is printed above "returned an error code (1)". See dpkg returned an error code (1).
  5. Conflicting repositories: check apt policy <package>, disable the third-party source, and run sudo apt full-upgrade.

apt keeps a log of everything it did in /var/log/apt/history.log, and dpkg logs every step in /var/log/dpkg.log. When something broke "after an update", those files tell you exactly which packages changed.

Distribution notes

  • Ubuntu: Snap is a separate package system. apt install firefox on Ubuntu installs a transitional package that pulls the snap. Unattended upgrades for security updates are on by default.
  • Debian: stable updates arrive through point releases and the -security suite. Backports (trixie-backports) offer newer versions of selected packages and must be requested explicitly with -t trixie-backports.
  • Linux Mint: the Update Manager adds safety levels on top of apt and Snap is disabled by default. The apt command on Mint is a wrapper script, but the usual subcommands behave the same.
  • Not on apt? Fedora uses dnf, Arch uses pacman, openSUSE uses zypper. The update-all-distros script shows the equivalent update commands.

Frequently asked questions

What is the difference between apt and apt-get?

apt is the newer front end meant for people at a terminal: progress bars, colour and sensible defaults. apt-get has a stable output format, so use it in scripts. Both use the same repositories and package database.

What is the difference between apt update and apt upgrade?

apt update only downloads the latest package lists from your repositories. apt upgrade then installs newer versions of the packages you already have. You need both, in that order.

Is apt autoremove safe?

Usually yes: it removes packages that were installed only as dependencies and are no longer needed. Read the list before confirming, and mark anything you want to keep with sudo apt-mark manual <package>.

What replaced apt-key?

Store each repository's key as a separate file (for example in /etc/apt/keyrings/) and reference it with signed-by or Signed-By: in that repository's source entry. apt-key is removed in Ubuntu 26.04.

How do I see which repository a package comes from?

Run apt policy <package>. It lists the installed version, the candidate version and every repository that offers the package, with its priority.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.