The Story of Software Repositories and the Struggles with Slow Networks
On my first day at work, I was assigned to deploy a cluster of 50 CentOS 7 servers for a bank. The catch? The Lab area was completely isolated from the internet for security. Back then, installing a simple tool like htop or vim was a nightmare. I had to copy individual RPM files and spend all day manually untangling a mess of dependencies.
After that painful experience, I realized that a Local Repository (internal software store) is indispensable. Instead of waiting for downloads from international mirrors at a few MB/s, you can pull packages over a 1Gbps or 10Gbps LAN. Installation speeds become nearly instantaneous. More importantly, it ensures every server in the system uses the same specific software version.
Below is the process I usually use to set up a Repo for CentOS, Rocky Linux, or AlmaLinux.
Quick Start: Create a Local Repo from an Existing Folder in 5 Minutes
If you already have a bunch of .rpm files on your machine and want to turn them into a repository that yum or dnf can understand, follow these steps:
- Install the initialization tool:
sudo yum install createrepo -y
- Prepare the directory: Let’s assume I place the packages at
/opt/my-local-repo.
sudo mkdir -p /opt/my-local-repo
# Copy .rpm files here
sudo cp /path/to/your/packages/*.rpm /opt/my-local-repo/
- Create Metadata for the Repo:
sudo createrepo /opt/my-local-repo/
- Declare it to the system: Create a new configuration file so Yum recognizes this repository.
sudo vi /etc/yum.repos.d/local.repo
Paste the following content into the file:
[local-repo]
name=My Local Repository
baseurl=file:///opt/my-local-repo/
enabled=1
gpgcheck=0
Now, you can use yum install freely without needing an internet connection.
Why Do Large Systems Always Use Local Repositories?
The quick method above only works on that specific machine. In practice, I always set up a server to act as a “storekeeper” for the entire infrastructure. This solution addresses three major pain points:
- Save Bandwidth: Only one machine needs internet access to download updates. The other 100 machines pull data directly from this storekeeper over the local network.
- Version Control: You avoid the disaster of application failures caused by automatic updates to incompatible new versions.
- Air-gapped Environments: This is a mandatory standard for financial or government systems where servers must absolutely not have external connections.
When helping teams migrate from CentOS 7 to AlmaLinux, using an internal Repo reduced package download wait times by up to 70%.
Deploying a Local Repo via HTTP with Nginx
To make it accessible to client machines on the LAN, we will use Nginx to share the repository directory.
Step 1: Install and Configure Nginx
sudo yum install nginx -y
sudo systemctl enable --now nginx
Create a server block configuration file to serve the files:
sudo vi /etc/nginx/conf.d/repo.conf
server {
listen 80;
server_name repo.local;
root /var/www/html/repos;
location / {
autoindex on; # Display file list
allow all;
}
}
Step 2: Organize the Repository Professionally
My experience is to divide directories by operating system and version:
sudo mkdir -p /var/www/html/repos/centos/7/os/x86_64/
sudo createrepo /var/www/html/repos/centos/7/os/x86_64/
Grant permissions to Nginx to avoid access errors:
sudo chown -R nginx:nginx /var/www/html/repos
sudo chmod -R 755 /var/www/html/repos
Step 3: Client-Side Configuration
On workstations, point the repo file to the IP address of the server you just set up:
[internal-repo]
name=Internal Central Repo
baseurl=http://192.168.1.100/centos/7/os/x86_64/
enabled=1
gpgcheck=0
priority=1
Synchronizing (Sync) Data from Official Mirrors
Manually downloading each RPM file is very time-consuming. To create a full mirror, use the reposync tool from the yum-utils package.
For example, to pull the entire CentOS 7 base repository to your machine:
sudo yum install yum-utils -y
sudo reposync -r base -p /var/www/html/repos/centos/7/os/x86_64/ --download-metadata
Note: A full repository can weigh anywhere from 10GB to over 50GB. Check your disk space before running this command.
Pro Tips for Smooth Operation
During my work, I’ve gathered a few notes to help you avoid time-consuming troubleshooting:
- Update Metadata: Every time you add a new
.rpmfile, you must runcreaterepo --update /path/to/repo. Without this step, client machines won’t see the new packages even if the files are in the directory. - Clear Cache: If a client reports that a package cannot be found, try the command
yum clean all && yum makecache. - SELinux: If Nginx returns a 403 error, it’s likely blocked by SELinux. Grant permissions to the directory using:
chcon -Rt httpd_sys_content_t /var/www/html/repos. - Firewall: Always remember to open port 80:
firewall-cmd --permanent --add-service=http && firewall-cmd --reload.
Building an internal Repository isn’t hard but it’s extremely valuable. If you manage 5 or more servers, set up a Local Repo immediately. It will help you resolve issues much faster when international connections fail or when you need to roll back software in the middle of the night.

