Updated: 28 September 2026 · Applies to: createrepo_c 0.20 and 1.1, httpd 2.4 and dnf on AlmaLinux and Rocky Linux 9 and 10 and RHEL 9 and 10
Your own package repository lets several servers install the same, tested RPM packages: internal software, pinned versions, or packages for servers without internet access. You create repository metadata with createrepo_c and publish the folder with any web server. We tested the steps on AlmaLinux 9: dnf found and read the new repository.
On the repository server
- Install the tools:
dnf install createrepo_c httpd systemctl enable --now httpd
- Create a folder per OS version and copy your packages into it:
mkdir -p /var/www/html/repo/el9 cp /path/to/*.rpm /var/www/html/repo/el9/
To add packages from the official repositories, download them withdnf download --resolve PACKAGE --destdir /var/www/html/repo/el9. - Create the metadata:
createrepo_c /var/www/html/repo/el9
This creates therepodatafolder. Run it again with--updateafter adding or removing packages. - Open the firewall for the clients:
firewall-cmd --permanent --add-service=http && firewall-cmd --reload(or a rich rule for your network only). - Check in a browser or with curl:
curl -I http://REPO-SERVER/repo/el9/repodata/repomd.xmlshould answer 200.
Files under /var/www/html get the correct SELinux label automatically. If you use another folder, label it with semanage fcontext -a -t httpd_sys_content_t "/srv/repo(/.*)?" and restorecon -Rv /srv/repo.
Sign the packages (recommended)
Signed packages let clients check that nothing was changed on the way. Create a GPG key, sign each package with rpmsign --addsign package.rpm (package rpm-sign, with %_gpg_name set in ~/.rpmmacros), publish the public key as a file in the repository, and set gpgcheck=1 on the clients.
On each client
Create /etc/yum.repos.d/internal.repo:
[internal] name=Internal packages baseurl=http://repo.example.lan/repo/el9 enabled=1 gpgcheck=1 gpgkey=http://repo.example.lan/repo/RPM-GPG-KEY-internal
Use gpgcheck=0 only for a quick test with unsigned packages. Then check:
dnf clean metadata dnf --disablerepo="*" --enablerepo=internal list available
Common problems
- "Cannot download repomd.xml": wrong
baseurl, the web server is not reachable, orcreaterepo_cwas not run. - New packages do not show up: run
createrepo_c --updateon the server anddnf clean metadataon the client. - A mirror of a whole distribution repository: use
dnf reposyncinstead of copying packages by hand.
Official documentation: createrepo_c and DNF configuration reference (repository options).
Ucartz services for this topic
- KVM VPS hosting: NVMe SSD and full root access, with Free Basic Managed Support.
- Unmanaged dedicated servers: full root access and free IPMI KVM, with Free Basic Managed Support.
- Linux server management: hardening, patching, monitoring and automation for Ubuntu, Debian, RHEL and AlmaLinux.
