29.5 /etc/yum.repos.d: Repository Configuration Files
Alright, let’s get our hands dirty. If rpm is the engine that installs individual packages, then the repositories defined in /etc/yum.repos.d/ are the entire global supply chain that feeds it. This directory is the brains of the operation for yum and dnf, telling them where to find software, how to trust it, and what to care about. Ignore this, and you’re just hammering away with a blunt rpm tool; master it, and you unlock the entire curated universe of software for your distribution.
Think of it this way: you wouldn’t drive across the country with a single, hand-scribbled gas station address from 1998. You use a modern app that shows you all the options, prices, and which ones your car accepts. /etc/yum.repos.d/ is that app. It’s a collection of plain-text .repo files that together form your system’s complete, updatable map of software sources.
The Anatomy of a .repo File
Each file in this directory ends with .repo, and the name is arbitrary but should be meaningful. fedora.repo is good; my_stuff.repo is fine; asdfghjkl.repo is a cry for help. Inside, you define one or more repositories, each in its own section.
A repository section is a perfect example of UNIX philosophy: a simple key-value pair configuration. Here’s a canonical example, the kind you’ll see for the main Fedora repositories:
[fedora]
name=Fedora $releasever - $basearch
metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
skip_if_unavailable=False
Let’s break down the key players here:
[fedora]: This is the repository ID. It’s a unique, single-word name used internally bydnf. Make it descriptive.name: A human-readable description. This is where you can use spaces and make it pretty.baseurlORmetalink: The critical “where to look” directive.baseurl: A direct, static list of URLs. Simple, but brittle. If one mirror goes down, the whole operation can fail. You’ll see it likebaseurl=http://mirror.example.com/fedora/releases/38/Everything/x86_64/os/.metalink: This is the smarter, modern choice. You point it to a metalink file (an XML document that contains a list of mirrors, their geographic location, and priority). The client then chooses the best mirror for you. It’s dynamic and robust. Always prefer this if provided.
enabled: A1(yes) or0(no). This is your on/off switch. You can have a.repofile present but disable a repo without deleting the file—incredibly useful for troubleshooting or temporarily avoiding a repo.gpgcheck: Leave this as1. This is what verifies the cryptographic signature of packages, ensuring they haven’t been tampered with and actually came from the repository owner. Turning this off is like buying medication from a guy in a alley because his “line was shorter”; you might get what you want, but you have no idea what’s actually in it.gpgkey: The path to the public GPG key file used to perform the signature check. This can be a local file (file://) or a remote URL (https://). The system will automatically import this key into your RPM keyring.
Variables: Making One Config Rule Them All
You noticed the $releasever and $basearch in the example, right? This isn’t magic; it’s simple variable substitution that dnf performs. This is why one .repo file can work across Fedora 36, 37, and 38, on both x86_64 and ARM architectures.
$releasever: The major version of your distribution (e.g., 38).$basearch: The base architecture (e.g.,x86_64,aarch64). This means you can often just drop a.repofile from a vendor onto any compatible system, and it just works. It’s a fantastically simple and effective system.
Common Pitfalls and the “Why”
Here’s where your brilliant friend (me) saves you from pulling your hair out.
- The Silent Enabling: If you don’t specify
enabled=,dnfassumes it’s enabled. I hate this default. It’s a terrible choice. Always explicitly stateenabled=0when adding a new repo you’re not ready to use, or when creating a repo for a specific, temporary purpose. This avoids accidentally installing packages from the wrong source. - The GPG Key Dance: Adding a new repo often requires importing its GPG key. You can specify it in the
gpgkey=directive, anddnfwill usually handle it on first run. But sometimes you need to do it manually. It’s not hard:sudo rpm --import https://example.com/REPO-KEY.pub - The Priority Gotcha: What if two repositories offer the same package? By default,
dnfjust picks the one with the higher version. If you need more control, you can use theprioritydirective. A lower number means a higher priority (because, of course it does). Use this sparingly, as it can create dependency hell if misconfigured.[my-special-repo] name=My Special Packages baseurl=https://example.com/repo enabled=1 gpgcheck=1 priority=50 - The Cleanup: When you disable or remove a
.repofile, the metadata is still cached. Ifdnfstarts acting weird, complaining about missing repos you just deleted, clear its cache:This forcessudo dnf clean alldnfto re-read all repository configurations and download fresh metadata. It’s the “have you tried turning it off and on again?” of package management, and it works an embarrassing percentage of the time.
So there you have it. The humble .repo file: a few lines of text that give you access to everything, from the core distro to niche proprietary drivers. Treat them with respect, understand their moving parts, and you’ll never be stuck wondering how to get the software you need.