Creating and using your own deb repository (not mirroring)


It doesn’t require a lot of software to create it.

  • web server with directory listing ( I use lighttpd)
  • packages: gpg(for signs), dpkg-dev
  • rng-tools (highly recommended)

Repo URL: (it is preferable to use DNS)
Repo directory on the server : /var/www/html/repo/
Deb-packages directory: /var/www/html/repo/deb-packages
Repo generation script: /usr/bin/

Server preparation

  • web server installation
  • gpg-key generation
  • creating script for repo generation
  • repo creation

Gpg-key generation notes

sudo apt-get update
sudo apt-get install -y rng-tools

Web server configuration

# install package
apt-get install lighttpd
# enable directory listing
echo 'server.dir-listing = "enable"' > /etc/lighttpd/conf-enabled/dir-listing.conf
# start lighhttpd and enable autostrt
systemctl restart lighttpd
systemctl enable lighttpd
# create dir for repo
mkdir -p /var/www/html/repo/deb-packages/

Now you should put your deb-packages in /var/www/html/repo/deb-packages/


root@repo:~# gpg --list-keys
gpg: directory '/root/.gnupg' created
gpg: keybox '/root/.gnupg/pubring.kbx' created
gpg: /root/.gnupg/trustdb.gpg: trustdb created

Now you can see that there are no keys available. First, we’ll create keys-generation script. You should use the proper values for your repo:

cat >~/.gnupg/aptRepo <<EOF
%echo Generating a basic OpenPGP key
Key-Type: RSA
Key-Length: 3072
Subkey-Type: ELG-E
Subkey-Length: 3072
Name-Real: apt tech user
Name-Comment: without passphrase
Name-Email: apt@email.non
Expire-Date: 0
%echo done

Now create the keys. This may take some time. Do not set a password for the keys since you’ll need to enter it every time the repo is updated:

root@repo:~# gpg --batch --gen-key ~/.gnupg/aptRepo
gpg: Generating a basic OpenPGP key
gpg: done
gpg: key 16B7C8484EC3AC5F marked as ultimately trusted
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/D538A3381F3D2FC89F34EFDD16B7C8484EC3AC5F.rev'

Check the keys availability:

root@repo:~# gpg --list-keys
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
pub rsa3072 2021-02-07 [SCEA]
uid [ultimate] apt tech user (without passphrase) <apt@email.non>
sub elg3072 2021-02-07 [E]

OK, now you need to export keys to the file:

gpg --export -a D538A3381F3D2FC89F34EFDD16B7C8484EC3AC5F > /var/www/html/repo/boozlachuRepo.gpg
It's time to write a repo-creation script. I used the following variables
• updatescript=/usr/bin/ - path to this script
• repodir=/var/www/html/repo - path to the repo
• gpgKey="D538A3381F3D2FC89F34EFDD16B7C8484EC3AC5F" - gpg-key ID
cat <<'EOFSH' >${updatescript}
# working directory
# GPG key
cd ${repodir}
# create the package index
dpkg-scanpackages -m . > Packages
cat Packages | gzip -9c > Packages.gz
# create the Release file
PKGS=$(wc -c Packages)
PKGS_GZ=$(wc -c Packages.gz)
cat <<EOF > Release
Architectures: all
Date: $(date -R -u)
$(md5sum Packages | cut -d" " -f1) $PKGS
$(md5sum Packages.gz | cut -d" " -f1) $PKGS_GZ
$(sha1sum Packages | cut -d" " -f1) $PKGS
$(sha1sum Packages.gz | cut -d" " -f1) $PKGS_GZ
$(sha256sum Packages | cut -d" " -f1) $PKGS
$(sha256sum Packages.gz | cut -d" " -f1) $PKGS_GZ
gpg --yes -u $gpgKey --sign -bao Release.gpg Release
chmod 755 ${updatescript}

Don’t forget to install the dpkg-scanpackages util:

apt-get install dpkg-dev

Repo creation/update

  • add your deb-packages to /var/www/html/repo/deb-packages
  • run the creation script /usr/bin/

Script output example (for a single package):

dpkg-scanpackages: info: Wrote 1 entries to output Packages file.

Clients setup

wget -O - | sudo apt-key add -
echo 'deb ./ ' > /etc/apt/sources.list.d/boozlachuRepo.list
apt-get update

You can now use this repo on clients:

root@alexey-VirtualBox:~# apt-cache search testpackage
testpackage - simple testpackage for demo

My test package is now available for installation.

Originally published at

IT-engineer, Linux lover

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store