This Blog is about a own Repository server for RHEL 8, Blogs for Repository Server for AlmaLinux, Oracle Linux, Rocky Linux, OpenSuse LEAP, SLES 15 and Debian 11 will follow.

The base is a minimal installation.
I have added EPEL and RPMFusion, may be that Desktpp systems also needed to be updated or systems with packages from EPEL.

$ [root@rhel-8-repo ~]# cat /etc/os-release 
$ NAME="Red Hat Enterprise Linux"
$ VERSION="8.6 (Ootpa)"
$ ID="rhel"
$ ID_LIKE="fedora"
$ VERSION_ID="8.6"
$ PLATFORM_ID="platform:el8"
$ PRETTY_NAME="Red Hat Enterprise Linux 8.6 (Ootpa)"
$ ANSI_COLOR="0;31"
$ CPE_NAME="cpe:/o:redhat:enterprise_linux:8::baseos"
$ HOME_URL="https://www.redhat.com/"
$ DOCUMENTATION_URL="https://access.redhat.com/documentation/red_hat_enterprise_linux/8/"
$ BUG_REPORT_URL="https://bugzilla.redhat.com/"
$ 
$ REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8"
$ REDHAT_BUGZILLA_PRODUCT_VERSION=8.6
$ REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
$ REDHAT_SUPPORT_PRODUCT_VERSION="8.6"
[$ root@rhel-8-repo ~]# 

As any RHEL Systems that this will work it is madatory that the system is attached to a subscription.

[root@rhel-8-repo ~]# subscription-manager register
Registering to: subscription.rhsm.redhat.com:443/subscription
Username: XXXXXXXXXXXXXXXXXX
Password: 
The system has been registered with ID: XXXXXXXXXXX
The registered system name is: rhel-8-repo.localdomain
[root@rhel-8-repo ~]# 

Now we can add EPEL and RPMFusion, first ist EPEL, it is required for RPMFusion.
For EPEL we need to enable codeready-builder first.

root@rhel-8-repo ~]# subscription-manager repos --enable codeready-builder-for-rhel-8-$(arch)-rpms
Repository 'codeready-builder-for-rhel-8-x86_64-rpms' is enabled for this system.
[root@rhel-8-repo ~]# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

Now we can add RPMFusion.

root@rhel-8-repo ~]# dnf install --nogpgcheck https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E %rhel).noarch.rpm
root@rhel-8-repo ~]# dnf install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-$(rpm -root@rhel-8-repo ~]# E %rhel).noarch.rpm

I’m using NGINX as HTTP service, and we need yum-utils createrepo_c for the sync functionality, so we need to install them.

root@rhel-8-repo ~]# dnf install nginx yum-utils createrepo_c

For synchronizig repositories I have written a script where the Relase number can be given as parameter.
The reason is that sometimes it is required having more than one Release availiable. We alo need to know which repositories are active.

[root@rhel-8-repo /]# dnf repolist
Updating Subscription Management repositories.
repo id                                                                                                                              repo name
codeready-builder-for-rhel-8-x86_64-rpms                                                                                             Red Hat CodeReady Linux Builder for RHEL 8 x86_64 (RPMs)
epel                                                                                                                                 Extra Packages for Enterprise Linux 8 - x86_64
epel-modular                                                                                                                         Extra Packages for Enterprise Linux Modular 8 - x86_64
rhel-8-for-x86_64-appstream-rpms                                                                                                     Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs)
rhel-8-for-x86_64-baseos-rpms                                                                                                        Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs)
rpmfusion-free-updates                                                                                                               RPM Fusion for EL 8 - Free - Updates
rpmfusion-nonfree-updates                                                                                                            RPM Fusion for EL 8 - Nonfree - Updates
[root@rhel-8-repo /]#

With this information we can write a sync sript.

[root@rhel-8-repo /]# cat /opt/reposync/reposync.sh 
##############################################
# Synchronisation of RHEL Repositories       #
# By Karsten Lenz dbi-services sa 2022.06.29 #
##############################################

#!/bin/bash

echo "Synchronisation of RHEL Repositores"
echo ""

# Help
function printHelp() {
  printf "Usage:\n"
  printf "${progName} [OPTION]\n\n"
  printf "Options:\n"
  printf "\t -v <RHEL Version>\t\tRHEL Release (required)\n"
  printf "\t -h <Help>\t\t\tprints this help\n"
}

# Select Options
while getopts v:h option 2>/dev/null
do
  case "${option}"
  in
  v) VERSION=${OPTARG};;
  h) printHelp; exit 2;;
  *) printf "Unsupported option or parameter value missing '$*'\n";
     printf "Run ${progName} -h to print help\n"; exit 1;;
  esac
done
# Extract Major Release
MAJOR=${VERSION:0:1}

# Set RHEL RELEASE to sync
printf "Set Release to sync"
subscription-manager release --set=$VERSION && rm -rf /var/cache/dnf

# SYNC BASE-OS, APPSTREAM, Codeready, EPEL and rpmfusion
if [ $MAJOR == '8' ]
then
    	printf "Sync Base OS "
        reposync -p /usr/share/nginx/html/$MAJOR/$VERSION --download-metadata --newest-only --delete --repoid=rhel-8-for-x86_64-baseos-rpms 
        printf "Sync Appstream "
        reposync -p /usr/share/nginx/html/$MAJOR/$VERSION --download-metadata --newest-only --delete --repoid=rhel-8-for-x86_64-appstream-rpms
        printf "Sync Codeready "
        reposync -p /usr/share/nginx/html/$MAJOR/$VERSION --download-metadata --newest-only --delete --repoid=codeready-builder-for-rhel-8-x86_64-rpms
        printf "Sync EPEL 8 "
        reposync -p /usr/share/nginx/html/$MAJOR --download-metadata --newest-only --delete --repo=epel 
        printf "Sync EPEL 8 Modular "
        reposync -p /usr/share/nginx/html/$MAJOR --download-metadata --newest-only --delete --repoid=epel-modular 
        printf "Sync rpmfusion-free "
        reposync -p /usr/share/nginx/html/$MAJOR --download-metadata --newest-only --delete --repoid=rpmfusion-free-updates
        printf "Sync rpmfusion-nonfree "
        reposync -p /usr/share/nginx/html/$MAJOR --download-metadata --newest-only --delete --repoid=rpmfusion-nonfree-updates
fi
[root@rhel-8-repo /]# 

EPEL and RPMFusion doesn’t know Minor Realeases, so there is only one Repository for all RHEL 8 Versions.
That is the reason to store the Repositories only under the extracted Major Release number.

Some explanations, –newest-only dowloads only the newest packages per-repo, –delete will delete local packages no longer present in the repository.
The switch -v means the version for which the local repository should be created, so it is 8.5 for 8.5 or 8.6 for 8.6, so there can be a local repository for each release which is locally used with only one script.

The shell script has a help function.

[root@rhel-8-repo reposync]# sh reposync.sh -h
Synchronisation of RHEL Repositores

Usage:
 [OPTION]

Options:
	 -v <RHEL Version>		RHEL Release (required)
	 -h <Help>			prints this help
[root@rhel-8-repo reposync]# 

Running for RHEL 8.6, the subscriptionmanager relaese command will set the Release to sync.

[root@rhel-8-repo reposync]# sh reposync.sh -v 8.6

The sync requires about 66GB with the parameters –newest-only and –delete, 21GB for RHEL 8.6, 18GB for RHEL 8.5, 13GB for RHEL 8.4, 13GB for EPEL and 1.4GB for RPMFusion.

[root@rhel-8-repo 8]# du -sh *
13G	8.4
18G	8.5
21G	8.6
13G	epel
1.1G	epel-modular
297M	rpmfusion-free-updates
1.1G	rpmfusion-nonfree-updates
[root@rhel-8-repo 8]# 

For configuration of NGINX we need to open the firewall port 80 and 443 first (http and https).

[root@rhel-8-repo /]# firewall-cmd --zone=public --permanent --add-service=http
success
[root@rhel-8-repo /]# firewall-cmd --zone=public --permanent --add-service=https
success
[root@rhel-8-repo /]# firewall-cmd --reload
success

I have adapted the originally nginx.conf, I have replaced the server section with my settings:

[root@rhel-8-repo ~]# cat /etc/nginx/nginx.conf
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
	listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html/;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                allow all;
                sendfile on;
                sendfile_max_chunk 1m;
                autoindex on;
                autoindex_exact_size off;
                autoindex_format html;
                autoindex_localtime on;
        }
	  error_page 404 /404.html;
            location = /40x.html {
        }

	  error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }


#    server {
#        listen       80 default_server;
#        listen       [::]:80 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers PROFILE=SYSTEM;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

[root@rhel-8-repo ~]# 

The next topic is SE Linux, when it is set to enforcing we need to set permissions and restart nginx.

[root@rhel-8-repo /]# chcon -Rt httpd_sys_content_t /usr/share/nginx/html/repo/
[root@rhel-8-repo /]# setfacl -R -m u:nginx:rwx /usr/share/nginx/html/repo/
[root@rhel-8-repo /]# systemctl restart nginx

A Repository Server for three RHEL 8 Releases including EPEL and RPMFusion.