Client Setup¶
Configure machines to install packages from your Repod repository.
Prerequisites¶
- The Repod repository server is running and accessible from the client machine
- At least one package has been successfully uploaded and published
- The repository's GPG public key is available (find it in Settings β GPG)
APT clients (Debian / Ubuntu)¶
Step 1 β Import the GPG signing key¶
The APT client verifies the repository's InRelease file signature. Import the
signing key once per machine:
Step 2 β Add the APT source¶
# Replace 'jammy' with your target distribution codename
echo "deb http://YOUR_HOST:80/repos jammy main" \
| sudo tee /etc/apt/sources.list.d/repod.list
Step 3 β Update and install¶
Verify the setup¶
# Check that the repo is recognised
apt-cache policy mypackage
# Should show "http://YOUR_HOST:80/repos jammy/main" as a candidate
Multiple distributions¶
/etc/apt/sources.list.d/repod.list
# Ubuntu 22.04 packages
deb http://YOUR_HOST:80/repos jammy main
# Ubuntu 24.04 packages (if you maintain separate packages per release)
deb http://YOUR_HOST:80/repos noble main
Ansible role¶
configure-repod.yml
---
- name: Configure Repod APT repository
hosts: all
become: true
tasks:
- name: Import Repod GPG key
ansible.builtin.get_url:
url: "http://YOUR_HOST:80/repos/gpg.key"
dest: /tmp/repod.asc
- name: Convert and install key
ansible.builtin.shell: |
gpg --dearmor < /tmp/repod.asc > /etc/apt/trusted.gpg.d/repod.gpg
- name: Add APT source
ansible.builtin.apt_repository:
repo: "deb http://YOUR_HOST:80/repos {{ ansible_distribution_release }} main"
filename: repod
state: present
update_cache: yes
RPM clients β DNF (AlmaLinux / RHEL / Rocky / Fedora)¶
Step 1 β Import the GPG signing key¶
Verify the key was imported:
Step 2 β Create the repo file¶
/etc/yum.repos.d/repod.repo
[repod]
name=Repod Private Repository
baseurl=http://YOUR_HOST:80/repos/almalinux9/x86_64/
enabled=1
gpgcheck=1
gpgkey=http://YOUR_HOST:80/repos/gpg.key
repo_gpgcheck=0
metadata_expire=300
repo_gpgcheck=0
Set repo_gpgcheck=0 unless you have signed repomd.xml with a key that
DNF can verify separately. The package-level gpgcheck=1 is sufficient for
most deployments.
Step 3 β Install packages¶
# Refresh metadata
sudo dnf makecache --repo=repod
# Install a package
sudo dnf install mypackage
# List available packages from Repod only
sudo dnf list available --repo=repod
Distribution-specific baseurl¶
| Distribution | baseurl |
|---|---|
| AlmaLinux 8 | http://YOUR_HOST:80/repos/almalinux8/x86_64/ |
| AlmaLinux 9 | http://YOUR_HOST:80/repos/almalinux9/x86_64/ |
| Rocky Linux 8 | http://YOUR_HOST:80/repos/rocky8/x86_64/ |
| Rocky Linux 9 | http://YOUR_HOST:80/repos/rocky9/x86_64/ |
| CentOS Stream 9 | http://YOUR_HOST:80/repos/centos-stream9/x86_64/ |
| Fedora 42 | http://YOUR_HOST:80/repos/fedora/x86_64/ |
| openSUSE Leap 15.6 | http://YOUR_HOST:80/repos/opensuse-leap-15.6/x86_64/ |
Ansible role (DNF)¶
configure-repod-rpm.yml
---
- name: Configure Repod RPM repository
hosts: all
become: true
tasks:
- name: Import Repod GPG key
ansible.builtin.rpm_key:
key: "http://YOUR_HOST:80/repos/gpg.key"
state: present
- name: Add Repod repository
ansible.builtin.yum_repository:
name: repod
description: Repod Private Repository
baseurl: "http://YOUR_HOST:80/repos/{{ ansible_distribution | lower }}{{ ansible_distribution_major_version }}/x86_64/"
enabled: yes
gpgcheck: yes
gpgkey: "http://YOUR_HOST:80/repos/gpg.key"
state: present
RPM clients β Zypper (openSUSE Leap)¶
Step 1 β Add the repository¶
sudo zypper addrepo \
--name "Repod Private Repository" \
--gpgcheck \
http://YOUR_HOST:80/repos/opensuse-leap-15.6/x86_64/ \
repod
Step 2 β Import the GPG key¶
Step 3 β Install packages¶
Authenticated access (API tokens)¶
If your Repod instance requires authentication to download packages (not the default for the repository Nginx, but possible via reverse proxy rules), use HTTP Basic Auth or a token in the request header.
CI/CD configuration¶
.github/workflows/install.yml
- name: Configure Repod repository (APT)
run: |
curl -fsSL http://${{ secrets.REPOD_HOST }}/repos/dists/jammy/InRelease \
| gpg --dearmor \
| sudo tee /etc/apt/trusted.gpg.d/repod.gpg > /dev/null
echo "deb http://${{ secrets.REPOD_HOST }}/repos jammy main" \
| sudo tee /etc/apt/sources.list.d/repod.list
sudo apt update
sudo apt install mypackage
.gitlab-ci.yml
install:
before_script:
- |
curl -fsSL http://${REPOD_HOST}/repos/dists/jammy/InRelease \
| gpg --dearmor \
| tee /etc/apt/trusted.gpg.d/repod.gpg > /dev/null
echo "deb http://${REPOD_HOST}/repos jammy main" \
> /etc/apt/sources.list.d/repod.list
apt-get update -qq
script:
- apt-get install -y mypackage
Troubleshooting¶
| Problem | Likely cause | Fix |
|---|---|---|
NO_PUBKEY on apt update |
GPG key not imported or expired | Re-run the key import command |
404 Not Found on apt update |
Wrong distribution codename | Check the codename in sources.list |
GPG key retrieval failed on dnf install |
Key not imported | Run rpm --import ... |
| Package version is stale | Metadata cache too long | dnf makecache or apt update |
HTTPS required by policy |
Internal policy | Add reverse proxy with TLS; see reverse proxy guide |