DB-유

Managing Packages with apt

· linux, ubuntu, apt

For years I knew four apt commands (update, upgrade, install, remove) and improvised the rest, until an upgrade went sideways and I didn't know how to preview it or find which package owned a file. apt can do a lot more: hold versions, show what an upgrade would change, clean up after itself.

Here are the commands and files I use on Ubuntu 16.04 and 18.04 (Debian 9 is the same), including apt vs apt-get and the repository config underneath. All you need is sudo.

apt or apt-get?

apt (since Ubuntu 16.04) is the friendlier front end for interactive use: progress bars, colour, and sensible defaults such as apt list --upgradable. apt-get and apt-cache are the stable, scriptable ones whose output format doesn't change. My rule: apt at the keyboard, apt-get in scripts and cron jobs. Script with apt and you'll get the warning WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Updating and upgrading

sudo apt update
apt list --upgradable
sudo apt upgrade

update refreshes the package lists from the sources; it installs nothing. upgrade installs newer versions of what is present but will never remove a package. full-upgrade (the apt name for apt-get dist-upgrade) is allowed to remove packages to resolve dependencies; use it when a kernel or a library transition needs it, and read the summary before pressing Y.

To see exactly what would change without doing it (I do this on anything production):

apt-get -s upgrade

If a reboot is needed afterwards, /var/run/reboot-required exists and /var/run/reboot-required.pkgs lists why.

Searching and finding file owners

apt search nginx
apt show nginx
apt-cache policy nginx
dpkg -L nginx-common | head
dpkg -S /etc/nginx/nginx.conf

apt-cache policy shows every version available from every source and which one would be installed, which is where you discover that a PPA is overriding the distribution package. dpkg -S answers "which package owns this file", and dpkg -L is its inverse. For a file that belongs to a package you have not installed, apt-file search from the apt-file package does the lookup against the archive index.

Versions, holds and pins

To install a particular version:

apt-cache madison docker-ce
sudo apt install docker-ce=5:19.03.5~3-0~ubuntu-bionic

To keep it there through future upgrades:

sudo apt-mark hold docker-ce
apt-mark showhold
sudo apt-mark unhold docker-ce

For finer control, an apt preferences file pins a package to a release or origin. This example prefers the nginx.org repository over Ubuntu's for the nginx package only:

Package: nginx
Pin: origin nginx.org
Pin-Priority: 900

Save it as /etc/apt/preferences.d/nginx and check with apt-cache policy nginx.

Adding a repository

Third-party repositories need a signing key and a source entry. I keep each in its own file so removing one later is a single rm:

curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
echo "deb http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update

For Launchpad PPAs, sudo add-apt-repository ppa:name/here does both steps. Avoid editing /etc/apt/sources.list itself; a botched line there breaks every apt update.

Removing and cleaning up

sudo apt remove nginx        # removes binaries, keeps config in /etc
sudo apt purge nginx         # removes config too
sudo apt autoremove          # drops dependencies nothing needs any more
sudo apt clean               # empties /var/cache/apt/archives

apt autoremove --purge combines the last two behaviours. Old kernels are the usual culprit for a full /boot; autoremove handles them on 18.04, but on 16.04 check dpkg -l 'linux-image-*' | grep ^ii and purge the ones you no longer boot.

Sanity checks

apt-get check
dpkg --audit
apt list --installed | wc -l

apt-get check verifies the dependency tree is consistent; dpkg --audit lists half-configured packages, which is what you are left with when an install was interrupted. Both should print nothing.

When apt complains

  • E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable). Another apt process is running, often unattended-upgrades shortly after boot. ps aux | grep -E 'apt|dpkg' shows it; wait for it rather than deleting the lock file.
  • E: Sub-process /usr/bin/dpkg returned an error code (1). A package's maintainer script failed. sudo dpkg --configure -a finishes any half-configured packages, and the lines above the error tell you which script and why.
  • The following packages have been kept back:. The upgrade would need to install or remove something else. sudo apt full-upgrade shows and resolves it; check the plan before accepting.
  • W: GPG error: ... NO_PUBKEY 3B4FE6ACC0B21F32. A repository's signing key is missing. Fetch it from the vendor's documentation and add it with apt-key add; do not just pull arbitrary keys from a keyserver by ID without checking the source.

Most "apt is broken" calls I get turn out to be an interrupted run or a stray sources line. Both take a minute to find with the commands above.