The apt Package Manager: A Complete Guide for Ubuntu and Debian
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.listand files in/etc/apt/sources.list.d/. - Package lists — the downloaded index of what each repository offers, in
/var/lib/apt/lists/.apt updaterefreshes 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
| Command | What it does |
|---|---|
sudo apt update | Download fresh package lists from every configured repository. |
sudo apt upgrade | Upgrade installed packages; may install new dependencies but never removes packages. |
sudo apt full-upgrade | Upgrade and also remove packages if that is needed to resolve changed dependencies (same as apt-get dist-upgrade). |
sudo apt install pkg1 pkg2 | Install one or more packages and their dependencies. |
sudo apt install ./file.deb | Install a local .deb and pull its dependencies from the repositories (the ./ matters). |
sudo apt install --reinstall pkg | Reinstall a package, restoring deleted or corrupted files. |
sudo apt remove pkg | Remove a package but keep its system-wide configuration files. |
sudo apt purge pkg | Remove a package and its configuration in /etc. |
sudo apt autoremove | Remove dependencies nothing needs any more, including old kernels. |
apt search keyword | Search names and descriptions. |
apt show pkg | Version, size, dependencies and description. |
apt list --installed | List installed packages (pipe to grep). |
apt list --upgradable | Show what upgrade would change. |
apt policy pkg | Installed and candidate versions and which repository each comes from. |
sudo apt clean | Delete 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.sourceson new installs, or the classic one-line/etc/apt/sources.liston 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.
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:
- 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.
- An interrupted install: finish it.
Details: dpkg was interrupted.sudo dpkg --configure -a - Missing dependencies: let apt complete them.
sudo apt --fix-broken install - A package's install script fails: the real error is printed above "returned an error code (1)". See dpkg returned an error code (1).
- Conflicting repositories: check
apt policy <package>, disable the third-party source, and runsudo 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 firefoxon 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
-securitysuite. 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
aptcommand on Mint is a wrapper script, but the usual subcommands behave the same. - Not on apt? Fedora uses
dnf, Arch usespacman, openSUSE useszypper. 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.