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

  1. Install the tools:
    dnf install createrepo_c httpd
    systemctl enable --now httpd
  2. 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 with dnf download --resolve PACKAGE --destdir /var/www/html/repo/el9.
  3. Create the metadata:
    createrepo_c /var/www/html/repo/el9
    This creates the repodata folder. Run it again with --update after adding or removing packages.
  4. Open the firewall for the clients: firewall-cmd --permanent --add-service=http && firewall-cmd --reload (or a rich rule for your network only).
  5. Check in a browser or with curl: curl -I http://REPO-SERVER/repo/el9/repodata/repomd.xml should 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, or createrepo_c was not run.
  • New packages do not show up: run createrepo_c --update on the server and dnf clean metadata on the client.
  • A mirror of a whole distribution repository: use dnf reposync instead of copying packages by hand.

Official documentation: createrepo_c and DNF configuration reference (repository options).

Ucartz services for this topic

Was this answer helpful? 0 Users Found This Useful (0 Votes)