Skip to content
Search AlmaLinux

    Browse this documentation

    AlmaLinux 9: installing packages without internet

    Executed in an almalinux:9 container (AlmaLinux 9.8, aarch64, dnf 4.14.0): installing createrepo_c, dnf install --downloadonly --destdir=… tree, rpm -qp --qf for the package architecture, createrepo_c, writing a local repo and running --disablerepo="*" --enablerepo=local-offline install tree, rpm -q tree, plus reproducing “install another package after downloading”. Log: plans/content-expansion/evidence/logs/alma-offline-updates.log.

    Full dependency resolution, GPG signature verification and real network isolation were not tested here and are labelled accordingly.

    Terminal window
    uname -m
    rpm -qp --qf "%{NAME} %{ARCH} %{VERSION}\n" /srv/off2/*.rpm
    aarch64
    tree aarch64 1.8.0

    The most common offline failure is not a missing repository but an architecture or major-version mismatch: packages fetched as x86_64 cannot be installed on an aarch64 host. Compare uname -m with rpm -qp before anything else.

    Terminal window
    sudo dnf -y install --downloadonly --destdir=/srv/off2 tree
    ls /srv/off2
    tree-1.8.0-10.el9.aarch64.rpm

    Do not install anything else right after this. Observed here: running dnf -y install wget next left /srv/off2 empty, because dnf cleaned the staging directory after the following successful transaction. Install tooling such as createrepo_c first, then run --downloadonly.

    Step 3: build metadata and point dnf at the directory

    Section titled “Step 3: build metadata and point dnf at the directory”
    Terminal window
    sudo createrepo_c /srv/off2
    printf '[local-offline]\nname=Local offline\nbaseurl=file:///srv/off2\nenabled=1\ngpgcheck=0\n' \
    | sudo tee /etc/yum.repos.d/local-offline.repo
    sudo dnf clean all

    createrepo_c writes repodata/, which is what makes the directory a repository; without it a pile of rpms only yields No match for argument.

    Step 4: install with only the local source enabled

    Section titled “Step 4: install with only the local source enabled”
    Terminal window
    sudo dnf -y --disablerepo="*" --enablerepo=local-offline install tree
    rpm -q tree
    Installed:
    tree-1.8.0-10.el9.aarch64
    Complete!
    tree-1.8.0-10.el9.aarch64

    On an isolated host every other repo is unreachable, so --disablerepo="*" keeps dnf from waiting on timeouts.

    Step 5: verify offline (more important than “it installed”)

    Section titled “Step 5: verify offline (more important than “it installed”)”
    Terminal window
    rpm -q tree
    rpm -V tree
    dnf --disablerepo="*" --enablerepo=local-offline repoquery --requires tree | head

    rpm -q prints a version, rpm -V prints nothing (files unmodified), and the dependency query returns output. All three must pass. Whether dependencies are truly satisfied depends on the actual install: tree has none here, but packages such as nginx require their dependencies to have been downloaded too.

    • Wrong architecture: run uname -m before downloading; aarch64 and x86_64 packages are not interchangeable;
    • Installing something before building the repo: the staging directory is cleaned (observed here); order is tooling → download → createrepo;
    • Leaving gpgcheck=0 in production: carry AlmaLinux’s GPG key and use gpgcheck=1 with a local gpgkey=file://.

    Prerequisite: connected host A and isolated host B, same architecture, both AlmaLinux 9.

    Terminal window
    # A
    sudo dnf -y install createrepo_c
    sudo dnf -y install --downloadonly --destdir=/srv/off nginx
    sudo createrepo_c /srv/off
    tar -C /srv -czf off.tgz off
    # B
    sudo tar -C /srv -xzf off.tgz
    # point local-offline.repo at /srv/off, then:
    sudo dnf -y --disablerepo="*" --enablerepo=local-offline install nginx

    Checks:

    1. rpm -q nginx → prints a version
    2. rpm -V nginx → no output
    3. dnf --disablerepo="*" --enablerepo=local-offline repoquery --requires nginx | wc -l → same count as dnf repoquery --requires nginx | wc -l on host A

    常见问题

    Why does dnf say No match when the rpm is in the directory?

    Usually because there is no repodata: the directory is just a folder. Run createrepo_c in it, then dnf clean all so dnf re-reads the metadata.

    The downloaded files disappeared after a while?

    In this test, running any successful dnf transaction afterwards (installing wget, for example) cleaned the staging directory. Install tools such as createrepo_c first, then run --downloadonly.

    Should gpgcheck stay enabled on an isolated host?

    Yes. Bring AlmaLinux's GPG public key along and set gpgcheck=1 with gpgkey=file:///...; keeping gpgcheck=0 long term drops signature verification.