Linux distributions organise system files on disk into collections called packages. Packages can be comprised of binaries (e.g.
grep), shared libraries, configuration files (e.g.
/etc/passwd) and directories.
Each package has some associated metadata, including a version number, which is committed to a database when the package is installed. This allows us to query the version of a package, the files installed by each package, find the package that owns a given file and even identify changes to a package's default configuration. To allow reuse, packages can have dependencies on other packages.
Distribution of packages takes place via repositories which contain copies of these packages and indexes describing their names and versions. By comparing the version numbers we have locally with those in the repository index we can identify packages in need of updates.
When we refer to APT we're usually referring to two things:
dpkg, the Debian PacKaGe manager, which manages
*.debpackages and their installed files on-disk. You can think of this as the low level tool that does most of the heavy lifting; you won't directly interact with it often.
- APT and frontends like
aptititudewhich allow us to fetch these packages from repositories.
Refreshing repository metadata
Data about the packages available in each repository is cached locally to improve query time. This data needs to be periodically refreshed:
$ sudo apt update Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease Get:2 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB] Get:3 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB] Get:4 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB] [snip] Fetched 18.0 MB in 6s (3102 kB/s) Reading package lists... Done Building dependency tree Reading state information... Done 126 packages can be upgraded. Run 'apt list --upgradable' to see them.
Show information about an installed package
$ apt show <package>
$ apt show bash Package: bash Version: 4.4.18-2ubuntu1.2 Priority: required Essential: yes Section: shells Origin: Ubuntu Maintainer: Ubuntu Developers <email@example.com> Original-Maintainer: Matthias Klose <firstname.lastname@example.org> Bugs: https://bugs.launchpad.net/ubuntu/+filebug Installed-Size: 1626 kB Pre-Depends: libc6 (>= 2.15), libtinfo5 (>= 6) Depends: base-files (>= 2.1.12), debianutils (>= 2.15) Recommends: bash-completion (>= 20060301-0) Suggests: bash-doc Conflicts: bash-completion (<< 20060301-0) Replaces: bash-completion (<< 20060301-0), bash-doc (<= 2.05-1) Homepage: http://tiswww.case.edu/php/chet/bash/bashtop.html Task: minimal Supported: 5y Download-Size: 614 kB APT-Sources: http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages Description: GNU Bourne Again SHell Bash is an sh-compatible command language interpreter that executes commands read from the standard input or from a file. Bash also incorporates useful features from the Korn and C shells (ksh and csh). . Bash is ultimately intended to be a conformant implementation of the IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2). . The Programmable Completion Code, by Ian Macdonald, is now found in the bash-completion package. N: There are 2 additional records. Please use the '-a' switch to see them.
List available updates
Be sure to refresh the repository metadata ahead of listing updates to ensure the latest updates are available.
$ apt list --upgradable Listing... Done apport/bionic-updates,bionic-security 2.20.9-0ubuntu7.9 all [upgradable from: 2.20.9-0ubuntu7.6] apt/bionic-updates 1.6.12 amd64 [upgradable from: 1.6.10] apt-utils/bionic-updates 1.6.12 amd64 [upgradable from: 1.6.10] base-files/bionic-updates 10.1ubuntu2.7 amd64 [upgradable from: 10.1ubuntu2.4] [snip]
Updating packages is referred to as "upgrading" in APT. There are two modes:
upgradewill only replace installed packages with newer versions.
dist-upgradewill perform all of the operations an
upgradewill do, additionally installing additional packages and removing obsolete packages whose dependencies cannot be met. This will upgrade any packages that
upgradesays have been "kept back".
The only difference between the two in normal operation is that Linux kernel updates will not be installed during an
upgrade, but will with a
$ sudo apt upgrade lcarrier@HLC002155:~$ sudo apt-get upgrade apt Reading package lists... Done Building dependency tree Reading state information... Done Calculating upgrade... Done The following package was automatically installed and is no longer required: libfreetype6 Use 'sudo apt autoremove' to remove it. The following packages have been kept back: ubuntu-wsl wslu The following packages will be upgraded: apport apt apt-utils base-files bash bind9-host bsdutils bzip2 cloud-init curl dbus distro-info-data dmeventd dmsetup dnsutils dpkg e2fsprogs fdisk file friendly-recovery gcc-8-base grep initramfs-tools initramfs-tools-bin initramfs-tools-core iputils-ping iputils-tracepath landscape-common [snip] 124 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. Need to get 53.1 MB of archives. After this operation, 1159 kB disk space will be freed. Do you want to continue? [Y/n] Get:1 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 base-files amd64 10.1ubuntu2.7 [60.3 kB] Get:2 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 bash amd64 4.4.18-2ubuntu1.2 [614 kB] Get:3 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 bsdutils amd64 1:2.31.1-0.4ubuntu3.4 [60.3 kB] Get:4 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 dpkg amd64 18.104.22.168ubuntu2.3 [1136 kB] [snip] Fetched 75.3 MB in 15s (4911 kB/s) Extracting templates from packages: 100% Preconfiguring packages ... (Reading database ... 28645 files and directories currently installed.) Preparing to unpack .../base-files_10.1ubuntu2.7_amd64.deb ... Unpacking base-files (10.1ubuntu2.7) over (10.1ubuntu2.4) ... Setting up base-files (10.1ubuntu2.7) ... Installing new version of config file /etc/issue ... Installing new version of config file /etc/issue.net ... Installing new version of config file /etc/lsb-release ... Installing new version of config file /etc/update-motd.d/50-motd-news ... (Reading database ... 28645 files and directories currently installed.) Preparing to unpack .../bash_4.4.18-2ubuntu1.2_amd64.deb ... Unpacking bash (4.4.18-2ubuntu1.2) over (4.4.18-2ubuntu1.1) ... Setting up bash (4.4.18-2ubuntu1.2) ... update-alternatives: using /usr/share/man/man7/bash-builtins.7.gz to provide /usr/share/man/man7/builtins.7.gz (builtins.7.gz) in auto mode (Reading database ... 28645 files and directories currently installed.) Preparing to unpack .../bsdutils_1%3a2.31.1-0.4ubuntu3.4_amd64.deb ... Unpacking bsdutils (1:2.31.1-0.4ubuntu3.4) over (1:2.31.1-0.4ubuntu3.3) ... Setting up bsdutils (1:2.31.1-0.4ubuntu3.4) ... (Reading database ... 28645 files and directories currently installed.) Preparing to unpack .../dpkg_22.214.171.124ubuntu2.3_amd64.deb ... Unpacking dpkg (126.96.36.199ubuntu2.3) over (188.8.131.52ubuntu2.1) ... Setting up dpkg (184.108.40.206ubuntu2.3) ... [snip] Selecting previously unselected package libogg0:amd64. Preparing to unpack .../09-libogg0_1.3.2-1_amd64.deb ... Unpacking libogg0:amd64 (1.3.2-1) ... Selecting previously unselected package x11-common. Preparing to unpack .../10-x11-common_1%3a7.7+19ubuntu7.1_all.deb ... dpkg-query: no packages found matching nux-tools Unpacking x11-common (1:7.7+19ubuntu7.1) ... Selecting previously unselected package libice6:amd64. Preparing to unpack .../11-libice6_2%3a1.0.9-2_amd64.deb ... Unpacking libice6:amd64 (2:1.0.9-2) ... Selecting previously unselected package libsm6:amd64. Preparing to unpack .../12-libsm6_2%3a1.2.2-1_amd64.deb ... Unpacking libsm6:amd64 (2:1.2.2-1) ... [snip] Setting up iputils-ping (3:20161105-1ubuntu3) ... Setting up libxi6:amd64 (2:1.7.9-1) ... Setting up libxcb-present0:amd64 (1.13-2~ubuntu18.04) ... Setting up libglvnd0:amd64 (1.0.0-2ubuntu2.3) ... [snip] Processing triggers for libc-bin (2.27-3ubuntu1) ... Processing triggers for systemd (237-3ubuntu10.31) ... Processing triggers for man-db (2.8.3-2ubuntu0.1) ... Processing triggers for rsyslog (8.32.0-1ubuntu4) ... invoke-rc.d: could not determine current runlevel [snip]
$ sudo apt dist-upgrade Reading package lists... Done Building dependency tree Reading state information... Done All packages are up to date.
If you want to upgrade specific packages, specify them by name:
sudo apt upgrade <package> [package] [package]
Removing outdated packages
Some packages (most notable the Linux kernel) are versioned in a way that allows multiple versions to be installed alongside one another, where the other is no longer used.
This is how we avoid filling
/boot with older kernels.
$ sudo apt autoremove Building dependency tree Reading state information... Done The following packages will be REMOVED: linux-azure-cloud-tools-5.0.0-1020 linux-azure-cloud-tools-5.0.0-1022 linux-azure-headers-5.0.0-1020 linux-azure-headers-5.0.0-1022 linux-azure-tools-5.0.0-1020 linux-azure-tools-5.0.0-1022 0 upgraded, 0 newly installed, 6 to remove and 16 not upgraded. After this operation, 187 MB disk space will be freed. Do you want to continue? [Y/n] (Reading database ... 143612 files and directories currently installed.) Removing linux-azure-cloud-tools-5.0.0-1020 (5.0.0-1020.21~18.04.1) ... Removing linux-azure-cloud-tools-5.0.0-1022 (5.0.0-1022.23~18.04.1) ... Removing linux-azure-headers-5.0.0-1020 (5.0.0-1020.21~18.04.1) ... Removing linux-azure-headers-5.0.0-1022 (5.0.0-1022.23~18.04.1) ... [snip]
Cleaning cached package files
Downloaded package (
*.deb) files are cached in
/var/lib/apt/cache to speed up future reinstallation operations.
In disk-constrained environments (e.g. when building Docker images or VM templates) you'll want to clean these directories to free up space. It's usually unnecessary in day-to-day administration, though.
$ sudo apt autoclean Reading package lists... Done Building dependency tree Reading state information... Done
Repositories are defined in two locations which are given equal precedence:
/etc/apt/sources.listdefines the system repositories. We can add additional entires to this file but it's considered better practice to use drop-ins.
/etc/apt/sources.list.d/*.listcontains drop-in definitions.
Repository definitions are done in a single line, e.g.:
deb https://apt.example.com/debian bionic main
deb [arch=amd64] https://apt.example.com/debian xenial main
For more details on formatting see
By default APT will upgrade all packages to their latest versions in any enabled repository during upgrade operations. This isn't always desirable:
- Sometimes a service is expected to be at the same version across a cluster of servers.
- We might want to use an older version of a package from a vendor's repository rather than the latest one available in the distribution.
"Pinning" is the act of limiting this behaviour to keep a package at a specific version or source repository.
APT frontends will read files placed in
/etc/apt/preferences.d formatted as follows:
Package: my-package Pin: version 1.2.3 Pin-Priority: 500
You can see the current policy for all repositories and pinned packages as follows:
$ apt policy Package files: 100 /var/lib/dpkg/status release a=now 500 http://security.ubuntu.com/ubuntu bionic-security/multiverse amd64 Packages release v=18.04,o=Ubuntu,a=bionic-security,n=bionic,l=Ubuntu,c=multiverse,b=amd64 origin security.ubuntu.com 500 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages release v=18.04,o=Ubuntu,a=bionic-security,n=bionic,l=Ubuntu,c=universe,b=amd64 origin security.ubuntu.com 500 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages release v=18.04,o=Ubuntu,a=bionic-security,n=bionic,l=Ubuntu,c=restricted,b=amd64 origin security.ubuntu.com [snip] Pinned packages: my-package -> 1.2.3 with priority 500
And for a specific package -- in this case for
my-package which is pinned at version 1.2.3 when 1.2.4 is available in a third-party repository:
$ apt policy my-package my-package: Installed: 1.2.3 Candidate: 1.2.3 Version table: 1.2.4 500 500 https://apt.example.com/debian/ bionic/main amd64 Packages *** 1.2.3 900 100 /var/lib/dpkg/status