Build local repositories for RPM, APT, and pacman so you can distribute internal packages without relying on external mirrors. Generate the metadata artifacts clients need to query and install packages like a standard repo.
You need to host and maintain local package repositories for custom software. Your task is to stage packages into the right directory layout and generate the metadata that RPM-based, Debian-based, and Arch-based clients expect.
Local repos are common in locked-down environments, air-gapped networks, and internal release pipelines. The job is mostly “put packages in the right place” plus “generate index files correctly,” then validate client behavior.
.rpm packages.
createrepo.
.deb packages.
dpkg-scanpackages and compress it to
Packages.gz.
repo-add.
mkdir -p /var/www/html/repo && cp *.rpm /var/www/html/repo
Put all RPM artifacts under a single repo root (often web-served). Metadata generation assumes packages are already present.
# Confirm packages are present:
ls -1 /var/www/html/repo
createrepo /var/www/html/repo
This generates repodata/ and the metadata files
yum/dnf read when they query the repo.
Spawning worker 0 with 1 pkgs
Workers finished
Saving Primary metadata
Repo created successfully.
mkdir -p /srv/aptrepo && cp *.deb /srv/aptrepo
This stages .deb packages. Next you generate the
index file apt reads when it searches for packages.
# Confirm packages are present:
ls -1 /srv/aptrepo
dpkg-scanpackages /srv/aptrepo /dev/null | gzip -9 > /srv/aptrepo/Packages.gz
This produces a minimal Packages index and writes
it as Packages.gz, which is common for small
local repos.
# Confirm the index exists:
ls -l /srv/aptrepo/Packages.gz
repo-add myrepo.db.tar.gz *.pkg.tar.zst
This creates or updates the pacman repository database and indexes all matching packages in the current directory.
:: Creating 'myrepo.db.tar.gz' database...
:: Adding package 'custompkg-1.0-1-x86_64.pkg.tar.zst'
Repo index updated.
Confirm the repo root is reachable over the chosen transport. If you are serving over HTTP, verify the web server is running, the path is correct, and the client repo file points at the right URL.
The client sources entry must point at the repo root and the package index must be in the expected location. Validate the repo path and regenerate the index after any package changes.
repo-add
expects Arch packages like
*.pkg.tar.zst
. Verify you are in the directory containing those packages
and the glob matches real files.
Repo metadata is not automatic. Re-run the metadata generation command after adding or removing packages and re-test client queries.
Remove the staged repo directories if you do not need to keep them. If this is a lab VM, cleanup returns the system to a clean baseline and prevents old metadata from confusing later runs.
sudo rm -rf /var/www/html/repo
sudo rm -rf /srv/aptrepo
rm -f myrepo.db.tar.gz myrepo.files.tar.gz
Repo directories and generated index files are removed, and subsequent runs start from an empty baseline.
mkdir -p <dir>
: Create a directory path (including parents) if it does not exist.
-p
: Create parent directories as needed and do not error if the directory exists.
cp *.rpm <dir>
: Copy RPM artifacts into a repo directory.
*.rpm
: Glob matching RPM package files in the current directory.
createrepo <repo_dir>
: Generate RPM repository metadata under <repo_dir>/repodata/.
repodata/
: Metadata directory read by yum/dnf clients.
cp *.deb <dir>
: Copy Debian packages into a repo directory.
*.deb
: Glob matching Debian package files in the current directory.
dpkg-scanpackages <dir> /dev/null | gzip -9 > <dir>/Packages.gz
: Build and compress a minimal APT package index.
|
: Pipe output from the left command into the right command.
gzip -9
: Compress with maximum compression.
Packages.gz
: Common compressed package index consumed by apt clients.
repo-add <repo.db.tar.gz> *.pkg.tar.zst
: Create or update a pacman repository database.
*.pkg.tar.zst
: Glob matching Arch package files in the current directory.
<repo.db.tar.gz>
: Repo database file read by pacman when configured as a repository.
rm -rf <path>
: Remove files/directories recursively (dangerous).
-r
: Remove directories and their contents recursively.
-f
: Force removal without prompting (ignore missing files).