A Bandwidth Nightmare at 2 AM
Imagine you’re on call at 2 AM. You need to urgently deploy a Kubernetes cluster or patch a security vulnerability for 20 Fedora servers. Suddenly, the international connection starts acting flaky. Watching the dnf update loading bar crawl at a few KB/s across dozens of servers simultaneously is a true test of patience.
After using Fedora as my primary OS for two years, I’m extremely satisfied with the ecosystem. However, letting every single server pull gigabytes of data individually from the internet is a massive waste of resources. A Local DNF Mirror solves this problem completely. It allows you to maximize internal bandwidth, reaching 1Gbps or even 10Gbps depending on your network infrastructure.
Infrastructure Preparation: Don’t Run Out of Disk Space Midway
Before running any commands, choose a server (physical or VM) with ample storage. Fedora repositories are quite large and will grow over time.
- Operating System: Fedora Server 40 (or the latest version).
- Storage: Minimum 200GB for Release and Updates. If you plan to mirror the Everything or Debuginfo repositories, you’ll need several terabytes.
- Tools:
dnf-utilsandcreaterepo_c.
Start by installing the synchronization tools and the web server:
sudo dnf install dnf-utils createrepo_c nginx -y
Step 1: Planning the Storage Directory
I usually mount a dedicated disk to /repo. This separates the repository data from the system partition, preventing the system from hanging if the disk fills up.
sudo mkdir -p /repo/fedora/releases/40/Everything/x86_64/os/
sudo mkdir -p /repo/fedora/updates/40/Everything/x86_64/
Tip: Replace ’40’ with the actual Fedora version you are currently deploying.
Step 2: Synchronizing Data with Reposync
This is the most time-consuming part of the initial setup. We will use reposync to pull all packages from official mirrors. Unlike standard DNF, reposync downloads an exact copy to build a local repository.
Syncing the fedora repo (original release):
sudo reposync --repoid=fedora --download-metadata --p=/repo/fedora/releases/40/Everything/x86_64/os/
Syncing the updates repo (latest patches):
sudo reposync --repoid=updates --download-metadata --p=/repo/fedora/updates/40/Everything/x86_64/
Important Note: Downloading dozens of gigabytes can be easily interrupted. You should run these commands in tmux or screen to maintain the session if your SSH connection drops.
Step 3: Initializing Metadata with Createrepo
Once the .rpm files are downloaded, client machines still won’t be able to use them without metadata. We need to use createrepo_c to generate index files. This tool is written in C, making it much faster than the older Python version.
sudo createrepo_c /repo/fedora/releases/40/Everything/x86_64/os/
sudo createrepo_c /repo/fedora/updates/40/Everything/x86_64/
Step 4: Configuring Nginx as the Distribution Hub
To allow client machines to access the repo via HTTP, Nginx is the top choice due to its lightweight nature.
Create a new configuration file at /etc/nginx/conf.d/repo.conf:
server {
listen 80;
server_name repo.lab.local;
root /repo;
location / {
autoindex on;
allow all;
}
}
Don’t forget to set permissions so Nginx can read the data and configure SELinux to allow the web service to function:
sudo chown -R nginx:nginx /repo
sudo chmod -R 755 /repo
sudo setsebool -P httpd_enable_homedirs on
sudo chcon -Rt httpd_sys_content_t /repo
Enable the service and open the firewall:
sudo systemctl enable --now nginx
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload
Step 5: Pointing Client Machines to the Local Mirror
Now it’s time to enjoy the results. On Fedora machines within the LAN, temporarily hide the default repos and point them to your internal server.
Clean up old files:
sudo mkdir /etc/yum.repos.d/backup
sudo mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/
Create the file /etc/yum.repos.d/local-fedora.repo with the following content:
[local-fedora]
name=Fedora $releasever - Local
baseurl=http://repo.lab.local/fedora/releases/$releasever/Everything/$basearch/os/
enabled=1
gpgcheck=0
[local-updates]
name=Fedora $releasever - Updates - Local
baseurl=http://repo.lab.local/fedora/updates/$releasever/Everything/$basearch/
enabled=1
gpgcheck=0
Check the speed with the command:
sudo dnf clean all && sudo dnf makecache
sudo dnf update
You will see that the package download speed now only depends on the limits of your internal network card.
Automating Daily Updates
Repository data will quickly become outdated if not updated regularly. Create a small script that runs at 3 AM to automatically sync the latest patches.
Create the script /usr/local/bin/sync-repo.sh:
#!/bin/bash
# Only download the newest packages to save storage space
reposync --repoid=updates --download-metadata --p=/repo/fedora/updates/40/Everything/x86_64/ --newest-only
createrepo_c --update /repo/fedora/updates/40/Everything/x86_64/
Set up a Cronjob for the script to run automatically:
0 3 * * * /usr/local/bin/sync-repo.sh > /var/log/repo-sync.log 2>&1
Final Thoughts
Setting up a Local DNF Mirror might seem time-consuming at first, but it’s a worthwhile investment for anyone managing a multi-server environment. You’ll no longer have to worry when fiber optic cables fail or sit waiting for hours to update a server cluster. If you manage five or more Fedora machines, try implementing this today.

