Distributions Reference¶
A distribution in Repod maps to a target operating system release. When you
upload a package, you assign it to a distribution. Packages are only visible to
clients (apt, dnf, zypper, apk) configured for that specific distribution.
Which distributions are available depends on REPO_FORMAT (apt, rpm, apk,
both, or all) — see Getting Started — Step 2.
APT distributions (.deb)¶
Active when REPO_FORMAT is apt, both, or all.
| Codename | OS | Architecture | Component |
|---|---|---|---|
jammy |
Ubuntu 22.04 LTS | amd64 |
main |
noble |
Ubuntu 24.04 LTS | amd64 |
main |
focal |
Ubuntu 20.04 LTS | amd64 |
main |
bookworm |
Debian 12 | amd64 |
main |
APT repository structure¶
For each distribution, reprepro manages the following tree under /repos/dists/,
served by depot-apt:
/repos/dists/
└── jammy/
├── InRelease ← GPG-signed index (verified by apt clients)
├── Release
├── Release.gpg
└── main/
├── binary-amd64/
│ ├── Packages
│ ├── Packages.gz
│ └── Packages.xz
└── Contents-amd64.gz
APT client configuration¶
# Import the signing key
curl -fsSL http://YOUR_HOST:80/repos/gpg.key \
| gpg --dearmor \
| sudo tee /etc/apt/trusted.gpg.d/repod.gpg > /dev/null
# Add the source
echo "deb http://YOUR_HOST:80/repos jammy main" \
| sudo tee /etc/apt/sources.list.d/repod.list
sudo apt update
RPM distributions (.rpm)¶
Active when REPO_FORMAT is rpm, both, or all.
| Codename | OS | Architecture | Package manager | Grype distro ID |
|---|---|---|---|---|
almalinux8 |
AlmaLinux 8 | x86_64 |
dnf | almalinux:8 |
almalinux9 |
AlmaLinux 9 | x86_64 |
dnf | almalinux:9 |
rocky8 |
Rocky Linux 8 | x86_64 |
dnf | rockylinux:8 |
rocky9 |
Rocky Linux 9 | x86_64 |
dnf | rockylinux:9 |
centos-stream9 |
CentOS Stream 9 | x86_64 |
dnf | centos:9 |
oraclelinux8 |
Oracle Linux 8 | x86_64 |
dnf | oraclelinux:8 |
fedora |
Fedora 42 | x86_64 |
dnf | fedora:42 |
opensuse-leap-15.6 |
openSUSE Leap 15.6 | x86_64 |
zypper | opensuse/leap:15.6 |
opensuse-tumbleweed |
openSUSE Tumbleweed (rolling) | x86_64 |
zypper | opensuse/tumbleweed:latest |
Grype distro ID
The Grype distro ID is the identifier passed to grype when scanning
a package for that distribution. It determines which CVE advisories are
considered relevant — a CVE patched in AlmaLinux 9 may still be open in
AlmaLinux 8, so the distro ID ensures accurate matching.
RPM repository structure¶
For each distribution, createrepo_c manages the following tree under /repos/rpm/,
served by depot-rpm:
/repos/rpm/
└── almalinux9/
└── x86_64/
├── repodata/
│ ├── repomd.xml ← Main index
│ ├── repomd.xml.asc ← GPG detached signature
│ ├── primary.xml.gz ← Package metadata
│ ├── filelists.xml.gz
│ └── other.xml.gz
└── *.rpm ← Package binaries
DNF / YUM client configuration¶
[repod-almalinux9]
name=Repod Private Repository — AlmaLinux 9
baseurl=http://YOUR_HOST:8080/repos/almalinux9/x86_64/
enabled=1
gpgcheck=1
gpgkey=http://YOUR_HOST:8080/repos/gpg.key
repo_gpgcheck=0
Zypper client configuration (openSUSE)¶
sudo zypper addrepo \
--gpgcheck \
http://YOUR_HOST:8080/repos/opensuse-leap-15.6/x86_64/ \
repod
sudo rpm --import http://YOUR_HOST:8080/repos/gpg.key
sudo zypper refresh repod
APK distributions (Alpine .apk)¶
Active when REPO_FORMAT is apk or all.
| Codename | OS | Architecture |
|---|---|---|
alpine3.18 |
Alpine Linux 3.18 | x86_64 |
alpine3.19 |
Alpine Linux 3.19 | x86_64 |
alpine3.20 |
Alpine Linux 3.20 | x86_64 |
alpine3.21 |
Alpine Linux 3.21 | x86_64 |
APK repository structure¶
apk index manages the following tree under /repos/apk/, served by depot-apt
under /apk/:
/repos/apk/
└── alpine3.20/
└── main/
└── x86_64/
├── APKINDEX.tar.gz ← Signed package index
└── *.apk ← Package binaries
APK client configuration¶
# Import the signing key
curl -fsSL http://YOUR_HOST:80/apk/repod.rsa.pub \
-o /etc/apk/keys/repod.rsa.pub
# Add the repository
echo "http://YOUR_HOST:80/apk/alpine3.20/main" \
| sudo tee -a /etc/apk/repositories
sudo apk update
Adding a distribution¶
Distributions are initialized automatically at first startup
(auto_init_distributions()), for every format enabled by REPO_FORMAT. To
re-initialize manually (e.g. after restoring a backup without the on-disk
distribution trees):
Modifying the supported codename list
The codenames above are hard-coded in services/distributions_apt.py,
services/distributions_rpm.py, and services/distributions_apk.py. Adding
an unsupported codename requires editing the relevant source file and
rebuilding the backend-api image, then calling /api/v1/distributions/init.
This is intentional — it prevents accidental distribution sprawl in production.
Distribution promotion¶
Repod supports promoting a package from one distribution to another without
re-uploading or re-scanning — the CVE decision and justification are preserved.
The promotion endpoint copies the package binary and re-runs reprepro includedeb
(APT), createrepo_c --update (RPM), or rebuilds APKINDEX.tar.gz (APK) in the
target distribution.
curl -X POST http://localhost:8000/api/v1/distributions/promote \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"package":"mypackage","from_dist":"jammy","to_dist":"noble"}'
Role required
Promotion requires the maintainer or admin role.
Distribution migration¶
To migrate all packages from one distribution to another (useful when upgrading your OS baseline):
curl -X POST http://localhost:8000/api/v1/distributions/migrate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"from_dist":"focal","to_dist":"jammy"}'
Migration does not remove the source
The source distribution remains intact after migration. Remove packages manually if needed.