Skip to content

ðŸ“Ķ reprepro

reprepro is used as a local repository for deb packages.

Some apps, like SOPS, release deb files, but are not a part of the normal repository. Hosting them locally, allows me to download the package once and then easily update on all other containers.

🛠 Installation

apt install reprepro apache2 gpg

⚙ Config

ðŸŠķ Apache

/etc/apache2/apache2.conf

echo "ServerName localhost" | tee -a /etc/apache2/apache2.conf
ServerName localhost

/etc/apache2/conf-availabe/repos.conf

cat <<EOF > /etc/apache2/conf-availabe/repos.conf 
# /etc/apache2/conf.available/repos.conf
# Apache HTTP Server 2.4

Alias /repos/apt/debian /srv/reprepro/debian

<Directory /srv/reprepro/ >
        # We want the user to be able to browse the directory manually
        Options Indexes FollowSymLinks Multiviews
        Require all granted
</Directory>

# This syntax supports several repositories, e.g. one for Debian, one for Ubuntu.
# Replace * with debian, if you intend to support one distribution only.
<Directory "/srv/reprepro/*/db/">
        Require all denied
</Directory>

<Directory "/srv/reprepro/*/conf/">
        Require all denied
</Directory>

<Directory "/srv/reprepro/*/incoming/">
        Require all denied
</Directory>

EOF
wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/reprepro/apache2/conf-available/repos.conf -O /etc/apache2/conf-availabe/repos.conf
# /etc/apache2/conf.available/repos.conf
# Apache HTTP Server 2.4

Alias /repos/apt/debian /srv/reprepro/debian

<Directory /srv/reprepro/ >
        # We want the user to be able to browse the directory manually
        Options Indexes FollowSymLinks Multiviews
        Require all granted
</Directory>

# This syntax supports several repositories, e.g. one for Debian, one for Ubuntu.
# Replace * with debian, if you intend to support one distribution only.
<Directory "/srv/reprepro/*/db/">
        Require all denied
</Directory>

<Directory "/srv/reprepro/*/conf/">
        Require all denied
</Directory>

<Directory "/srv/reprepro/*/incoming/">
        Require all denied
</Directory>

Enable and test

(
    a2enconf repos && \
    apache2ctl configtest && \
    service apache2 restart
)

ðŸ“Ķ Repository

Make directories

shell ( [ -d /srv/reprepo/debian/conf ] || mkdir -p /srv/reprepo/debian/conf [ -d /srv/reprepo/ubuntu/conf ] || mkdir -p /srv/reprepo/ubuntu/conf )

Generate new gpg keys

gpg --full-generate-key
gpg --list-keys  
 pub  2048R/489CD644 2014-07-15  
 uid         Your Name <[email protected]>  
 sub  2048R/870B8E2D 2014-07-15

Get short fingerprint

gpg --list-keys [email protected] | sed -n '2p'| sed 's/ //g' | tail -c 9

Export public gpg key

gpg --armor --output /srv/reprepro/public.gpg.key --export-options export-minimal --export 089C9FAF

/srv/reprepo/<dist>/conf/distributions

(
  cat <<EOF > /srv/reprepo/debian/conf/distributions
  Origin: Debian  
  Label: Bookworm apt repository  
  Codename: bookworm
  Architectures: i386 amd64 arm64  
  Components: main  
  Description: Apt repository for Debian stable - Bookworm  
  DebOverride: override.bookworm
  DscOverride: override.bookworm
  SignWith: 089C9FAF 

  Origin: Debian  
  Label: Bullseye apt repository
  Codename: bullseye
  Architectures: i386 amd64 arm64  
  Components: main  
  Description: Apt repository for Debian stable - Bullseye  
  DebOverride: override.bullseye
  DscOverride: override.bullseye
  SignWith: 089C9FAF 

  EOF
  cat <<EOF > /srv/reprepo/ubuntu/conf/distributions
  Origin: Ubuntu
  Label: Oracular apt repository
  Codename: oracular
  Architectures: amd64 arm64  
  Components: main  
  Description: Apt repository for Ubuntu stable - Oracular
  DebOverride: override.oracular
  DscOverride: override.oracular
  SignWith: 089C9FAF 

  Origin: Ubuntu
  Label: Noble apt repository
  Codename: noble
  Architectures: amd64 arm64  
  Components: main  
  Description: Apt repository for Ubuntu stable - Noble
  DebOverride: override.noble
  DscOverride: override.noble
  SignWith: 089C9FAF 

  EOF
)
(
  ln -s /root/git/nicholaswilde/homelab/pve/reprepro/debian/conf/distributions /srv/reprepo/debian/conf/distributions
  ln -s /root/git/nicholaswilde/homelab/pve/reprepro/ubuntu/conf/distributions /srv/reprepo/ubuntu/conf/distributions
)
(
  wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/reprepro/debian/conf/distributions -O /srv/reprepo/debian/conf/distributions
  wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/reprepro/ubuntu/conf/distributions -O /srv/reprepo/ubuntu/conf/distributions
)
Origin: Debian  
Label: Bookworm apt repository  
Codename: bookworm
Architectures: i386 amd64 arm64  
Components: main  
Description: Apt repository for Debian stable - Bookworm  
DebOverride: override.bookworm
DscOverride: override.bookworm
SignWith: 089C9FAF 

Origin: Debian  
Label: Bullseye apt repository
Codename: bullseye
Architectures: i386 amd64 arm64  
Components: main  
Description: Apt repository for Debian stable - Bullseye  
DebOverride: override.bullseye
DscOverride: override.bullseye
SignWith: 089C9FAF 
Origin: Ubuntu
Label: Oracular apt repository
Codename: oracular
Architectures: amd64 arm64  
Components: main  
Description: Apt repository for Ubuntu stable - Oracular
DebOverride: override.oracular
DscOverride: override.oracular
SignWith: 089C9FAF 

Origin: Ubuntu
Label: Noble apt repository
Codename: noble
Architectures: amd64 arm64  
Components: main  
Description: Apt repository for Ubuntu stable - Noble
DebOverride: override.noble
DscOverride: override.noble
SignWith: 089C9FAF 

/srv/reprepo/<dist>/conf/options

cat <<EOF > /srv/reprepo/debian/conf/options
verbose
basedir /srv/reprepro/debian
ask-passphrase
EOF
cat <<EOF > /srv/reprepo/ubuntu/conf/options
verbose
basedir /srv/reprepro/ubuntu
ask-passphrase
EOF
(
  wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/reprepro/debian/conf/options -O /srv/reprepo/debian/conf/options
  wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/reprepro/ubuntu/conf/options -O /srv/reprepo/ubuntu/conf/options
)
(
  ln -s /root/git/nicholaswilde/homelab/pve/reprepro/debian/conf/options /srv/reprepo/debian/conf/options
  ln -s /root/git/nicholaswilde/homelab/pve/reprepro/ubuntu/conf/options /srv/reprepo/ubuntu/conf/options
)
verbose
basedir /srv/reprepro/debian
ask-passphrase
verbose
basedir /srv/reprepro/ubuntu
ask-passphrase

/srv/reprepo/<dist>/conf/override.<codename>

(
  wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/reprepro/debian/conf/override.bullseye -O /srv/reprepo/debian/conf/override.bullseye
  wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/reprepro/debian/conf/override.bookworm -O /srv/reprepo/debian/conf/override.bookworm
  wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/reprepro/ubuntu/conf/override.oracular -O /srv/reprepo/ubuntu/conf/override.oracular
  wget https://github.com/nicholaswilde/homelab/raw/refs/heads/main/pve/reprepro/ubuntu/conf/override.noble -O /srv/reprepo/ubuntu/conf/override.noble
)
(
  ln -s /root/git/nicholaswilde/homelab/pve/reprepro/debian/conf/override.bullseye /srv/reprepo/debian/conf/override.bullseye
  ln -s /root/git/nicholaswilde/homelab/pve/reprepro/debian/conf/override.bookworm /srv/reprepo/debian/conf/override.bookworm
  ln -s /root/git/nicholaswilde/homelab/pve/reprepro/ubuntu/conf/override.oracular /srv/reprepo/ubuntu/conf/override.oracular
  ln -s /root/git/nicholaswilde/homelab/pve/reprepro/ubuntu/conf/override.noble /srv/reprepo/ubuntu/conf/override.noble
)
(
  touch /srv/reprepro/ubuntu/conf/override.noble
  touch /srv/reprepro/ubuntu/conf/override.oracular
  touch /srv/reprepro/debian/conf/override.bookworm
  touch /srv/reprepro/debian/conf/override.bullseye
)

Traefik

homelab/pve/traefik/conf.d/reprepro.yaml
---
http:
 #region routers 
  routers:
    reprepro:
      entryPoints:
        - "websecure"
      rule: "Host(`deb.l.nicholaswilde.io`)"
      middlewares:
        - default-headers@file
        - https-redirectscheme@file
      tls: {}
      service: reprepro
#endregion
#region services
  services:
    reprepro:
      loadBalancer:
        servers:
          - url: "http://192.168.2.32"
        passHostHeader: true
# #endregion

📝 Usage

ðŸ–Ĩ Server

Add deb file to reprepro.

(
  reprepro -b /srv/reprepro/ubuntu/ includedeb oracular sops_3.9.4_amd64.deb
  reprepro -b /srv/reprepro/ubuntu/ includedeb noble sops_3.9.4_amd64.deb
  reprepro -b /srv/reprepro/debian/ includedeb bookworm sops_3.9.4_amd64.deb
  reprepro -b /srv/reprepro/debian/ includedeb bullseye sops_3.9.4_amd64.deb
)

ðŸ’ŧ Client

Download gpg key

wget  http://deb.l.nicholaswilde.io/public.gpg.key -O /etc/apt/trusted.gpg.d/reprepro.asc

Add repo and install.

/etc/apt/sources.list.d/reprepro.list

(
  echo "deb http://deb.l.nicholaswilde.io/debian bookworm main" >> /etc/apt/sources.list.d/reprepro.list && \  
  apt update && \
  apt install sops
)
deb http://deb.l.nicholaswilde.io/debian bookworm main
apt update && \
apt install sops

Sync Check

The script sync-check.sh is used to compare the latest released versions of the apps SOPS and Task to the local versions.

If out of date, the debs are downloaded and added to reprepro.

homelab/pve/reprepro

task sync-check
./sync-check.sh

⏰ Cronjob

A cronjob can be setup to run every night to check the released versions.

2 A.M. nightly

(crontab -l 2>/dev/null; echo "0 2 * * * /root/git/nicholaswilde/homelab/pve/reprepro/sync-check.sh) | crontab -
crontab -e
0 2 * * * /root/git/nicholaswilde/homelab/pve/reprepro/sync-check.sh

🔗 References