Managing Packages with 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, oftenunattended-upgradesshortly 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 -afinishes 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-upgradeshows 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 withapt-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.