How To Create And Install RPM Package on RHEL/CentOS/Rocky Linux


RPM stands for Red Hat package manager which is a collection of files. These files can be any like, configuration files, binary files or documentation files etc. Using RPM we can package our scripts/files for easy installation and modification in our machine. In fact we can share our build scripts with others by packaging into RPM.

In this tutorial, we will learn

  1. How to create RPM package
  2. How to build RPM package
  3. How to Install RPM package
  4. How to verify installed RPM package

How To Create And Install RPM Package on RHEL/CentOS/Rocky Linux

How To Create And Install RPM Package on RHEL / CentOS / Rocky Linux

Also Read: How to Install InfluxDB2 on Ubuntu 20.04 LTS [Step by Step]

We will first install few pre-requisite rpms for our tutorial like below. These rpms helps in building the package and perform many check on them.

[root@cyberithub:~]# yum install rpmdevtools -y
[root@cyberithub:~]# yum install rpm-build -y
[root@cyberithub:~]# yum install tree -y

We will install another rpm called rpmlint which helps in validating and checking our .spec file.

[root@cyberithub:~]# yum install rpmlint -y

To verify installed rpms, use below command.

[root@cyberithub:~]# rpm -qa | grep rpm
[root@cyberithub:~]# rpm -qa | grep tree


1. How to create RPM package

Use below command to create a RPM file tree. It will create a dir inside  ~/ path.

[root@cyberithub:~]# rpmdev-setuptree

To view created dir structure.

[root@cyberithub:~]# tree ~/rpmbuild
├── RPMS

5 directories, 0 files

Next, we will create a simple .sh file which we will then package and create a rpm of it. Below script will simply check if a network interface on a machine exist or not. Firstly, switch to the BUILD directory like below.

[root@cyberithub:~]# cd  ~/rpmbuild/BUILD

Inside it, we will create a new directory which RPM package expects and then we will place our script inside newly created directory.

[root@cyberithub BUILD]# mkdir  interface-0.0.1
[root@cyberithub BUILD]# cd interface-0.0.1
[root@cyberithub interface-0.0.1]# cat <<EOF>>
> #!/bin/bash
> if ip link show eth5 ;then
>    echo "eth5 present"
> else
>    echo "eth5 not present"
> fi

Once script is created, we will next create tar by following certain rules which RPM build package manager expects.

[root@cyberithub interface-0.0.1]# cd ..
[root@cyberithub BUILD]# tar -czf interface-0.0.1.tar.gz interface-0.0.1

Copy the tar inside SOURCES directory.

[root@cyberithub BUILD]# cp interface-0.0.1.tar.gz ../SOURCES/

Next step is to create a .spec file. Using below command we will first generate the spec template which then will be modified based on our requirements.

[root@cyberithub:~]# rpmdev-newspec interface
interface.spec created; type minimal, rpm version >= 4.11.

Move the generated spec file inside the SPEC dir of rpm build structure using below command.

[root@cyberithub:~]# mv interface.spec ~/rpmbuild/SPECS/

View the files create so far by using tree ~/rpmbuild/ command as shown below.

[root@cyberithub:~]# tree ~/rpmbuild/
├── RPMS
│   └── interface.tar.gz
│   └── interface.spec

5 directories, 2 files

Since we are building a RPM to package a .sh file, will modify our spec file accordingly. We will be using mostly macros to server fulfill the requirement.

[root@cyberithub RPMS]# cd ~/rpmbuild/SPECS/
[root@cyberithub RPMS]# vi interface.spec
Name:           interface
Version:        0.0.1
Release:        1%{?dist}
Summary:        Simple Network Interface Check Script
BuildArch:      noarch
License:        GPL
Source0:        %{name}-%{version}.tar.gz
Requires:       bash
Session on RPM build
%setup -q
rm -rf %{buildroot}
mkdir -p %{buildroot}/tmp
cp %{name}.sh %{buildroot}/tmp
* Tue May 31 2016 Hub CyberITHub <> - 0.1-1
First RPM package

We can perform a check on the created .spec file using below command.

[root@cyberithub SPECS]# rpmlint ~/rpmbuild/SPECS/interface.spec
/root/rpmbuild/SPECS/interface.spec: W: no-%build-section
/root/rpmbuild/SPECS/interface.spec: W: invalid-url Source0: interface-0.0.1.tar.gz
0 packages and 1 specfiles checked; 0 errors, 2 warnings.

There are no errors reported, just warnings which are expected.


2. How to build RPM package

Now that we have our spec file created, we will next build the package. To do so, execute the below command.

[root@cyberithub SPECS]# rpmbuild -bb interface.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.FIdQga
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd /root/rpmbuild/BUILD
+ rm -rf interface-0.0.1
+ /usr/bin/gzip -dc /root/rpmbuild/SOURCES/interface-0.0.1.tar.gz
+ /usr/bin/tar -xf -
+ '[' 0 -ne 0 ']'
+ cd interface-0.0.1
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.ytY77e
+ umask 022
+ cd /root/rpmbuild/BUILD
+ '[' /root/rpmbuild/BUILDROOT/interface-0.0.1-1.el7.x86_64 '!=' / ']'
+ rm -rf /root/rpmbuild/BUILDROOT/interface-0.0.1-1.el7.x86_64
++ dirname /root/rpmbuild/BUILDROOT/interface-0.0.1-1.el7.x86_64
+ mkdir -p /root/rpmbuild/BUILDROOT
+ mkdir /root/rpmbuild/BUILDROOT/interface-0.0.1-1.el7.x86_64
+ cd interface-0.0.1
+ rm -rf /root/rpmbuild/BUILDROOT/interface-0.0.1-1.el7.x86_64
+ mkdir -p /root/rpmbuild/BUILDROOT/interface-0.0.1-1.el7.x86_64/tmp
+ cp /root/rpmbuild/BUILDROOT/interface-0.0.1-1.el7.x86_64/tmp
+ '[' noarch = noarch ']'
+ case "${QA_CHECK_RPATHS:-}" in
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
+ /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars

Processing files: interface-0.0.1-1.el7.noarch
Provides: interface = 0.0.1-1.el7
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/interface-0.0.1-1.el7.x86_64
Wrote: /root/rpmbuild/RPMS/noarch/interface-0.0.1-1.el7.noarch.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.EP8Cqp

+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd interface-0.0.1
+ /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/interface-0.0.1-1.el7.x86_64
+ exit 0

Once the build process is success, we will have the directory structure like below.

[root@cyberithub RPMS]# tree ~/rpmbuild/
│   └── interface-0.0.1
│       └──
├── RPMS
│   └── noarch
│       └── interface-0.0.1-1.el7.noarch.rpm
│   └── interface-0.0.1.tar.gz
│   └── interface.spec

8 directories, 4 files

If you notice, a rpm is created inside RPMS folder. We now have successfully created our first rpm package.


3. How to Install RPM Package

Finally let’s install our created package to verify if it’s getting installed and doing the required job. For installation, we will use -U option instead of -i due to the fact that if the lower version of this package is already installed then it will upgrade the package to the latest version and remove all the other versions In case none of the versions are installed then it will simply install this package. More on rpm command man page.

[root@cyberithub:~]# rpm -Uvh interface-0.0.1-1.el7.noarch.rpm
Preparing...                          ################################# [100%]
Updating / installing...
1:interface-0.0.1-1.el7            ################################# [100%]


4. How to verify installed RPM package

Once rpm package is installed, you can use rpm -qa | grep interface command to verify the installation.

[root@cyberithub:~]# rpm -qa | grep interface

Then switch to /tmp directory where this package is suppose to copy the script and verify by using ll command.

[root@cyberithub tmp]# pwd
[root@cyberithub tmp]# ll
total 8
-rw-r--r--. 1 root root   98 Jan 16 00:12

We have successfully created and installed the RPM package.

Leave a Comment