Updating a Low-memory Server Running Fedora 36+
The Problem: dnf
requires a lot of RAM!
I have been running Fedora Server for several years on a server with a small amount of RAM (1 GiB) and a small amount of swap (1.2 GiB). Over the last several months, I ran into a situation where the server was having high loads on occasion. Thinking that something malicious was happening, I investigated.
As it turned out, what was happening is that I had auto updates for Fedora
turned on and they were failing due to the amount of metadata dnf
had to
handle—it was running out of RAM and swap to complete the update process. This
seemed crazy since I have successfully being using Fedora on that machine for
some time and have upgraded the distribution in place many times.
In researching the situation, several people have run across this particular
issue. In fact, there is a
Red Hat Bugzilla issue for
the situation. Buried deep in the posts, I ran across several things that were
very helpful. First, as a background, it appears that the implementation of
dnf
(the standard Fedora package manager for years) has been written in Python
(to some degree). As a result of using Python and the large number of packages
in the Fedora repositories, just processing the updates and their dependencies
can take a lot of RAM.
The Solution: microdnf
In the bug tracker post, though, there was several suggested solutions. The
most promising was the use of
microdnf
in place of
dnf
for handling package
management. microdnf
is written in C and requires much less RAM and other
resources to run. In fact, it was designed to run as the package manager for
containers, so it is designed to reduce the resources required for package
management.
Given that dnf
was having issues, it might be challenging to install
microdnf
in the first place. The suggestion was to run the following to
reduce the memory footprint for installing microdnf
:
dnf --repoid=fedora makecache && dnf --repoid=fedora install microdnf
In particular, this is restricting the effort and memory costs to make the
repository cache and installing microdnf
by limiting dnf
to using the
fedora
repository. Once it is installed you can run microdnf
, much like you
can dnf
.
One operation that I wasn’t sure about, though, was how to update to a newer version of Fedora. For example, from Fedora 36 to Fedora 38. Thankfully, the Red Hat Bugzilla issue provided an example of how to do that:
microdnf --releasever=38 distro-sync
microdnf
Command Reference
Here is the help provided by microdnf
on the command line:
$ microdnf -h
Usage:
dnf5 <COMMAND> [--help] ...
Description:
DNF5 is a program for maintaining packages.
Software Management Commands:
install Install software
upgrade Upgrade software
remove Remove (uninstall) software
distro-sync Upgrade or downgrade installed software to the latest available versions
downgrade Downgrade software
reinstall Reinstall software
swap Remove software and install another in one transaction
mark Change the reason of an installed package
autoremove Remove all unneeded packages originally installed as dependencies.
check-upgrade Check for available package upgrades
Query Commands:
leaves List groups of installed packages not required by other installed packages
repoquery Search for packages matching various criteria
search Search for software matching all specified strings
list Lists packages depending on the packages' relation to the system
info Lists packages depending on the packages' relation to the system
Subcommands:
group Manage comps groups
environment Manage comps environments
module Manage modules
history Manage transaction history
repo Manage repositories
advisory Manage advisories
Compatibility Aliases:
dg Alias for 'downgrade'
groupinfo Alias for 'group info'
grouplist Alias for 'group list'
in Alias for 'install'
ls Alias for 'list'
rei Alias for 'reinstall'
repoinfo Alias for 'repo info'
repolist Alias for 'repo list'
rm Alias for 'remove'
up Alias for 'upgrade'
update Alias for 'upgrade'
updateinfo Alias for 'advisory'
upgrade-minimal Alias for 'upgrade --minimal'
check-update Alias for 'check-upgrade'
Commands:
clean Remove or expire cached data
download Download software to the current directory
makecache Generate the metadata cache
Global options:
-h, --help Print help
--config=CONFIG_FILE_PATH Configuration file location
-q, --quiet In combination with a non-interactive command, shows just the relevant cont
ent. Suppresses messages notifying about the current state or actions of dn
f5.
--setopt=[REPO_ID.]OPTION=VALUE set arbitrary config and repo options
--setvar=VAR_NAME=VALUE set arbitrary variable
-y, --assumeyes automatically answer yes for all questions
--assumeno automatically answer no for all questions
--best try the best available package versions in transactions
--no-best do not limit the transaction to the best candidate
--no-docs Don't install files that are marked as documentation (which includes man pa
ges and texinfo documents)
-x package,..., --exclude=package,... exclude packages by name or glob
--enable-repo=REPO_ID,... Enable additional repositories. List option. Supports globs, can be specifi
ed multiple times.
--disable-repo=REPO_ID,... Disable repositories. List option. Supports globs, can be specified multipl
e times.
--repo=REPO_ID,... Enable just specific repositories. List option. Supports globs, can be spec
ified multiple times.
--no-gpgchecks disable gpg signature checking (if RPM policy allows)
--no-plugins disable all plugins
--enable-plugin=PLUGIN_NAME,... Enable plugins by name. List option. Supports globs, can be specified multi
ple times.
--disable-plugin=PLUGIN_NAME,... Disable plugins by name. List option. Supports globs, can be specified mult
iple times.
--comment=COMMENT add a comment to transaction
--installroot=ABSOLUTE_PATH set install root
--use-host-config use configuration, reposdir, and vars from the host system rather than the
installroot
--releasever=RELEASEVER override the value of $releasever in config and repo files
--debugsolver Dump detailed solving results into files
--version Show DNF5 version and exit
Options Compatibility aliases:
--nobest Alias for '--no-best'
--nodocs Alias for '--no-docs'
--enablerepo=REPO_ID,... Alias for '--enable-repo'
--disablerepo=REPO_ID,... Alias for '--disable-repo'
--repoid=REPO_ID,... Alias for '--repo'
--nogpgcheck Alias for '--no-gpgchecks'
--noplugins Alias for '--no-plugins'
--enableplugin=PLUGIN_NAME,... Alias for '--enable-plugin'
--disableplugin=PLUGIN_NAME,... Alias for '--disable-plugin'
It is interesting that microdnf
is actually called
dnf5
. The
documentation for dnf5
provides some
nice additional information . dnf5
is a rewrite of dnf
in C++ and is
planned to replace
dnf
in Fedora 41, a few releases in the future.
In any case, using microdnf
made it possible for me to continue to use Fedora
on my small server where dnf
ran out of RAM resources to run.