Create an RPM repository

Install dependencies

sudo dnf install -y gnupg createrepo dnf-utils rpm-sign wget

Setup GnuPG

echo "%echo Generating a PGP key
Key-Type: RSA
Key-Length: 4096
Name-Real: Jeffrey Serio
Name-Email: hyperreal@moonshadow.dev
Expire-Date: 0
%no-ask-passphrase
%no-protection
%commit" > ~/hyperreal-pgp-key.batch

Now generate the key with the following command:

gpg --no-tty --batch --gen-key ~/hyperreal-pgp-key.batch

Export the public key.

gpg --armor --export "Jeffrey Serio" > ~/hyperreal-pgp-key.pub

Export the private key to back it up somewhere safe.

gpg --armor --export-secret-keys "Jeffrey Serio" > ~/hyperreal-pgp-key.sec

After backup up the private key, shred it from the working directory.

shred -xu ~/hyperreal-pgp-key.sec

Setup RPM signing

Replace E1933532750E9EEF with your key's ID.

echo "%_signature gpg
%_gpg_name E1933532750E9EEF" > ~/.rpmmacros

Create a directory to serve the repository.

mkdir -p ~/rpm-repo/packages

Move RPM packages into the repo directory. Then sign them with the following command:

rpm --addsign ~/rpm-repo/packages/*.rpm

Create repo index

Once all the packages are signed, create the repository with the following command:

createrepo ~/rpm-repo/packages/

The above command will create a directory in the repo named repodata containing a file named repomd.xml.

Note that the createrepo command must be run against each directory in the repo that contains .rpm files.

Now sign the repo metadata with the following command:

gpg --detach-sign --armor ~/rpm-repo/packages/repodata/repomd.xml

Create a .repo file

~/rpm-repo/hyperreal-kernel-bazzite.repo

[hyperreal-kernel-bazzite]
name=hyperreal kernel bazzite $releasever
baseurl=https://rpm.hyperreal.coffee/kernel-bazzite/fedora-$releasever/$basearch
enabled=1
gpgcheck=1
gpgkey=https://rpm.hyperreal.coffee/hyperreal-pgp-key.pub

The RPM repository should now be ready to be served on a web server with ~/rpm-repo as the web root.

Example Caddy configuration

rpm.hyperreal.coffee {
root * /home/jas/rpm-repos/
file_server browse
}