Creating A Local and HTTP RedHat Yum Repository

We’re rolling out a RedHat platform for a major product delivery to a client in the next couple of weeks, which is a great chance for me to build a fresh platform using all the skills I’ve acquired and actually do things properly (TM).

We’re using RedHat Enterprise Linux 5 because this is a very critical deployment and we want an Operating System that is certified to both our hardware and software applications, something that unfortunately Ubuntu does not deliver.

The first stage of the deployment is to create our own RedHat RPM repository on the local network, so we can easily create servers.

I’m going to cover setting up 2 types of repository, initially a file system based repo and then an http based repo so that other servers can talk to the repo and snag RPMs from it.

To start with a repository is just a path with RPMs in it, regardless of file hierarchy, so we need to create this. I’m working with the RHEL 5 DVD so my first task is to simply copy the contents of the DVD on to the server’s hard drive.

Ok, now we have a lovely directory structure with over 3000 RPMs just gagging to be installed in it 😉

Next up we need to create the Yum repository metadata, to do this we first need to install a tool called createrepo. Fortunately this is on the DVD image we just copied to our hard drive so we can sneakily install it with rpm -i 😉

repomd.xml this is the file that describes the other metadata files. It is like an index file to point to the other files. It contains timestamps and checksums for the other files. This lets a client download this one, small file and know if anything else has changed. This also means that cryptographically (ex: gpg) signing this one file can ensure repository integrity.

other.xml.gz this file currently only stores the changelog data from packages. However, this file could be used for any other additional metadata that could be useful for clients.

Ok, we now have our file system based repo, so we now need to tell Yum all about it!

Yum repository information is located in /etc/yum.repos.d as a series of files, it is possible to define multiple repositories in a single file, but I prefer to limit each file to one repository as in my opinion this makes it easier to manage, especially when implementing tools like Puppet.

Our repository is a local rhel repo, so create it vi /etc/yum.repo.d/rhel-local.repo

We’ve created a repo labeled rhel-local. We’ve told Yum that the RPMs are signed using GPG, we’ve given it a name, and we’ve defined the baseurl of the repo to be a local file path!

To test we simply run yum list and you’ll see that packages are now available in the rhel-local repo!

That’s great, but we have to get on to the real task of creating a HTTP based Yum repository so we can use it to start building servers!! We’re going to serve the repo via the Apache HTTPD server so the first logical thing to do is to install it, using our new fancy pants local repo 😉

Oh god no, what is this error? Wait, that looks similar to the rpm NOKEY error we saw earlier! Relax, it’s simple!

Remember we set the repository to be GPG signed? Well, it is, but we don’t have the GPG key installed that we need to use to compare to the signings! This is easily fixable as the GPG keys came on the DVD, which we copied to the hard drive 😉

RedHat has a quirk though, a default install of most services means that the service will not start if the box is rebooted, in fact after installing an RPM of a service, like Apache it doesn’t even start the daemon! So we must do both, register the service to be started each boot and then start the server up!

Now we just need to configure Apache to use the repo we’ve previously set up!

There are an infinite number of ways to configure Apache to serve data, but I’m going to do it the simple and quick way and just use an Alias to do it. Create /etc/httpd/conf.d/repo.conf

Alias /repo/ "/var/repo/"

Now we just need to reload Apache

[rus@redhat ~]$ sudo /etc/init.d/httpd reload
Reloading httpd: [ OK ]

And we should be able to access the all important repomd.xml file with lynx :

[rus@redhat ~]$ lynx http://localhost/repo/repodata/repomd.xml

If Apache throws a 403 forbidden error error this could very well be SELinux getting in the way. If you are using SELinux you will need to change the Security Context of all the repo files so that Apache can read them!

[rus@redhat ~]$ sudo chcon -R -t httpd_sys_content_t /var/repo/

Lynx should now be able to download that file successfully.

The last thing to do now that we can retrieve files is to configure Yum to use the web based repo!

First we’re going to disable the existing local file server repo /etc/yum.repos.d/rhel-local.repo with the enabled=0 flag:

Hi, I'm Rus and after 10 years of Linux administration and software development, in September 2014 I quit my day job, sold all my stuff and moved to Thailand to live the good life.
My new website, http://www.ruspow.com shows how I'm making money online as well as what life can be like when you're not sat behind a desk and are free to make your own decisions!

thanks for the post. but if I want to have a updated “rpm” repository, what sever repository should I refer?
Tks

raspberrypi_fan

very nicely written ..to the point, no nonsense and clear as mud tutorial….

thanks.

jim

HUGE thumbs up!

Hitesh

Rus,

Thanks for this blog which is very help full me…

– Hitesh

MAtt

I just could not fix a problem with getting a working repository over http (403 errors) , then this tutuorial solved it for me, needed to run chcon to get httpd_sys_content type . Many thanks for this clearly written tutorial

Elsie

This is a very helpful post. It saved me big time. Thumbs up! Purely awesome

Freddie Boy

Like MAtt, I had 403 errors I could not figure out. ‘chcon’ did the trick. Thanks!!!!

Vimal

Hi,

Just wondering if you can help me in this scenario. Example: I have 5 Linux servers to be upgraded from RHEL 5.3 to RHEL 5.9. I don’t have RHN/Satellite. All the servers are in same subnet. Having anyone linux server as master, can I upgrade all the other servers? How should be baseurl= look like? If you get time reply.

Thanks,
Vimail

steve

hey, something not in this, but was my problem, I had to edit /etc/httpd/conf/httpd.conf and specifically change DocumentRoot and add