Many of us have faced this scenario: setting up a brand-new Linux Server, only to discover it’s a minimal setup lacking essential tools like our favorite ‘VIM’ text editor. This leads to frustration while trying to make changes without our familiar tools and coping with mismatched keyboard layouts. Even simple tasks, such as navigating directories, become tests of patience.

And for consultants, operating in networks that enforce strict network restrictions and lack accessible repositories is a common scenario.

In this blog, I’ll guide you on making installations a breeze. We can easily access basic packages from an ISO. For more specific installations, we can download required packages onto a VM using the same distribution as our target system. Feeling ambitious? We can even create an offline repository using “reposync”.

Using your installation CD as a Repository

Many of you might already be familiar with the classic trick of using the Installation ISO configured as a local repository. Thankfully for all rpm based distributions the mounting is the same:

# Create Mount point and mount iso/ sr0
$ mkdir -p  /mnt/repo
$ mount -o loop /home/user/isofile.iso /mnt/repo
# or for a physical/ mounted loop device:
$ mount /dev/sr0 /mnt/repo

From here we can just add the repositories to the newly created mount point. Here’s a step-by-step guide that covers multiple distributions:

RHEL/ OL/ Fedora/ CentOS/ Rocky:

Once the disc/ISO is mounted, variations between RPM-based distributions emerge. For instance, RHEL typically contains a single repository within the ISO. However, in Oracle Linux, you’ll find separate “AppStream” and “BaseOS” repositories. To simplify locating the correct destination for our ‘baseurl=’ parameter, executing the following command and using its output can streamline the process:

[root@test-oraclelinux ~]# find /mnt/repo/ -type f -name "repomd.xml"
# With that output we can write down the directory that holds the "repodata" directory
# Create new repository file inside /etc/yum.repos.d/
# Add the following Lines and call the file <reponame>.repo
name=AppStream from iso

name=BaseOS from iso

# Now we can clean the cache of DNF/ YUM and check if our local repo is availible
$ dnf clean all
$ dnf repolist enabled


As usual SUSE/ SLES has a very simplified way to add a iso or disc as a repository in zypper:

# We can make our lifes easier with the command "find" and look for the needed "repomd.xml"
test-suse:/home/user # find /mnt/repo/ -type f -name "repomd.xml"
# Now we can just add the repository with "ar" or "addrepo" and point to the repomd.xml including a self defined alias (e.g local-repo) at the end
$ zypper addrepo /mnt/repo/repodata/repomd.xml local-repo
# Now lets list the repositories with "lr" or "listrepo" and check if it is usable for zypper
$ zypper listrepo

Debian/ Ubuntu:

Debian and Ubuntu use a very similar, simplified way of adding repositories from iso/ disc:

# Just make sure the CD-ROM is attached/ inserted to your machine (on /dev/sr0) and then run this command:
$ sudo apt-cdrom add
# Now you can install any basic package with "apt-get install package"
# To check if the CD-Repository is availible we can run "apt-cache policy"
user@test-debian:~$ apt-cache policy
Package files:
 100 /var/lib/dpkg/status
     release a=now
 500 cdrom://[Debian GNU/Linux 12.2.0 _Bookworm_ - Official amd64 NETINST with firmware 20231007-10:28] bookworm/non-free-firmware amd64 Packages
release c=non-free-firmware,b=amd64

Download and transfer packages with all dependencies

I’ve worked for some clients that do not allow us to use any proxy nor have any kind of internet access to the Linux machines we need to setup. In such cases, offline Linux systems require configuration assistance from a similar machine (same distribution & version) with internet connectivity.

For that there is an tool for most of the package manager, to be able to only download the packages including all of their dependencies without installing them locally.

To address this, most package managers offer a tool allowing package download, including dependencies, without local installation. To utilize this functionality, we need a comparable Linux machine with internet access (for example a local VM). We can then transfer all the required packages, along with dependencies, using tools like WinSCP from the online host to our productive client-side host.

RHEL/ OL/ Fedora/ CentOS/ Rocky:

With all RPM-Based distributions there is an DNF/ YUM plugin that helps the package manager to download and resolve all dependencies automatically:

# Check if the DNF plugin is installed and availible
$ dnf list installed dnf-plugins-core 
# If the dnf-plugin-core is not installed run the following command
$ dnf install dnf-plugins-core -y
# Now we can donwload all packages and their dependencies to a local directory
$ dnf download --resolve <package-name> --destdir=/path/to/download_dir
# Now we can zip the "destdir" and scp or WinScp the archive to the offline server
$ tar -czf <archive name>.tar.gz /path/to/download_dir


As usual, we have all things/ tools we need already inside the SUSE/ SLES system. To be able to download a package including all of its dependencies, we just need “zypper” without any plugins or tools.

# With the "zypper install" command we can add an -d to download only including all dependecies. Default path is /var/cache/zypp/packages/
$ zypper in -d <package-name>
# Now we can zip the zypper cache and scp or WinScp the archive to the offline server
$ tar -czf <archive name>.tar.gz /var/cache/zypp/packages/

Debian/ Ubuntu:

Debian and Ubuntu use apt-get for the package manager. To be able to download the packages only we might use apt download, but this will have the issue that we do not get all the dependencies we need. For that we have a plugin called “aptitude”. With that we can easily download packages including all dependencies:

# First install the aptitude plugin
$ sudo apt-get install aptitude 
# Then download the needed package including all dependencies. Same as in Zypper the default download directory is the apt cache: /var/cache/apt/archives/
$ sudo aptitude --download-only install <package-name>
# Now we can zip the apt cache and scp or WinScp the archive to the offline server
$ tar -czf <archive name>.tar.gz /var/cache/apt/archives/

Using reposync (apt-mirror)

When setting up servers for a client, consistency across environments is crucial. Often, you require one or more identical servers for each environment. Establishing reproducibility is key, achieved by employing a local repository or ensuring the installation of servers with identical software configurations. However, there are situations where this isn’t possible, prompting the need for a “reposync”.

A “reposync” operation downloads all necessary packages intended for installation on a specific system (such as updates) and stores them in a designated folder. This approach enables the installation of new servers in precisely the same manner as the initial server. Moreover, streamlining this process by setting up a cronjob automates the “reposync” and establishing a simple web host facilitates sharing the “reposync” with all servers effortlessly.

RHEL/ OL/ Fedora/ CentOS/ Rocky:

Usually the command “reposync” is not available out of the box for most of the RPM-Based distributions. To install it, the only thing we need to install is the package “dnf-utils” (in the good old days before RHEL 8 “yum-utils”). So here is how we can setup a “reposync”:

# First install the needed dnf-utils package
$ dnf install -y dnf-utils
# Now create a folder where you can place all of the packages you download
$ mkdir -p /u00/reposync
# Now we can run the "reposync" command
$ reposync --newest-only --download-metadata --repoid=ol8_baseos_latest -p /u00/reposync/OracleLinux
$ reposync --newest-only --download-metadata --repoid=ol8_appstream -p /u00/reposync/OracleLinux
$ reposync --newest-only --download-metadata --repoid=ol8_UEKR6 -p /u00/reposync/OracleLinux
# Here are the examples for a RHEL Machine:
$ reposync --newest-only --download-metadata --repoid=rhel-8-for-x86_64-appstream-rpms -p /u00/reposync/RHEL
$ reposync --newest-only --download-metadata --repoid=rhel-8-for-x86_64-baseos-rpms -p /u00/reposync/RHEL

Let me break down the parameters we are using in this case:

  • –newest-only : This parameter instructs “reposync” to download only the latest versions of packages available in the repository.
  • –download-metadata : This parameter tells “reposync” to download repository metadata. Metadata includes information about available packages, their versions, dependencies, and other details. By downloading metadata, “reposync” ensures that the local repository’s metadata is synchronized with the remote repository.
  • -p or –download-path=<path> : This parameter tells “reposync” where to download the packages and metadata. If you point to a missing folder, “reposync” will create it (if the parent directory exists).

Debian/ Ubuntu:

With Debian/ Ubuntu based distributions, there is no DNF package manager and therefor we need to use an APT specific program called “apt-mirror”. This program first needs to be installed before we can use it. To setup a basic “apt-mirror” execute the following commands:

# First install the needed apt-mirror package (in some cases an "apt update" might be needed)
$ sudo apt install -y apt-mirror
# Now create a folder where you can place all of the packages you download
$ mkdir -p /u00/apt-mirror
# Other than "reposync" we need to configure all of the needed repositories inside the config file of "apt-mirror" inside /etc/apt/mirror.list
$ vi /etc/apt/mirror.list
# Add/ uncomment the following lines for a Ubuntu 22.04:
set base_path   /u00/apt-mirror
deb jammy main restricted universe multiverse
deb-src jammy main restricted universe multiverse
deb jammy-updates main restricted universe multiverse
deb-src jammy-updates main restricted universe multiverse
deb jammy-security main restricted universe multiverse
deb-src jammy-security main restricted universe multiverse
deb jammy-backports main restricted universe multiverse
deb-src jammy-backports main restricted universe multiverse

# Now we can start the mirroring process of all configured repositories (this might take a while!)
$ sudo apt-mirror

For most regular users and system administrators, especially those who do not actively develop or modify software packages, downloading source packages (“deb-src” lines) is not necessary. So to make sure you are not filling your disk for no reason comment out all “deb-src” lines.


In this blog post, I’ve covered important steps to create your own repositories using simple tools like your installation CD. This guide is helpful when your servers are offline and you need basic applications for installation. I’ve explained how to efficiently download all the necessary packages from a connected server, making it easy to transfer these packages to an offline machine for installation.

Additionally, I’ve detailed the use of specialized tools like “reposync” and “apt-mirror” for RPM and DEB-based distributions, respectively. These tools simplify managing repositories, allowing users to synchronize and copy repositories effortlessly.

As a big fan of SUSE/ SLES, I know that this important distribution is partially missing here. But the RMT (Repository Mirroring Tool) is so powerful that I’m saving it for a dedicated blog post in the future. Stay tuned for my upcoming SUSE/ SLES blogs, where I’ll explore the extensive capabilities and benefits provided by RMT.