Creating a local repository for your own Fedora packages

Posted on . Updated on .

Almost two years ago I wrote about a nice surprise in the Fedora freetype package that made it easy for users to rebuild the package and include subpixel rendering support. In the original article I also added some brief instructions with a few commands to run in order to create and prepare a specific user account used to build packages.

Expanding on that, I mentioned you’d want to install the build dependencies for the freetype package before rebuilding it. Back then I mentioned the packages explicitly. The list can be obtained from the package SPEC file, but there’s a better option. Any time you want to rebuild an official package you can install its build dependencies automatically by using dnf builddep, as in:

dnf builddep freetype

Furthermore, if you rebuild an official package you’ll notice sometimes Fedora wants to reinstall the original one from the official repositories. In order to avoid that, you can create a local repository containing your own packages and make it take precedence over the official packages. In any case, this is also handy if you have additional non-official packages you build yourself.

The first step is creating the repository metadata. Let’s suppose the build user is named “build”, and let’s suppose rpmdevtools has been set up normally for that user, creating a bunch of directories under /home/build/rpmbuild.

One of those is the directory containing RPM files for every package you create, called /home/build/rpmbuild/RPMS. It has one subdirectory for each architecture you create packages for, normally x86_64 and sometimes noarch too. You want to create a repository with the contents of that directory. It could hardly be easier:

createrepo /home/build/rpmbuild/RPMS

You can run that as the build user. It will create a subdirectory called repodata containing package metainformation. If you have a lot of personal packages or if you want something faster, you can replace createrepo with createrepo_c, a version of createrepo written in C that’s supposed to be much faster. For my simple use case, I barely notice any difference between the two. You’ll have to run that command every time you add or remove packages from the repository, to update their metainformation.

The final step is telling dnf there’s a repository there. That’s as easy as creating a file under /etc/yum.repos.d with information about it. I called mine localrepo.repo and it has the following contents:

[localrepo]
name=localrepo
baseurl=file:///home/build/rpmbuild/RPMS
enabled=1
gpgcheck=0
metadata_expire=60s
priority=80

The base URL mentions the path to the local directory. The repo is also enabled and its packages are not signed, so the GPG check is disabled. Metadata expires after 60 seconds and needs to be rechecked then. That’s handy so you won’t have to use dnf’s --refresh option all the time while working with your local repository. The last line contains a numeric priority value.

The lower the number, the higher the priority. The default priority is 99 according to dnf.conf(5) and that’s the priority of the official repos because they don’t set a value. If you use other non-official repositories like RPM Fusion, you’ll see they have their own priority value. You have to decide if you want your local repo to have higher or lower priority compared to others and put a numeric value there.

Going back to the rebuilt freetype package, dnf won’t insist anymore on reinstalling the official version, but it will update it if the official package version is considered more recent. Hopefully, you’ll notice font rendering has changed slightly, rebuild the package and reinstall it from your local repository.

Load comments