Sign in
← Linux: administration
10 min · easy · Lesson 3 of 10

Package managers: apt, dnf, apk

How to install and update software across distros: repositories, update vs upgrade, and the difference between apt, dnf, and apk.

Installing software by downloading a binary and unpacking it by hand is a bad idea: nobody tracks dependencies, updates or removal. A package manager does this for you. It knows which libraries a program needs, installs them, updates them and can remove them cleanly.

Concepts

Package: an archive with a program, its files and a description. The description says which other packages it depends on and what to do after install.

Repository: a server with packages that the system trusts. The package manager downloads packages from there and checks their signatures. Repository addresses live in settings: on Ubuntu 24.04 that's /etc/apt/sources.list.d/ubuntu.sources, on Alpine /etc/apk/repositories.

Index (package list): a local copy of the repository's catalog, that is, which packages and which versions are there. The package manager searches the index, not the server.

Which package manager is on a machine depends on the distro. This is exactly the kind of detail where distros differ. You can find out the distro like this:

cat /etc/os-release
PRETTY_NAME="Ubuntu 24.04.5 LTS"
NAME="Ubuntu"
...
ID=ubuntu
ID_LIKE=debian
...
FamilyPackage managerPackage format
Debian, Ubuntuapt, apt-get.deb
RHEL, Rocky, AlmaLinux, Fedoradnf (formerly yum).rpm
Alpineapk.apk

A package manager from another family simply won't be found. On Alpine, apt-get gives sh: apt-get: not found.

apt: Debian and Ubuntu

apt update              # refresh the index from the repositories
apt install nginx       # install a package
apt upgrade             # upgrade installed packages
apt remove nginx        # remove a package
apt search nginx        # search for a package by name and description

People often mix up update and upgrade. apt update only refreshes the local index: which packages and which versions are in the repositories. apt upgrade installs the actual updates. Run apt update before installing, otherwise apt looks for the package in a stale index.

The index can even be completely empty. That's the case in the Docker image ubuntu:24.04: there, /var/lib/apt/lists/ is empty, and an install without update fails:

apt-get install -y tree
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package tree

The package exists. After apt-get update, the same command works.

A few more commands you need every day:

apt-cache policy tree   # which version is installed and which install will pick
dpkg -l tree            # is the package installed (ii at the start of the line means "installed")
apt list --upgradable   # what can be upgraded
apt autoremove          # remove dependencies nobody needs anymore

apt-cache policy shows a Candidate: line: the version that install will put in:

tree:
  Installed: (none)
  Candidate: 2.1.1-2ubuntu3.24.04.2
  Version table:
     2.1.1-2ubuntu3.24.04.2 500
        500 http://ports.ubuntu.com/ubuntu-ports noble-updates/universe arm64 Packages
...

remove only removes the package itself. Libraries that apt installed along with it stay behind, and apt says so directly. Here's what apt-get remove -y jq prints:

The following packages were automatically installed and are no longer required:
  libjq1 libonig5
Use 'apt autoremove' to remove them.

apt remove also leaves the package's configs in /etc. To remove those too, there's apt purge.

dnf: RHEL, Rocky, AlmaLinux, Fedora

dnf install nginx
dnf upgrade
dnf remove nginx
dnf search nginx

A separate "refresh the index" step usually isn't needed here: dnf downloads fresh repository metadata itself if the saved copy is stale. By default, metadata is considered stale after 48 hours (metadata_expire in /etc/dnf/dnf.conf). You can force a refresh with dnf makecache. The old name for the command is yum. On RHEL 8 and newer, yum runs on top of dnf and accepts the same commands.

apk: Alpine

apk add nginx           # install
apk del nginx           # remove, along with dependencies nobody needs
apk update              # refresh the index
apk upgrade             # upgrade packages
apk search nginx        # search for a package
apk info -e nginx       # is the package installed (prints the name if it is)

Alpine is minimalist, apk is fast. That's why Alpine is a common base for small Docker images. If there's no index, apk add downloads it itself and saves it to /var/cache/apk (about 2 MB). apk add --no-cache installs the package and doesn't save the index.

In Dockerfile

Inside images there's a catch: you clean up the index after install, so the image doesn't bloat. Otherwise the downloaded package lists stay in the layer forever. In ubuntu:24.04, after apt-get update they take up about 56 MB.

# Debian/Ubuntu
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

# Alpine
RUN apk add --no-cache curl

There are three rules here, and each one closes off its own problem.

Scripts and Dockerfiles use apt-get, not apt. apt's output is meant for people and can change between versions, which it warns about itself when run outside a terminal:

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Packages and systemd

Many service packages bring their own unit file. On Debian and Ubuntu, installing such a package immediately enables and starts the service: after apt-get install nginx, a link to nginx.service appears in /etc/systemd/system/multi-user.target.wants/. On Fedora and RHEL, by default it's the opposite: the unit file is installed, but you need to enable the service yourself with systemctl enable --now.

Common mistakes

What you'll need for the tasks

Done reading?

Mark the lesson as read to move your track progress forward.

Go through it with an AI agent

The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.

Get access for $49

Tell the agent: use MCP izi, give me lesson linux-admin-03-package-mgmt