<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Offline-Repository on K-Life Hack | Systems Architecture &amp; DevOps</title><link>https://klifehack.com/en/tags/offline-repository/</link><description>Recent content in Offline-Repository on K-Life Hack | Systems Architecture &amp; DevOps</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Tue, 01 Sep 2026 10:17:30 +0900</lastBuildDate><atom:link href="https://klifehack.com/en/tags/offline-repository/index.xml" rel="self" type="application/rss+xml"/><item><title>HAProxy Offline Dependency Resolution and Local Repository Construction Procedure on RHEL 8</title><link>https://klifehack.com/en/p/rhel8-haproxy-offline-dnf-repository-deployment/</link><pubDate>Tue, 01 Sep 2026 10:17:30 +0900</pubDate><guid>https://klifehack.com/en/p/rhel8-haproxy-offline-dnf-repository-deployment/</guid><description>&lt;p&gt;In enterprise air-gapped environments or DMZ zones where direct connection to external networks is restricted due to security constraints, installation errors caused by missing dependent libraries are a frequent challenge when deploying the HAProxy load balancer anew. RHEL 8 adopts DNF (Dandified YUM) as its standard package management system, strongly requiring an operational design where all dependencies (Dependency Graph) are resolved and packages are acquired in advance in an online environment, and then configured as a local repository on the target verification machine.&lt;/p&gt;&#10;&lt;h2 id="extracting-packages-and-all-dependencies-in-an-online-environment"&gt;Extracting Packages and All Dependencies in an Online Environment&#10;&lt;/h2&gt;&lt;p&gt;To prepare the package set to be brought into the air-gapped network, first extract HAProxy and the shared libraries required for its runtime (&lt;code&gt;openssl-libs&lt;/code&gt;, &lt;code&gt;pcre2&lt;/code&gt;, &lt;code&gt;systemd&lt;/code&gt;, etc.) on a workstation node with internet connectivity.&lt;/p&gt;&#10;&lt;p&gt;Rather than acquiring only the main RPM, execute with a combination of the &lt;code&gt;--resolve&lt;/code&gt; and &lt;code&gt;--alldeps&lt;/code&gt; options to collect all libraries not yet installed in the target environment without omission.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf download --resolve --alldeps --destdir&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/tmp/haproxy_rpms haproxy&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="parameter-configuration-specifications"&gt;Parameter Configuration Specifications&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;--resolve&lt;/code&gt;: Analyzes the dependency tree and identifies all RPM files required for operation as download targets.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;--alldeps&lt;/code&gt;: Forces all dependent packages to be downloaded without omitting them, even if the libraries already exist on the host executing the download.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;--destdir=/tmp/haproxy_rpms&lt;/code&gt;: Outputs the downloaded RPMs collectively to the specified directory.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;When explicitly acquiring a specific version (e.g., &lt;code&gt;haproxy-2.2.0-1.el8&lt;/code&gt;), verify the list of versions in the repository and specify the version string.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Check available duplicate and older versions&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf --showduplicates list haproxy&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Explicitly download a specific version&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf download --destdir&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/tmp/haproxy_rpms haproxy-2.2.0-1.el8&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="creating-and-deploying-a-local-repository-in-an-offline-environment"&gt;Creating and Deploying a Local Repository in an Offline Environment&#10;&lt;/h2&gt;&lt;p&gt;After transferring the acquired RPMs to the target server in the air-gapped environment via USB flash drive or internal storage, initialize a local filesystem-based DNF repository.&lt;/p&gt;&#10;&lt;h3 id="1-generating-repository-metadata"&gt;1. Generating Repository Metadata&#10;&lt;/h3&gt;&lt;p&gt;Navigate to the destination directory and create XML-formatted metadata (&lt;code&gt;repodata&lt;/code&gt;) using the &lt;code&gt;createrepo&lt;/code&gt; utility.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd /tmp/haproxy_rpms&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo createrepo .&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2-configuring-the-repository-definition-file"&gt;2. Configuring the Repository Definition File&#10;&lt;/h3&gt;&lt;p&gt;Create a &lt;code&gt;.repo&lt;/code&gt; configuration file pointing to the local repository under &lt;code&gt;/etc/yum.repos.d/&lt;/code&gt;.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cat &amp;amp;lt;&amp;amp;lt; EOF | sudo tee /etc/yum.repos.d/haproxy-local.repo&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;haproxy-local&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;HAProxy Local Repository&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;baseurl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;file:///tmp/haproxy_rpms&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;enabled&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gpgcheck&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;EOF&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-executing-installation-from-the-local-repository"&gt;3. Executing Installation from the Local Repository&#10;&lt;/h3&gt;&lt;p&gt;Once configuration is complete, reference the local metadata and execute the installation.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf clean all&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install -y haproxy&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="troubleshooting"&gt;Troubleshooting&#10;&lt;/h2&gt;&lt;p&gt;Below are representative troubleshooting steps for errors caused by permissions, SELinux, and dependency mismatches during local repository operations and package installations in an offline environment.&lt;/p&gt;&#10;&lt;h3 id="1-tmp-directory-permissions-and-selinux-context-denials"&gt;1. &lt;code&gt;/tmp&lt;/code&gt; Directory Permissions and SELinux Context Denials&#10;&lt;/h3&gt;&lt;p&gt;When placing a repository under &lt;code&gt;/tmp&lt;/code&gt;, metadata read errors may occur due to SELinux access controls or system temporary file cleanup jobs (&lt;code&gt;systemd-tmpfiles&lt;/code&gt;).&lt;/p&gt;&#10;&lt;p&gt;&lt;b&gt;Example Symptoms:&lt;/b&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Error: Failed to download metadata for repo &amp;#39;haproxy-local&amp;#39;: Cannot download repomd.xml: Cannot open file&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Workaround:&lt;/b&gt;&#10;Change the repository location to a persistent directory such as &lt;code&gt;/opt/local_repos/haproxy&lt;/code&gt; and reapply the appropriate SELinux context.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mkdir -p /opt/local_repos/haproxy&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mv /tmp/haproxy_rpms/* /opt/local_repos/haproxy/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo restorecon -Rv /opt/local_repos/haproxy&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Rebuild the cache after updating &lt;code&gt;baseurl&lt;/code&gt; in &lt;code&gt;/etc/yum.repos.d/haproxy-local.repo&lt;/code&gt; to &lt;code&gt;file:///opt/local_repos/haproxy&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h3 id="2-gpg-signature-verification-error"&gt;2. GPG Signature Verification Error&#10;&lt;/h3&gt;&lt;p&gt;When &lt;code&gt;gpgcheck=1&lt;/code&gt; is set, the installation will be aborted if the public key has not been imported.&lt;/p&gt;&#10;&lt;p&gt;&lt;b&gt;Workaround:&lt;/b&gt;&#10;For local verification purposes, set &lt;code&gt;gpgcheck=0&lt;/code&gt; or import the official Red Hat GPG key in advance.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-system-verification-log-protocol"&gt;3. System Verification Log Protocol&#10;&lt;/h3&gt;&lt;p&gt;Example terminal verification commands and execution logs to confirm service status and system socket health after deployment completion.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sudo systemctl enable --now haproxy&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Created symlink /etc/systemd/system/multi-user.target.wants/haproxy.service -&amp;amp;gt; /usr/lib/systemd/system/haproxy.service.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sudo systemctl status haproxy&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;● haproxy.service - HAProxy Load Balancer&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Active: active (running) since Tue 2026-09-01 10:15:30 KST; 12s ago&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Main PID: 14820 (haproxy)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Tasks: 2 (limit: 23800)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Memory: 7.4M&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CGroup: /system.slice/haproxy.service&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├─14820 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └─14822 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ haproxy -v&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HA-Proxy version 2.2.9-3.el8 2021/08/10&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Configuration file is /etc/haproxy/haproxy.cfg&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configuration-notes"&gt;Configuration Notes&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;b&gt;Ensuring Completeness of Package Dependencies&lt;/b&gt;: When executing &lt;code&gt;dnf download --resolve --alldeps&lt;/code&gt; in a staging environment, using a node with an OS build version and minimal installation (Minimal Install) equivalent to the target environment as much as possible helps prevent missing dependent libraries.&lt;/li&gt;&#10;&lt;li&gt;&lt;b&gt;Periodic Update of Repository Indexes&lt;/b&gt;: Whenever packages are added or replaced, always execute &lt;code&gt;createrepo --update /opt/local_repos/haproxy&lt;/code&gt; to recalculate the metadata index.&lt;/li&gt;&#10;&lt;li&gt;&lt;b&gt;Alignment with Security Policies&lt;/b&gt;: In production environments, maintaining &lt;code&gt;gpgcheck=1&lt;/code&gt; and automating the checksum comparison and signature verification process for downloaded RPMs is recommended.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;</description></item></channel></rss>