APT (Debian/Ubuntu)
APT (Advanced Package Tool) is the command-line package manager used by Debian, Ubuntu, and every distribution built on them (Linux Mint, Pop!_OS, Raspberry Pi OS, and more). Instead of hunting down installers on random websites, you tell APT what software you want, and it downloads a vetted .deb package from a trusted repository, pulls in everything that package needs to run, and installs it all in one transaction. This lesson covers everything from your first apt install to how APT resolves dependencies under the hood and how to avoid the mistakes that break systems.
Overview: How APT Works
Software on Debian-based systems is distributed as .deb files – archives that bundle compiled binaries, configuration files, and metadata such as the package’s name, version, and the other packages it depends on. The tool that actually unpacks a .deb file onto disk is called dpkg. dpkg is low-level: give it a single .deb file and it will install it, but it has no idea how to find that file on the internet or what to do if it needs five other packages first.
APT sits on top of dpkg and solves exactly that problem. It manages a list of repositories (servers hosting collections of packages), keeps a local index of every package available in those repositories, computes which packages satisfy a request’s dependencies, downloads the right .deb files, and hands them to dpkg in the correct order.
Repositories and the package index
Repositories are configured in /etc/apt/sources.list and any .list files under /etc/apt/sources.list.d/. Each line names a URL, a distribution codename (like jammy for Ubuntu 22.04), and one or more components (main, universe, restricted, multiverse on Ubuntu). Running sudo apt update downloads the current package index from every configured repository and caches it under /var/lib/apt/lists/. This step does not install or upgrade a single package – it only refreshes APT’s knowledge of what versions are currently available. If you skip it, APT may try to fetch a package version that a mirror no longer serves, and you will see errors like 404 Not Found.
Dependency resolution
Every .deb package declares relationships to other packages: Depends (must be installed), Recommends (installed by default but skippable), Suggests (optional), and Conflicts (cannot coexist). When you run apt install, APT builds a dependency graph across the entire package index, and computes the smallest set of additional packages that satisfies every constraint. This is why installing one package can pull in a dozen others – and why APT shows you a summary of everything it’s about to change before it touches your system.
apt vs apt-get vs apt-cache
apt is the modern, user-friendly command introduced in 2014 that merges functionality previously split across apt-get (install/remove/upgrade) and apt-cache (search/inspect). It adds a progress bar and color output and is what you should type interactively. The older apt-get and apt-cache commands still exist and are preferred inside scripts, because APT’s own documentation warns that apt‘s command-line interface and output format may change between versions – apt-get‘s output is stable and scriptable.
Why sudo
Installing, removing, or upgrading packages writes to system directories like /usr, /etc, and /var, all of which are owned by root. APT itself needs to acquire a lock file before it can safely write to its package database, and only root (or a user invoking sudo) can create that lock, which is why every mutating APT command in this lesson is prefixed with sudo.
Syntax
The general form of an APT command is:
apt COMMAND [options] [package...]
| Command | What it does |
|---|---|
update |
Refreshes the local package index from configured repositories (no installs/upgrades) |
upgrade |
Installs newer versions of already-installed packages; never removes a package or installs a new one |
full-upgrade |
Like upgrade, but will add or remove packages if needed to complete an upgrade |
install <pkg> |
Installs a package and its dependencies |
remove <pkg> |
Uninstalls a package’s programs but keeps its configuration files |
purge <pkg> |
Uninstalls a package and deletes its configuration files too |
autoremove |
Removes packages that were installed as dependencies and are no longer needed |
search <term> |
Searches package names and descriptions in the local index |
show <pkg> |
Prints detailed metadata for a package (version, dependencies, size, description) |
list --installed |
Lists every package currently installed |
list --upgradable |
Lists installed packages that have a newer version available |
On RHEL, Fedora, and other Red Hat-family distributions, the equivalent tool is dnf (or the older yum) – the commands differ (dnf install, dnf remove, dnf search), but the concept of a repository-backed, dependency-resolving package manager is the same.
Examples
Example 1: Refresh the index and check what can be upgraded
sudo apt update
apt list --upgradable
Output:
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Fetched 238 kB in 1s (238 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
5 packages can be upgraded. Run 'apt list --upgradable' to see them.
Listing...
curl/jammy-updates 7.81.0-1ubuntu1.15 amd64 [upgradable from: 7.81.0-1ubuntu1.14]
openssl/jammy-updates 3.0.2-0ubuntu1.14 amd64 [upgradable from: 3.0.2-0ubuntu1.13]
apt update contacted each repository, downloaded the latest index files, and reported that five packages have newer versions available. apt list --upgradable then reads that local index (no network access needed) and prints exactly which packages and versions are involved. Nothing has been installed yet – the system is unchanged until you run upgrade.
Example 2: Install a package
sudo apt install curl
Output:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
curl
0 upgraded, 1 newly installed, 0 to remove and 4 not upgraded.
Need to get 226 kB of archives.
After this operation, 615 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 curl amd64 7.81.0-1ubuntu1.15 [226 kB]
Fetched 226 kB in 0s (1,024 kB/s)
Selecting previously unselected package curl.
(Reading database ... 184291 files and directories currently installed.)
Preparing to unpack .../curl_7.81.0-1ubuntu1.15_amd64.deb ...
Unpacking curl (7.81.0-1ubuntu1.15) ...
Setting up curl (7.81.0-1ubuntu1.15) ...
APT looked up curl in its index, found it had no unmet dependencies beyond what’s already installed, downloaded the .deb to /var/cache/apt/archives/, and handed it to dpkg, which unpacked the files and ran the package’s setup step. The summary line (0 upgraded, 1 newly installed...) is worth reading every time – it’s your chance to notice if a command is about to remove something you didn’t expect.
Example 3: Removing a package properly – remove vs purge
sudo apt purge nginx
sudo apt autoremove
Output:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
nginx*
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 3,481 kB disk space will be freed.
(Reading database ... 184320 files and directories currently installed.)
Removing nginx (1.18.0-6ubuntu14.4) ...
Purging configuration files for nginx (1.18.0-6ubuntu14.4) ...
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
apt remove nginx would have uninstalled the nginx binaries and stopped its service, but left files like /etc/nginx/nginx.conf on disk in case you reinstall later. apt purge goes further and deletes those configuration files too – use it when you want a completely clean uninstall. autoremove then cleans up any packages that were pulled in only as a dependency of nginx and are no longer needed by anything else.
Example 4: Researching a package before installing it
apt search "text editor"
apt show vim
Output:
Sorting... Done
Full Text Search... Done
vim/jammy-updates 2:8.2.3995-1ubuntu2.15 amd64
Vi IMproved - enhanced vi editor
nano/jammy 6.2-1 amd64
small, friendly text editor inspired by Pico
Package: vim
Version: 2:8.2.3995-1ubuntu2.15
Depends: vim-common (= 2:8.2.3995-1ubuntu2.15), vim-runtime (= 2:8.2.3995-1ubuntu2.15), libc6 (>= 2.34), libgpm2, libtinfo6 (>= 6)
Download-Size: 1,268 kB
Description: Vi IMproved - enhanced vi editor
apt search scans package names and short descriptions in the local index for a matching term – no installation, no network round trip. apt show prints full metadata for a specific package, including its exact dependency list and download size, so you know what you’re agreeing to before running install.
How It Works, Step by Step
When you run sudo apt install nginx, this is roughly what happens:
- APT reads the local package index (built by the last
apt update) to findnginxand every package it depends on. - It computes the full set of packages that need to be installed, upgraded, or (in rare conflict cases) removed to satisfy those dependencies.
- It prints a summary of that plan and asks for confirmation (unless you passed
-y). - It downloads each required
.debfile from the repository into/var/cache/apt/archives/. - It hands the downloaded files to
dpkgin dependency order – a package is never unpacked before the packages it depends on. dpkgunpacks each package’s files onto the filesystem, then runs its post-install script (fornginx, this typically registers and can start asystemdservice).
Common Mistakes
Mistake 1: Forgetting sudo
apt install curl
Output:
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
APT needs to write to the package database, which is owned by root. Run mutating commands with sudo:
sudo apt install curl
Mistake 2: Assuming remove fully uninstalls a package
sudo apt remove nginx
dpkg -l | grep nginx
Output:
rc nginx 1.18.0-6ubuntu14.4 amd64 small, powerful, scalable web/proxy server
The leading rc means “removed, config files remain” – /etc/nginx/ is still on disk. If you wanted a clean slate, purge instead:
sudo apt purge nginx
Mistake 3: Relying on apt’s output inside scripts
apt list --installed
Output:
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Listing...
adduser/jammy,now 3.118ubuntu5 all [installed]
apt/jammy,now 2.4.13 amd64 [installed]
APT itself warns you here. For anything you plan to parse or run unattended (cron jobs, provisioning scripts, CI), use apt-get and dpkg-query instead, whose output format is guaranteed stable:
dpkg-query -W -f='${binary:Package} ${Version}\n'
Best Practices
- Run
sudo apt updatebefore installing or upgrading anything on a system you haven’t touched recently, so you’re working from a current package index. - Review the summary line APT prints before confirming – especially watch for packages listed “to remove” that you didn’t expect.
- Use
apt purgeinstead ofapt removewhen you want configuration files gone too, and follow up withapt autoremoveto clean up orphaned dependencies. - Prefer
apt-getandapt-cacheoveraptin shell scripts and cron jobs, since their output is stable and documented. - Use
apt show <package>to inspect dependencies and download size before installing something unfamiliar. - Only add third-party repositories (via
/etc/apt/sources.list.d/) from sources you trust – anything listed there can run code as root during package installation. - If a previous APT operation was interrupted and packages are left half-configured, run
sudo apt --fix-broken installbefore trying anything else.
Practice Exercises
- On a Debian or Ubuntu machine (or a container), run
sudo apt updatefollowed byapt list --upgradable. How many packages are upgradable, and which one has the largest download size according toapt show? - Install the
httpiepackage, use it to make a request, then remove it withapt removeand check withdpkg -l | grep httpiewhether configuration files remain. Purge it and check again. - Before installing
docker.io, runapt show docker.ioto see its dependency list. Which packages would be pulled in that you didn’t expect?
Summary
- APT is a high-level package manager that wraps
dpkg, adding repository management, dependency resolution, and downloads. apt updaterefreshes the local package index only – it never installs or upgrades anything by itself.apt upgradeupdates existing packages without adding or removing any;apt full-upgradewill add or remove packages if that’s required.apt removekeeps configuration files;apt purgedeletes them too.- Mutating commands need
sudobecause they write to root-owned system directories and the package database lock. - Use
aptinteractively; useapt-get/apt-cachein scripts, since APT’s own docs warn thatapt‘s interface can change. - On RHEL/Fedora,
dnf(oryum) plays the same role as APT.
