Host Debian Packages with Reprepro

This guide sets up an apt repository with reprepro that serves the CPM Lab Debian packages, like https://cpm.lrt.unibw.de/apt. The repository serves Ubuntu 24.04 (noble, ROS2 Jazzy) and Ubuntu 22.04 (jammy, ROS2 Humble), each for amd64 and arm64.

Run all gpg and reprepro commands as the same user (the user that owns /srv/repo), without sudo; otherwise they do not share the keyring.

GPG Key Pairs

To sign and verify your packages, you need to create GPG key pairs.

Generating a GPG Key

Run the following command to generate your key:

gpg --full-generate-key

Follow the prompts to choose the key type, key size, expiration date, and provide your name and email address. Remember the passphrase you choose.

🎉 Congratulations! You have successfully created a GPG key pair.

To find your key ID, run:

gpg --list-public-keys --with-subkey-fingerprint

You’ll see output like this:

pub   rsa4096 2010-09-23 [SC]
E123D55E623D56323D65E123655E623D563D5831
uid           [ultimate] Max Mustermann (RWTH) <max@rwth-aachen.de>
sub   rsa4096 2010-09-23 [E]
F24957412415744F1495F149571F2495F2495714

Use the long hexadecimal number under pub as your GPG key ID. It will be referred to as <your-gpg-key-id> in the following steps.

For more advanced use, subkeys may be preferable. See the GPG documentation for more details. This guide uses the primary key for simplicity.

Exporting the GPG Key

To share the public key with other machines:

gpg --export <your-gpg-key-id> > whatever.key

Setting Up the Repository

  1. Install reprepro

sudo apt-get install reprepro
  1. Create Repository Directory

mkdir -p /srv/repo/conf
  1. Configure the Repository

Navigate to the configuration directory:

cd /srv/repo/conf

Create a file named distributions:

nano distributions

Add the following content, replacing <your-gpg-key-id> with your actual key ID:

Codename: noble
Architectures: amd64 arm64
Components: main
SignWith: <your-gpg-key-id>

Codename: jammy
Architectures: amd64 arm64
Components: main
SignWith: <your-gpg-key-id>

Create an options file:

nano options

Add the following content:

ask-passphrase
verbose

🎉 Repository setup complete!

Setting Up Nginx

  1. Install Nginx

sudo apt-get install nginx
  1. Configure Nginx

Open the default Nginx site configuration:

nano /etc/nginx/sites-available/default

Ensure the configuration looks like this:

server {

    root       /srv/repo/;
    autoindex  on;

    access_log  /var/log/nginx/repo.access.log;
    error_log   /var/log/nginx/repo.error.log;

    location ~ /(db|conf) {
        deny   all;
        return 404;
    }
}

Save and exit the file.

  1. Start Nginx

Restart the service:

sudo systemctl restart nginx

🎉 Nginx server is now running and serving your repository!

Adding and Updating Packages

Prerequisites

Make sure you have:

  • A reprepro repository (e.g., at /srv/repo/)

  • A .deb file for the package you want to deploy

Adding Packages

Use the following command to add a package:

reprepro -b /srv/repo/ includedeb noble /path/to/ros-jazzy-*.deb
reprepro -b /srv/repo/ includedeb jammy /path/to/ros-humble-*.deb

Add the packages of each distribution to its codename: Jazzy packages to noble, Humble packages to jammy. The architecture is taken from the package. If your GPG key has a passphrase, you’ll be prompted to enter it.

To list packages in the repository:

reprepro -b /srv/repo/ list noble

Updating Packages

To update an existing package with a new version:

reprepro -b /srv/repo/ includedeb noble /path/to/deb/file.deb

Note

reprepro keeps only one version of each package per distribution: adding a new version replaces the old one. Older releases cannot be installed from the apt server afterwards. Their packages stay available in the GitLab package registry of ros2-workspace-lab (cpm_lab/<version>), see Versions, Updates and Rollback.

Publishing a Release

The tag pipeline of ros2-workspace-lab builds the packages for both distributions and architectures and uploads them to the package registry of the project (upload_to_package_registry). The job release_to_server then hands them to the apt server, which adds them with reprepro includedeb.

Internal content

You are part of the development team? Read this part in the internal documentation.

Troubleshooting

GPG Key Issues

  • Ensure you run both gpg and reprepro with the same user. If one is run as root and the other as a normal user, they won’t share keyrings.

Reprepro Issues

  • Deleting Packages

    Reprepro sometimes struggles to delete packages cleanly. If necessary, manually reset the repository:

    cd /srv/repo/
    rm -rf db dists lists pool
    
  • zstd Error

    You may see this warning:

    zstd: error 70: Write error : cannot write decoded block : Broken pipe
    

    This is a known bug in reprepro. It’s safe to ignore—your package will still be added. See the GitHub issue for more details.