By Brennen Bearnes and Vinayak Baranwal
Most modern Unix-like operating systems offer a centralized mechanism for finding and installing software. Software is usually distributed in the form of packages, kept in repositories. Working with packages is known as package management. Packages provide the core components of an operating system, along with shared libraries, applications, services, and documentation.
Use your system’s package manager to find, install, and upgrade software from vetted repositories. On Debian and Ubuntu you use apt and dpkg; on Rocky Linux, Fedora, and RHEL you use dnf (or yum on older systems); on FreeBSD you use pkg. This guide is a quick reference for the same operations across these tools so you can translate commands between systems.
policy and depends./usr/share/keyrings/ or signed-by= for apt; rpm --import for dnf/yum.Package files are archives that contain compiled applications, resources, and installation scripts. Metadata includes dependencies, the list of other packages required to install and run them. Formats and tools vary by platform:
| Platform | Package format | Primary tools |
|---|---|---|
| Debian / Ubuntu | .deb |
apt, dpkg |
| Rocky / Fedora / RHEL | .rpm |
dnf (or yum on legacy systems) |
| FreeBSD | .txz (binary), Ports (source) |
pkg, Ports Collection |
On Debian-derived systems (Ubuntu, Linux Mint, Raspbian), apt is the front end for most operations: searching repositories, installing packages and dependencies, and managing upgrades. The lower-level dpkg installs individual .deb files and is sometimes used directly. See the Ubuntu and Debian package management essentials tutorial for full coverage.
On Rocky Linux, Fedora, and RHEL, dnf is the default package manager. It replaced yum and keeps a compatible command set. If you manage older RHEL or CentOS systems, you may still use yum; see Understanding yum (RHEL and CentOS Legacy) below.
On FreeBSD, pkg manages binary packages (typically .txz). FreeBSD also provides the Ports Collection, a tree of Makefiles to build software from source. Use pkg when a binary exists; use Ports when you need a pre-compiled package that is unavailable or when you must change compile-time options. The FreeBSD Handbook documents both.
On Ubuntu and other Debian-based systems you have apt, apt-get, and apt-cache. Use apt for interactive use and most day-to-day tasks.
apt is the unified command that wraps common operations. It is the recommended interface for update, upgrade, install, remove, search, and show. It gives clearer output and is stable for scripts in current releases. See the Ubuntu manpage for apt for the full list.
Use apt-get when you need behavior that only it provides, or when writing scripts that must run on older or minimal systems. Examples: apt-get install -y for non-interactive installs, apt-get dist-upgrade for resolving dependency changes that may add or remove packages, and apt-get autoremove for removing orphaned dependencies.
Use apt-cache for low-level queries that apt does not expose in the same way. Examples: apt-cache policy package to see which version would be installed and from which repository, and apt-cache depends package to list dependencies. For search and show, apt search and apt show are equivalent to apt-cache search and apt-cache show.
To see which version would be installed and from which repository:
apt-cache policy curl
curl:
Installed: 7.81.0-1ubuntu1.13
Candidate: 7.81.0-1ubuntu1.15
Version table:
7.81.0-1ubuntu1.15 500
500 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
*** 7.81.0-1ubuntu1.13 100
100 /var/lib/dpkg/status
apt-cache depends curl
curl
Depends: libcurl4
Depends: zlib1g
Suggests: libcurl4-gnutls-dev
To check which installed packages have pending upgrades after updating the index:
apt update && apt list --upgradable
The output has two parts. First, apt update refreshes the index (shown below). Then apt list --upgradable prints the list of installed packages that have a newer version available:
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease ...
...
Listing Done
curl/jammy-updates 7.81.0-1ubuntu1.15 amd64 [upgradable from: 7.81.0-1ubuntu1.13]
libcurl4/jammy-updates 7.81.0-1ubuntu1.15 amd64 [upgradable from: 7.81.0-1ubuntu1.13]
Repositories define where your package manager fetches software. Configure them correctly so you get the right packages and security updates.
On Debian and Ubuntu, repository configuration lives in /etc/apt/sources.list and in files under /etc/apt/sources.list.d/. Each line specifies a type (e.g. deb for binaries, deb-src for source), a URL, the release (e.g. jammy), and component names (e.g. main universe). Edit these files only with care; a bad line can break apt update.
To add a repository from the command line, use add-apt-repository (from the software-properties-common package). It appends the correct line and can optionally run apt update.
sudo add-apt-repository ppa:owner/ppa-name
sudo apt update
Warning: Adding third-party PPAs or repositories can install unvetted packages. Prefer official or well-known sources and verify GPG keys. See Package Verification and Security.
To add a third-party repository manually using the modern signed-by format, create a new file under /etc/apt/sources.list.d/ rather than editing sources.list directly. For example, to add the official Nginx mainline repo:
curl -fsSL https://nginx.org/keys/nginx_signing.key \
| sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
Then create the repo file:
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://nginx.org/packages/mainline/ubuntu jammy nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
Each file in sources.list.d/ is a self-contained repo definition. Keeping third-party repos in separate files makes them easier to disable or remove without touching sources.list.
On dnf-based systems, repository configs are under /etc/yum.repos.d/. Add a new repo with dnf config-manager (from the dnf-plugins-core package):
sudo dnf config-manager --add-repo https://example.com/repo/repo-name.repo
Enable or disable an existing repo by name:
sudo dnf config-manager --set-enabled repo-id
sudo dnf config-manager --set-disabled repo-id
Repository IDs are defined in the .repo files in /etc/yum.repos.d/. The DNF documentation covers repository configuration in detail.
On FreeBSD, pkg reads its repository configuration from /etc/pkg/FreeBSD.conf for the default official repository, and from files under /usr/local/etc/pkg/repos/ for custom or additional repositories. Do not edit FreeBSD.conf directly; override it by creating a file in /usr/local/etc/pkg/repos/.
To add a custom repository, create a .conf file in that directory:
sudo mkdir -p /usr/local/etc/pkg/repos
sudo vi /usr/local/etc/pkg/repos/repo-name.conf
The file format follows this structure:
repo-name: {
url: "https://example.com/packages/${ABI}",
mirror_type: "srv",
signature_type: "fingerprints",
fingerprints: "/usr/share/fingerprints/repo-name",
enabled: yes
}
After adding the file, update the package index to confirm pkg can reach the new repository:
sudo pkg update
Updating repo-name repository catalogue...
Fetching meta.conf: 100%
Fetching packagesite.pkg: 100%
Processing entries: 100%
repo-name repository update completed.
To disable the default FreeBSD repository without deleting it, create an override file:
sudo vi /usr/local/etc/pkg/repos/FreeBSD.conf
Add this content:
FreeBSD: {
enabled: no
}
Warning: Disabling the official FreeBSD repository means pkg will only install from your configured custom sources. Ensure your custom repository is complete and trusted before disabling the default.
The FreeBSD Handbook section on pkg covers repository configuration and signature verification in detail.
Update the local index of available packages before installing or upgrading. dnf may refresh metadata automatically for some operations, but you can always check for updates explicitly.
| System | Command |
|---|---|
| Debian / Ubuntu | sudo apt update |
| Rocky / Fedora / RHEL | dnf check-update |
| FreeBSD (packages) | sudo pkg update |
| FreeBSD (Ports) | See FreeBSD Ports vs pkg |
Example on Ubuntu:
sudo apt update
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Hit:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Reading package lists... Done
Building dependency tree... Done
On dnf-based systems, dnf check-update exits 0 when there are no updates and 100 when updates are available, which is useful in scripts.
On RHEL and CentOS 7 and earlier, yum is the only package manager available. On RHEL 8, Fedora 22, and later releases, dnf replaced yum as the default. On most current systems that ship dnf, the yum binary is a symlink or compatibility shim pointing to dnf, so yum commands still work but dnf is what runs.
Use yum explicitly only when:
On any system where dnf is available, prefer dnf. The command set is compatible for common operations, but dnf adds transaction history, better dependency resolution, and modular repository support that yum does not have.
If you are unsure which is running, check:
which yum && yum --version
/usr/bin/yum
4.14.0
Installed: dnf-0:4.14.0-1.el9.noarch at ...
If the version output references dnf, yum is a wrapper. For a full command mapping, see the Command Comparison Table below.
Package managers apply available upgrades from the repositories. Run an update of the package list first (see Update Package Lists).
| System | Command |
|---|---|
| Debian / Ubuntu | sudo apt upgrade |
| Rocky / Fedora / RHEL | sudo dnf upgrade |
| FreeBSD (packages) | sudo pkg upgrade |
On Debian and Ubuntu, apt upgrade installs updates that do not change the set of installed packages. Use apt full-upgrade (or apt-get dist-upgrade) when you need to allow new dependencies or package removals. On FreeBSD, upgrading ports can introduce breaking changes; read /usr/ports/UPDATING before upgrading with tools like portmaster.
Warning: Running apt upgrade or dnf upgrade on a production server can restart services or apply kernel updates that require a reboot. Use dry runs and change windows. See Production Best Practices.
Search by name or description to get the exact package name before installing.
| System | Command |
|---|---|
| Debian / Ubuntu | apt search search_string |
| Rocky / Fedora / RHEL | dnf search search_string |
| FreeBSD (packages) | pkg search search_string |
Note: On Rocky, Fedora, or RHEL, dnf search all searches both package names and descriptions. On FreeBSD, pkg search -D searches descriptions.
apt search nginx
Sorting... Done
Full Text Search... Done
nginx/jammy-updates 1.18.0-6ubuntu14.4 amd64
small, powerful, scalable web/proxy server
nginx-common/jammy-updates 1.18.0-6ubuntu14.4 all
small, powerful, scalable web/proxy server - common files
If search returns too many results, filter by searching the exact package name first, then fall back to description search only if needed:
apt search --names-only nginx
Sorting... Done
Full Text Search... Done
nginx/jammy-updates 1.18.0-6ubuntu14.4 amd64
small, powerful, scalable web/proxy server
On dnf-based systems, the default dnf search matches names and summaries. To include full descriptions:
dnf search all nginx
Use the exact package name from search results when running install or info commands. Package names are case-sensitive on all platforms.
Inspect version, description, and dependencies before installing.
| System | Command |
|---|---|
| Debian / Ubuntu | apt show package |
| Rocky / Fedora / RHEL | dnf info package |
| FreeBSD (packages) | pkg info package |
| FreeBSD (Ports) | cd /usr/ports/category/port && cat pkg-descr |
For example, to inspect the nginx package before installing:
apt show nginx
Package: nginx
Version: 1.18.0-6ubuntu14.4
Priority: optional
Section: web
Installed-Size: 46.1 kB
Depends: nginx-common (= 1.18.0-6ubuntu14.4), iproute2
Suggests: fcgiwrap, nginx-doc, ssl-cert
Homepage: https://nginx.net
APT-Sources: http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
The fields that matter most before installing:
Install a package and its dependencies with one command. You can list multiple packages.
| System | Command |
|---|---|
| Debian / Ubuntu | sudo apt install package |
| Rocky / Fedora / RHEL | sudo dnf install package |
| FreeBSD (packages) | sudo pkg install package |
The package manager resolves and lists dependencies before prompting for confirmation:
sudo apt install nginx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
libnginx-mod-http-geoip2 libnginx-mod-http-image-filter
libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream
libnginx-mod-stream-geoip2 nginx-common
The following NEW packages will be installed:
libnginx-mod-http-geoip2 libnginx-mod-http-image-filter
libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream
libnginx-mod-stream-geoip2 nginx nginx-common
0 upgraded, 8 newly installed, 0 to remove and 12 not upgraded.
Do you want to continue? [Y/n]
When you have a downloaded package file, install it from disk. On Debian-derived systems, dpkg installs a single .deb; if dependencies are missing, use gdebi or run apt install -f afterward to fix. On dnf-based systems, dnf install accepts a path to an .rpm and resolves dependencies from configured repositories. On FreeBSD, pkg add installs a local binary package (e.g. .txz).
| System | Command |
|---|---|
| Debian / Ubuntu | sudo dpkg -i package.deb |
| Rocky / Fedora / RHEL | sudo dnf install package.rpm |
| FreeBSD (packages) | sudo pkg add package.txz |
Note: On Debian and Ubuntu, if dpkg -i reports unmet dependencies, run sudo apt install -f to install them from repositories, or use gdebi package.deb to install the file and pull dependencies in one step.
Removal uninstalls the package and, depending on the tool and options, may remove configuration files or orphaned dependencies.
| System | Command |
|---|---|
| Debian / Ubuntu | sudo apt remove package |
| Rocky / Fedora / RHEL | sudo dnf remove package |
| FreeBSD (packages) | sudo pkg delete package |
On dnf-based systems, use dnf remove. On legacy systems that only have yum, yum erase package does the same thing. To remove a package and its configuration files, use apt purge package. Use purge when you want a clean slate, for example before reinstalling a service with different configuration. Use remove when you want to keep existing config files so they are available if you reinstall.
Repositories and packages are often signed so the package manager can verify origin and integrity. Misconfigured or missing keys can lead to failed updates or insecure installs.
Repository metadata is verified using GPG keys. Keys are stored in /usr/share/keyrings/ or /etc/apt/trusted.gpg.d/. Adding a repo usually involves adding its public key. The legacy apt-key command is deprecated; prefer placing key files in /usr/share/keyrings/ and referencing them in the repo line with signed-by=.
Most third-party repositories distribute keys as ASCII-armored .asc files. Convert and install the key in one step:
curl -fsSL https://example.com/repo-key.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/repo-key.gpg
Then in the repo definition (in sources.list or a file under sources.list.d/), use:
deb [signed-by=/usr/share/keyrings/repo-key.gpg] https://example.com/apt release components
See the Debian Wiki on SecureApt and your distribution’s documentation for the exact key setup for official repos.
RPM packages and repository metadata are signed. Import a repository’s GPG key with rpm:
sudo rpm --import https://example.com/repo-key.asc
Keys are stored in the rpm database. Repo files in /etc/yum.repos.d/ can specify gpgcheck=1 and gpgkey= so dnf/yum verify packages automatically.
pkg verifies packages using the repository’s signature. Ensure you are using an official or trusted repository configuration. The FreeBSD Handbook section on pkg describes repository and trust setup.
What can go wrong: If apt update fails with a GPG or signature error, the repository key may have changed or the repo URL may be wrong. Fix or remove the offending entry in sources.list or sources.list.d/. On dnf systems, rpm --import the correct key or disable the repo until it is fixed.
dnf keeps a transaction history so you can see past installs and upgrades and undo them.
List recent transactions:
dnf history list
ID | Command line | Date and time | Action(s)
-------+--------------------------+-----------------+-----------
5 | install httpd | YYYY-MM-DD HH:MM | Install
4 | upgrade | YYYY-MM-DD HH:MM | Upgrade
Undo a transaction by ID (for example, the last upgrade):
sudo dnf history undo id
Use dnf history rollback id to revert to the state after a given transaction. The DNF documentation describes all history subcommands.
Debian and Ubuntu apt do not provide a built-in rollback. You can reinstall an older version from cache if it is still present, or use snapshot/backup tools (e.g. LVM snapshots or system backups) to restore state. FreeBSD pkg does not offer transaction history rollback; rely on backups or reinstalling specific package versions if needed.
Broken dependencies prevent clean installs or upgrades. Fix them before proceeding.
If dpkg or apt report broken dependencies, try:
sudo apt --fix-broken install
This attempts to install or remove packages to satisfy dependencies. If the problem persists, apt install may suggest removing conflicting packages; review the list before confirming. Holding packages with apt-mark hold package can avoid unwanted upgrades but can also lead to conflicts if other packages depend on newer versions.
After a release upgrade or mixed repos, package versions can get out of sync. dnf distro-sync aligns installed packages with what the repository provides (downgrading or upgrading as needed):
sudo dnf distro-sync
Use when the release has changed or when you have enabled/disabled repos and get dependency conflicts. For single-package issues, dnf check and dnf repoquery can help inspect dependencies.
Warning: dnf distro-sync can downgrade packages. Run dnf distro-sync --assumeno first to see the proposed changes without applying them.
On production servers, avoid surprises by simulating changes and applying updates in controlled windows.
Dry run first. See what would be installed or upgraded without applying it.
apt upgrade --dry-run (simulation only; apt does not change the system).sudo dnf upgrade --assumeno (shows what would be done, then exits without applying).pkg upgrade -n (no-install mode).Schedule updates. Run upgrades during maintenance windows. Assume that kernel or library updates may require a reboot or service restarts.
Verify after update. After apt upgrade or dnf upgrade, check that critical services are running and that no packages were held back or skipped due to conflicts. Resolve any reported issues before leaving the window.
Staging. Test the same upgrade path on a staging system or non-critical server before applying it to critical production hosts.
Example: simulate an upgrade on a dnf system without applying it:
sudo dnf upgrade --assumeno
Review the list of packages; then run sudo dnf upgrade when you are ready to apply.
Use this table to translate between the four package managers for the same task.
| Task | apt (Debian/Ubuntu) | dnf (Rocky/Fedora/RHEL) | yum (legacy) | pkg (FreeBSD) |
|---|---|---|---|---|
| Update package lists | apt update |
dnf check-update |
yum check-update |
pkg update |
| Upgrade all packages | apt upgrade |
dnf upgrade |
yum update |
pkg upgrade |
| Search | apt search term |
dnf search term |
yum search term |
pkg search term |
| Package info | apt show pkg |
dnf info pkg |
yum info pkg |
pkg info pkg |
| Install from repo | apt install pkg |
dnf install pkg |
yum install pkg |
pkg install pkg |
| Install local file | dpkg -i file.deb |
dnf install file.rpm |
yum localinstall file.rpm |
pkg add file.txz |
| Remove package | apt remove pkg |
dnf remove pkg |
yum erase pkg |
pkg delete pkg |
| Transaction history / rollback | No built-in | dnf history list/undo |
Limited | No built-in |
pkg installs pre-built binary packages from FreeBSD mirrors. The Ports Collection is a tree of Makefiles under /usr/ports that build software from source. Use pkg when a binary is available and you do not need custom compile options; it is faster and avoids build dependencies. Use Ports when no binary exists, when you need to enable port options (e.g. build flags), or when you want to build from source for auditing or customization.
To use Ports, you need the ports tree. portsnap is deprecated on current FreeBSD releases. The recommended method is to install the tree from Git or from release media. For Git (as in the FreeBSD Handbook):
git clone https://git.freebsd.org/ports.git /usr/ports
To update an existing Git ports tree:
cd /usr/ports && git pull
To build and install a port, navigate to its directory under /usr/ports and run:
cd /usr/ports/category/port-name
make install clean
===> Installing for port-name-version
===> Registering installation for port-name-version
===> Cleaning for port-name-version
To configure build options before compiling:
make config
This opens a menu where you can toggle compile-time features. Run make config before make install clean so options are applied to the build.
Warning: Building from Ports compiles from source and can take significantly longer than pkg install, especially for large packages like databases or browsers. Use pkg install when a binary is available and you do not need custom options.
Binary packages from pkg remain the default for most users. Use Ports when no binary exists or when you need to change compile-time options.
Man pages are available for each package manager. Use / to search inside a page and q to quit.
| System | Command |
|---|---|
| Debian / Ubuntu | man apt or man apt-get |
| Rocky / Fedora / RHEL | man dnf |
| FreeBSD (packages) | man pkg |
| FreeBSD (Ports) | man ports |
man page
What is the difference between apt and apt-get?
apt is the recommended high-level command for interactive use: update, upgrade, install, remove, search, show. apt-get is the older interface and is still used for scripting (e.g. apt-get install -y) and for operations like dist-upgrade and autoremove. Both use the same repositories and package database.
Why was yum replaced by dnf?
dnf (Dandified YUM) was written to fix yum’s dependency resolution speed and memory use, and to use modern libraries. Fedora adopted dnf as the default; RHEL and derivatives (including Rocky Linux) followed. dnf keeps a yum-compatible command set so existing scripts and habits mostly work.
Can I use yum and dnf interchangeably?
On systems that ship dnf, yum is often a symlink or wrapper to dnf, so yum install and dnf install do the same thing. On legacy systems that only have yum, you must use yum. Prefer dnf where available; reserve yum for older RHEL/CentOS or when tooling explicitly expects it.
What is the difference between RPM and DEB packages?
RPM (Red Hat Package Manager) is used by Fedora, RHEL, Rocky Linux, and related distros; packages have a .rpm suffix. DEB is used by Debian, Ubuntu, and derivatives; packages have a .deb suffix. Both are archives of files plus metadata and dependencies; they are not interchangeable. Each family has its own tools: dnf/yum and rpm for RPM; apt and dpkg for DEB.
How do I update all packages safely on a production server?
Update package lists, then run a dry run or use –assumeno (dnf) or -n (pkg) to see what would change. Schedule the actual upgrade in a maintenance window. After upgrading, verify that critical services are running and that no dependency or hold-back issues remain. Test the same upgrade on a staging system when possible. See Production Best Practices.
What is FreeBSD pkg and how is it different from Linux package managers?
pkg is FreeBSD’s binary package manager. It installs pre-built .txz packages from repositories, similar in role to apt or dnf. Differences: pkg does not use apt or dnf; it has its own repo format and config; it has no built-in transaction history rollback; and FreeBSD also offers the Ports Collection for building from source, which has no direct Linux equivalent in the same form.
How do I roll back a package update in dnf?
Run dnf history list to see transaction IDs, then sudo dnf history undo id to undo that transaction. Use dnf history rollback id to revert to the state after a given transaction.
What happens if dependencies conflict?
The package manager will refuse the install or upgrade and report the conflict. On Debian/Ubuntu, run sudo apt --fix-broken install to try to resolve it; you may need to remove or change versions of conflicting packages. On dnf-based systems, dnf distro-sync can align packages with the repository after a release change; use dnf distro-sync --assumeno first to preview.
This guide gives a cross-platform reference for package management with apt, dnf, yum, and pkg. For deeper coverage of a single system, use the resources below.
For foundational Linux knowledge, see Getting started with Linux.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Building future-ready infrastructure with Linux, Cloud, and DevOps. Full Stack Developer & System Administrator. Technical Writer @ DigitalOcean | GitHub Contributor | Passionate about Docker, PostgreSQL, and Open Source | Exploring NLP & AI-TensorFlow | Nailed over 50+ deployments across production environments.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
you can use just “apt” for everything (except dpkg) apt-get update -> apt update apt-get upgrade -> apt upgrade apt-get dist-upgrade -> apt dist-upgrade apt-cache search search_string -> apt search search_string apt-cache show package -> apt show package install remove …
Great article! Apt-ollutly fantastic, condensed and straightforward :) Just wondering, did Fedora ppl ever get away from computers? I mean, in sports dnf means “did not finish”…
What about the best package managers, pacman and zypper? You forgot us, the Arch users… ;)
PS: Good article :)
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.