apt to dnf: equivalents for Rocky and Fedora
The dnf command for every apt command you already know, on Rocky Linux, AlmaLinux and Fedora, plus the repository and rollback parts that do not map.
The short answer
Moving from apt to dnf is mostly a vocabulary change. apt install nginx becomes dnf install nginx. apt remove nginx becomes dnf remove nginx. apt update has no direct equivalent, because dnf refreshes its repository metadata on its own when the cached copy gets old. The easy half of the translation takes one screen. The useful half is the four operations that do not map at all: adding a repository, undoing a transaction, installing a package group, and running unattended updates.
Every command below is written for you to run on your own server. Read the transaction summary dnf prints before you answer y, especially on removals.
Which distros use dnf, and which use apt
dnf is the package manager on Fedora, on Red Hat Enterprise Linux (RHEL), and on the rebuilds of RHEL: Rocky Linux, AlmaLinux and CentOS Stream. apt is the package manager on Debian and on everything derived from Debian, which on a VPS almost always means Ubuntu. There is no third answer. If your provider's image list offers Rocky Linux or AlmaLinux, you are getting dnf. If it offers Ubuntu, you are getting apt.
The package format follows the tool. dnf installs .rpm files and its database is rpm. apt installs .deb files and its database is dpkg. That is why so many vendor install pages have one tab for each family, and why a .deb downloaded from a project's release page is useless on Rocky Linux.
Whichever family you land on, the first login is the same work. The first ten minutes on a new VPS applies to both. Only the install command changes.
Every apt command and its dnf equivalent
Install, remove, search and show. These take almost the same words on both sides.
# apt
sudo apt install nginx
sudo apt remove nginx
apt search nginx
apt show nginx
# dnf
sudo dnf install nginx
sudo dnf remove nginx
dnf search nginx
dnf info nginxapt show is dnf info. That is the only renamed verb in the group, but one behaviour differs and it catches people out. dnf remove also removes dependencies that nothing else needs, while apt remove leaves them installed for a later apt autoremove. So removing one small utility on Rocky Linux can propose taking a dozen libraries with it. Read the list before confirming.
Refresh metadata, check what is waiting, and upgrade.
# apt
sudo apt update
apt list --upgradable
sudo apt install --only-upgrade nginx
sudo apt upgrade
# dnf
sudo dnf makecache
dnf check-update
sudo dnf upgrade nginx
sudo dnf upgradeapt update is mandatory on the apt side, because apt uses whatever metadata is on disk and will happily install a version that left the archive months ago. dnf checks the age of its cache before every transaction and downloads fresh metadata by itself, so sudo dnf makecache is only for forcing that download to happen now instead of during your next install.
apt splits the whole system upgrade in two, and dnf does not. apt upgrade refuses to remove any installed package, so it stops short whenever an update needs one gone. apt full-upgrade is the version allowed to remove. dnf has no such restriction, which means dnf upgrade is the equivalent of apt full-upgrade, not of apt upgrade. dnf update is an older alias for the same command and still works.
One detail matters if you script this: dnf check-update exits with status 100 when updates are waiting and 0 when there are none. apt list --upgradable exits 0 either way, so scripts have to parse its output.
List what is installed, and find out which package owns a file.
# apt
dpkg -l
dpkg -S /usr/sbin/nginx
dpkg -L nginx
apt-file search /usr/sbin/nginx
# dnf
dnf list --installed
rpm -qf /usr/sbin/nginx
rpm -ql nginx
dnf provides /usr/sbin/nginxThe last line of each block answers a different question from the ones above it. dpkg -S and rpm -qf search only packages that are already installed, so they answer "what put this file here". apt-file search and dnf provides search the repositories, so they answer "what would I install to get this file". apt-file is a separate package on Ubuntu and needs sudo apt-file update before its first run. dnf provides needs nothing extra, though the first run can be slow because dnf downloads the repository file lists to answer.
To list the files inside a package you have not installed yet, use dnf repoquery -l nginx. On the apt side that is apt-file list nginx.
Autoremove, clean the cache, hold a version.
# apt
sudo apt autoremove
sudo apt clean
sudo apt-mark hold nginx
apt-mark showhold
sudo apt-mark unhold nginx
# dnf
sudo dnf autoremove
sudo dnf clean all
sudo dnf versionlock add nginx
dnf versionlock list
sudo dnf versionlock delete nginxversionlock is not installed by default on Rocky Linux or AlmaLinux, so the first of those lines fails with No such command: versionlock on a fresh box. Install it first with sudo dnf install python3-dnf-plugin-versionlock. apt needs nothing extra for apt-mark hold, because a hold is a dpkg state rather than a plugin.
Where the mapping breaks: adding a repository
This is the part that sends Ubuntu admins hunting for a command that does not exist. There is no add-apt-repository on dnf, and there are no personal package archives (PPAs). A PPA is a service run by Launchpad, and Launchpad is Ubuntu infrastructure. Nothing in the RPM world hosts one.
What dnf has instead is one plain text file per repository in /etc/yum.repos.d/, ending in .repo.
[docker-ce-stable]
name=Docker CE Stable
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg$releasever and $basearch are dnf variables. dnf fills in your major release number and your CPU architecture at runtime, so the same file works on version 9 and version 10, and on x86_64 and aarch64.
Most vendors publish that file and tell you to fetch it. Docker's own instructions for RHEL and its rebuilds are two commands:
sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repoThe first line is there because config-manager is a plugin, not part of dnf itself. Skip it and the second line fails with No such command: config-manager. Nothing stops you from downloading that same .repo file with curl into /etc/yum.repos.d/ by hand, and the result is identical. Installing Docker on a VPS walks the Debian side of the same job, where the equivalent step writes a source list and a signing key into two different directories.
The layout difference decides where you look when a repository misbehaves. apt keeps definitions in /etc/apt/sources.list and /etc/apt/sources.list.d/, with signing keys held separately under /etc/apt/keyrings/. dnf keeps everything in /etc/yum.repos.d/, and the key is a URL inside the .repo file, so there is one file to read and one file to delete. Newer apt has moved toward the same shape with the deb822 format, one .sources file per repository. If you have hit the deb822 duplicate sources error on Ubuntu, you have already met the apt half of this problem.
EPEL is the archive most guides assume
Extra Packages for Enterprise Linux (EPEL) is a Fedora project that builds Fedora packages for RHEL and its rebuilds. It is the nearest thing this world has to a universal PPA, and a very large number of tutorials assume it is already enabled. If dnf install answers No match for argument for a package you can see on the project's own website, EPEL is the first thing to check.
On Rocky Linux and AlmaLinux:
sudo dnf config-manager --set-enabled crb
sudo dnf install epel-release
sudo dnf makecacheCRB is CodeReady Builder, a repository of libraries that ships with the distribution but is not enabled by default. Most EPEL packages depend on something in it, so enabling EPEL without CRB does not fail at that moment. It fails later, at install time, with unresolved dependencies on a package you have never heard of. Enable CRB first and that class of error disappears.
On RHEL itself, CRB arrives through your subscription rather than through config-manager, so follow Red Hat's own EPEL instructions for that step. Fedora needs none of this, because its main repository already carries what EPEL backports. EPEL policy is to never replace a package that RHEL ships, so adding the repository does not change anything already installed on your server.
dnf history undo, the thing apt cannot do
dnf records every transaction, and it can build the reverse of one.
sudo dnf history
sudo dnf history info 42
sudo dnf history undo 42dnf history prints a numbered list of transactions with the command line that started each one. undo constructs the opposite transaction: packages that transaction installed are removed, and packages it upgraded go back to the version you had. This is the feature apt users miss most after switching.
It has real limits, and they are worth knowing before you rely on it. undo can only reinstall a package version that still exists in an enabled repository, so once the old build has been dropped from the mirror the undo fails with a not-found error. Rollback also stops at the package database. A config file the upgrade rewrote stays rewritten, and a database schema a service migrated on first start stays migrated. dnf puts the files back. It does not put your data back.
apt has no equivalent. /var/log/apt/history.log records exactly what happened, including the command line, but reading a log is not undoing it. The apt-side recovery is manual: run apt list -a nginx to see which versions the archive still holds, then sudo apt install nginx=<exact version string> to pin one, and add sudo apt-mark hold nginx so the next upgrade does not undo your fix.
Package groups have no apt equivalent
dnf can install a named set of packages in one command.
dnf group list
dnf group info "Development Tools"
sudo dnf group install "Development Tools"Older guides write dnf groupinstall "Development Tools". That alias works on dnf 4 and is gone on dnf 5, so the two-word dnf group install is the only spelling that works everywhere. Use it and stop thinking about it.
apt has no groups. Debian's closest idea is a metapackage, an otherwise empty package whose only content is a list of dependencies, such as build-essential. The practical difference is on the way out: removing a metapackage leaves its dependencies installed until you run apt autoremove, while dnf group remove takes the group's packages with it in the same transaction.
unattended-upgrades and dnf-automatic
Both families ship a way to install updates with nobody logged in. The tools share nothing but the purpose.
On Ubuntu and Debian the package is unattended-upgrades, configured in /etc/apt/apt.conf.d/50unattended-upgrades, where you list the origins it is allowed to pull from. Setting up unattended upgrades on Ubuntu covers that config file and the reboot question that comes with it.
On Rocky Linux, AlmaLinux and Fedora the package is dnf-automatic, and the systemd timer you enable decides the behaviour.
sudo dnf install dnf-automatic
sudo systemctl enable --now dnf-automatic-install.timer
systemctl list-timers 'dnf-automatic*'dnf-automatic-install.timer downloads and applies updates. dnf-automatic-download.timer downloads them and stops, leaving the install to you. dnf-automatic-notifyonly.timer only reports. Each of those units overrides the apply_updates setting in /etc/dnf/automatic.conf, so the timer you pick matters more than what the config file says.
To restrict it to security fixes, set upgrade_type = security in /etc/dnf/automatic.conf. That filter depends on your repositories publishing security errata, so check first with dnf updateinfo list security. An empty result on a box that has updates pending means the metadata is not there, and security would then install nothing at all.
On Fedora, dnf 5 renamed the unit. It is dnf5-automatic.timer, and it reads the same /etc/dnf/automatic.conf.
Is yum still a real command?
Yes, and it does nothing by itself. On Rocky Linux, AlmaLinux and CentOS Stream, /usr/bin/yum is a symbolic link pointing at dnf. Check yours:
ls -l /usr/bin/yum
dnf --versionOld yum syntax keeps appearing in tutorials because most of it still passes straight through. yum install, yum remove and yum update all work. One habit is worth dropping: yum-config-manager still exists as its own binary on dnf 4 systems, but dnf config-manager is the spelling current documentation uses, and it is the one that keeps working when the box moves to dnf 5.
dnf 4 and dnf 5: check before you copy a command
dnf 5 is a rewrite, and it changed the spelling of several commands. Fedora 41 and later ship it as dnf. The enterprise rebuilds have been slower to switch, so do not guess from the distribution name. Run dnf --version on your own server and read the first line, because that number decides which syntax below you need.
The clearest demonstration comes from Docker, which publishes a different repository command for each. On RHEL and its rebuilds, with dnf 4:
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repoOn Fedora, with dnf 5:
sudo dnf config-manager addrepo --from-repofile https://download.docker.com/linux/fedora/docker-ce.repoSame vendor, same job, different words. dnf 5 turned config-manager into a subcommand-driven tool, so the old --add-repo flag is not accepted and you get a usage error instead of a repository. The other one you will meet is enabling a repository: dnf config-manager --set-enabled crb on dnf 4 becomes dnf config-manager setopt crb.enabled=1 on dnf 5.
The choice that actually matters
Picking a server distribution on package manager alone is the wrong axis. dnf and apt do the same work, and the vocabulary takes an afternoon. What changes your year is the release model behind the repository. Fedora moves quickly and a given release stops getting updates roughly thirteen months after it appears, which is fine for a workstation and painful for a server you do not want to rebuild. Rocky Linux and AlmaLinux track RHEL, so you get a ten year support window and package versions that deliberately stay still. Ubuntu offers both shapes, and the difference between Ubuntu LTS and interim releases on a server is the same decision made inside the apt world.
As of August 2026, all of these are ordinary VPS images. Pick the support window you want, then learn the ten commands above.
FAQ
What is the dnf equivalent of apt update?
There is no command you have to run. dnf checks how old its cached metadata is before every transaction and downloads a fresh copy when it has expired, so dnf install on a server you have not touched for a month still sees current packages. sudo dnf makecache exists and does force that download, but its real use is moving the delay to a time you choose instead of into your next install. The command that answers "what is waiting for me" is dnf check-update, which maps to apt list --upgradable and exits with status 100 when updates are available.
Is there a PPA equivalent on Rocky Linux or Fedora?
No. Personal package archives are a Launchpad service and Launchpad is Ubuntu infrastructure, so add-apt-repository has nothing to translate into. The RPM equivalent is a .repo file in /etc/yum.repos.d/ holding a name, a baseurl and a gpgkey. Vendors publish that file for you, and sudo dnf config-manager --add-repo <url> on dnf 4, or sudo dnf config-manager addrepo --from-repofile <url> on dnf 5, downloads it into place. For general extra software the answer is usually EPEL, which you enable with sudo dnf config-manager --set-enabled crb followed by sudo dnf install epel-release.
Can I undo a dnf upgrade that broke my server?
Yes, within limits. Run sudo dnf history to find the transaction number, sudo dnf history info <id> to see exactly what it changed, then sudo dnf history undo <id>. The undo fails if the older package version is no longer present in any enabled repository, because dnf has nothing to reinstall from. It also only reverses package changes. A configuration file rewritten by the upgrade, or a database migrated by a service on first start, stays as it is. apt has no equivalent command at all, only the record in /var/log/apt/history.log.
Does yum still work on Rocky Linux and AlmaLinux?
It works because /usr/bin/yum is a symbolic link to dnf. Confirm it on your own box with ls -l /usr/bin/yum. Typing yum install httpd runs dnf, so old tutorials mostly still function. Write new scripts and documentation with dnf, since the yum name is compatibility only, and prefer dnf config-manager over the older yum-config-manager binary.
Why does dnf remove want to delete so many packages?
Because dnf removes dependencies that nothing else needs as part of the same transaction, while apt remove leaves them installed until you run apt autoremove separately. So a removal that looks small on Ubuntu can print a long list on Rocky Linux. The list is usually correct, but read it before confirming. If a package on it is one you want to keep, install it explicitly first so dnf records it as wanted in its own right.