Skip to content

Debian APT package repository format

Ben Hutchison edited this page Oct 15, 2024 · 15 revisions

To make a Debian APT repository with one package, you need at least 3 files. In this example, the package is named dotnet-runtime-8.0 with version 8.0.8-0, and it targets Debian 12 Bookworm on 32-bit ARM CPUs.

  • .deb (e.g. packages/dotnet-runtime-8.0.8-0-armhf.deb)
    ↑ refers to
  • Packages.gz (e.g. dists/bookworm/main/binary-armhf/Packages.gz)
    ↑ refers to
  • InRelease (e.g. dists/bookworm/InRelease)
    ↑ downloads
  • apt-get

.deb

  • Purpose: contains files to install, scripts to run, and metadata for your package
  • Quantity: one per package, version, CPU architecture, and possibly Debian version if there are differences
  • Path: a .deb file in any subdirectory (possibly nested) of the repository's root directory, such as packages or pool
  • File type: AR archive (Common variant)
  • Archive contents
    1. File debian-binary
      • Contents: 2.0\n (ASCII encoded)
    2. File control.tar.gz
      • ./control: text file containing the metadata for your package
      • ./conffiles: text file that specifies which installed files in the package are configuration files, relevant during upgrades
      • ./postinst and other scripts to run at different lifecycles of the package installation
      • The TAR archive can also be compressed with XZ or Zstd, instead of Gzip
    3. File data.tar.gz
      • Contents: a Gzipped TAR archive that contains all the files to extract to disk when your package is installed. May contain symlinks, subdirectories, file permissions, owners, and groups.
      • The TAR archive can also be compressed with XZ, Bzip2, Zstd, or LZMA (Lzip), instead of Gzip

control package metadata file

Fields

❗ = required

Architecture ❗
The CPU architecture that this package runs on, or all if it is CPU-agnostic (like a script or metapackage). Common choices are armhf, arm64, amd64, and i386.
Depends
Comma-separated list of other packages that must also be installed along with this package. Can specify version inequalities in parentheses and alternatives separated by vertical pipes. Unknown alternatives are silently ignored.
Description ❗
Free-form descriptive text explaining what this package is and does. The first line is a summary. The remaining lines are the body, prepended by spaces and separated by linefeeds. Each empty and whitespace-only line in the body is replaced with . (a space followed by a period). Non-empty lines in the body are not allowed to start with ., so replace leading periods with another character like β€€ (U+2024 ONE DOT LEADER).
Homepage
URL of a web page related to this package
Installed-Size
Sum of the sizes of all the files that will be installed by this package, in kilobytes, rounded to the nearest integer of KB, with no separators or decimal places. Directories and symlinks each count as 1KB.
Maintainer ❗
Name and email address of a person who works on this package, in the form Name <name@email.com>
Package ❗
Name of the package. This is what users will type into apt install.
Priority
How important this package is to a functioning system, usually optional
Provides
Comma-separated list of virtual packages that this package implicitly fulfills. This allows users or downstream packages to install or depend on one virtual package, and as long as you have installed any of the concrete packages that Provide it, the dependency will be fulfilled. Useful if there are multiple package names that provide different versions or alternatives of the same functionality.
Section
A topic or theme of the package. For a more up-to-date list than the Policy Manual's, see the official Debian section lists for different releases (use the final URL path segment like devel, not the user-facing label like "Development").
Version ❗
The version number of this build of the package

Example contents

Architecture: armhf
Depends: dotnet-cli (>= 8.0.8-0), libc6, libgcc-s1 | libgcc1, libgssapi-krb5-2, libicu72 | libicu67 | libicu63, libssl3 | libssl1.1, libstdc++6, tzdata, zlib1g
Description: .NET CLI tools and runtime
 β€€NET is a fast, lightweight, and modular platform for creating cross platform applications that work on GNU/Linux, Mac OS, and Windows.
 .
 It particularly focuses on creating console applications, web applications, and microservices.
 .
 β€€NET contains a runtime conforming to .NET Standards, a set of framework libraries, an SDK containing compilers, and a 'dotnet' CLI application to drive everything.
Homepage: https://dot.net/
Installed-Size: 64815
Maintainer: Ben Hutchison <ben@aldaviva.com>
Package: dotnet-runtime-8.0
Priority: optional
Provides: dotnet-runtime-8.0-or-greater, dotnet-runtime-7.0-or-greater, dotnet-runtime-6.0-or-greater
Section: devel
Version: 8.0.8-0

Verification

After building a .deb file, you can verify it using official tools to see if it's valid, especially if you're getting errors.

command description
dpkg --info dotnet-runtime-8.0.8-0-armhf.deb show metadata of package file
dpkg --contents dotnet-runtime-8.0.8-0-armhf.deb list files to install
dpkg --unpack dotnet-runtime-8.0.8-0-armhf.deb outDir extract files to directory
dpkg-deb --raw-extract dotnet-runtime-8.0.8-0-armhf.deb outDir extract files and metadata to directory
dpkg --install dotnet-runtime-8.0.8-0-armhf.deb install
dpkg --status dotnet-runtime-8.0 show metadata of installed package
dpkg --remove dotnet-runtime-8.0 uninstall, retains configuration files
dpkg --purge dotnet-runtime-8.0 uninstall, deletes configuration files

Packages.gz

  • Purpose: list all the control metadata files' contents for each .deb package file
  • Quantity: one per Debian version, CPU architecture, and component (main)
  • Path: dists/$distribution/$component/$arch/Packages.gz
    • $distribution = Debian major version distribution, suite, or codename, such as bookworm, bullseye, stable, or oldstable
    • $component = usually main
    • $arch = CPU architecture, like armhf
  • Format: blank line separated strings (two linefeeds between each entry)
  • File type: Gzipped plaintext
    • Can also be compressed with XZ, Bzip2, or LZMA
  • Recommended additional files for older clients
    • Packages: this file but not Gzipped (if this file exists, it must also appear in InRelease)

Fields

The entries in this text file are a superset of the control metadata text from each .deb package file, with three extra fields added per file.

❗ = required

All fields from control ❗
Include all of the fields from ./control inside each .deb file's control.tar.gz
Filename ❗
Path to the .deb file, relative to the repository root, separated by forward slashes (such as packages/dotnet-runtime-8.0.8-0-armhf.deb)
SHA256 ❗
Lowercase SHA-256 hash of the .deb file
Size ❗
File size of the .deb file, in bytes, with no separators (unlike Installed-Size, which is in kilobytes)

Example contents

Architecture: armhf
Depends: dotnet-cli (>= 8.0.8-0), libc6, libgcc-s1 | libgcc1, libgssapi-krb5-2, libicu72 | libicu67 | libicu63, libssl3 | libssl1.1, libstdc++6, tzdata, zlib1g
Description: .NET CLI tools and runtime
 β€€NET is a fast, lightweight, and modular platform for creating cross platform applications that work on GNU/Linux, Mac OS, and Windows.
 .
 It particularly focuses on creating console applications, web applications, and microservices.
 .
 β€€NET contains a runtime conforming to .NET Standards, a set of framework libraries, an SDK containing compilers, and a 'dotnet' CLI application to drive everything.
Homepage: https://dot.net/
Installed-Size: 64815
Maintainer: Ben Hutchison <ben@aldaviva.com>
Package: dotnet-runtime-8.0
Priority: optional
Provides: dotnet-runtime-8.0-or-greater, dotnet-runtime-7.0-or-greater, dotnet-runtime-6.0-or-greater
Section: devel
Version: 8.0.8-0
Filename: packages/dotnet-runtime-8.0.8-0-armhf.deb
Size: 29350430
SHA256: 96b9391674b36ddb5c9a3367058c6fd7c31501c336727cc95f3d014fedda4586

Architecture: armhf
Depends: dotnet-runtime-8.0 (= 8.0.8-0)
Description: ASP.NET Core runtime
 The ASP.NET Core runtime contains everything needed to run .NET web applications. It includes a high performance Virtual Machine as well as the framework libraries used by .NET applications.
 .
 ASP.NET Core is a fast, lightweight, and modular platform for creating cross platform applications that work on GNU/Linux, Mac OS, and Windows.
 .
 It particularly focuses on creating console applications, web applications, and microservices.
Homepage: https://dot.net/
Installed-Size: 24912
Maintainer: Ben Hutchison <ben@aldaviva.com>
Package: aspnetcore-runtime-8.0
Priority: optional
Provides: aspnetcore-runtime-8.0-or-greater, aspnetcore-runtime-7.0-or-greater, aspnetcore-runtime-6.0-or-greater
Section: devel
Version: 8.0.8-0
Filename: packages/aspnetcore-runtime-8.0.8-0-armhf.deb
Size: 10598480
SHA256: 83400e6c6105b4b9847c32331a77182716b965096d567e0476feef4697b1150e

InRelease

  • Purpose: list and hash the per-architecture package metadata lists for a given Debian version
  • Quantity: one per Debian major version
  • Path: dists/$distribution/InRelease
    • $distribution = Debian major version distribution, suite, or codename, such as bookworm, bullseye, stable, or oldstable
  • Format: linefeed-separated list of key-value pairs, where keys and values are separated by :
  • File type: plaintext
    • PGP clearsigned using gpg --sign --clearsign --armor (file contents are wrapped inline with a PGP signature)
  • Recommended additional files for older clients
    • Release: this file with no inline PGP signature
    • Release.gpg: PGP detached signature of Release generated using gpg --sign --detach-sign --armor

Fields

❗ = required

Architectures ❗
The union of CPU architecture names of all packages that target this Debian version, separated by spaces
Codename ❗
Debian version codename, like bookworm or bullseye. Required if Suite is missing.
Components ❗
Usually just main, but sometimes nonfree or testing are used. Space-separated.
Date ❗
When this file was generated, in UTC and RFC 1123 format
Description
Free-form descriptive text about this repository
Label
Free-form name of the repository
Origin
Your name or organization
SHA256 ❗
List of per-architecture package list files for this Debian version (Packages[.gz]) on separate lines, in the following format (there is a leading space on each line). If Packages.gz and Packages both exist, they must each be listed on their own lines.
 $hash $size $path
$hash ❗
Lowercase SHA-256 hash of a Packages[.gz] package list file that targets this Debian version
$size ❗
Number of bytes of the package list file, without separators
$path ❗
Path to the package list file, relative to this InRelease file, using forward slash separators.
Suite ❗
The Debian stability indicator, like unstable, testing, stable, or oldstable. Required if Codename is missing.

Example contents

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Origin: Ben Hutchison
Label: .NET for Raspberry Pi OS
Codename: bookworm
Suite: stable
Architectures: armhf arm64
Components: main
Description: ARM packages of .NET Runtimes and SDKs for Raspberry Pi OS
Date: Thu, 29 Aug 2024 04:35:54 GMT
SHA256:
 2c033756b9870d1dda6641028ccde7fa6009244a1340cd228d42426eac9cf084 3127 main/binary-armhf/Packages.gz
 c7538fe49a49f5c0663045d3f0734a7e9df049e1121569719368ed84d1c780f3 19810 main/binary-armhf/Packages
 8e8217243138f72e6f640f576f49d8cf6d7e126961f3dcdd3355f843855442b0 3127 main/binary-arm64/Packages.gz
 b75bd84c341437b1c6102412ed82b8915b386a980fd1432740fe79825d48c13a 19812 main/binary-arm64/Packages
-----BEGIN PGP SIGNATURE-----
Version: BouncyCastle.NET Cryptography (net6.0) v2.4.0+83ebf4a805

iQJgBAEBCABKBQJmz/qrQxxCZW4gSHV0Y2hpc29uIChSYXNwYmlhbiBERUIgcGFj
a2FnZSByZXBvc2l0b3J5KSA8YmVuQGFsZGF2aXZhLmNvbT4ACgkQRdZvBUq5pmrp
8BAAptQBxfxCSHQg0hYM8Vpq3noJL2Dz6fW80KE956KId5a3l7a6cr8fwrfXBQ5X
52D71mzMvYuJ+kgZlMfvYAeP5JId0THh92thcNIrzhUzQr6YZ4GLl+ySME2gHxRf
Wi+W60q3mKx8A6h3+e6Yy+EypOEdG/aE0ntIhVEl3p7dNb/YH0B6dExN8ulgwa/Z
QLWvFBTvcQZsJjA8QlQPYj7VAjVaaQJpFxdfNCGMxlQNcAsZ2VpiSPhd1h1SGbzi
juWSuzqLWJm+gpQQv72RoMWqscEFm9gXEX0g1bTTnechhaiA0Rfbo26IHZw72zXD
9FvUrf+fc+mFSnMlEqTPp8K9sHQA/o90tj6WhijOq4zCak6jNigiHJZMpjXOga8/
6E3m2tCLUb6ZE/KWAWajRinuH5rh3gp8eacDYX1Ww7hcwfBX/mpm08kE9YHD8BlM
JTJQl44ccqRcl/w7EP6S/LVib4C3wMSrISRtOnoBebZT+SJ5JhiXxC74ERWK/5mU
j4Eu+JmFlyjV/WO20dw0qFo+txYg3DjjWgSzxXQ95yBhm5F0175wgED96qhOR2GS
97vX8NzDEag+wYFAe8l0sA0byXXdinfhhcRjXDHUVf4PdPcp5QGcl8RZzBs1l3s4
c8ilkniDh/ARvdHVQqXkjsPZ+qmTCUjSCJ3cRkQwFb82eZ8=
=Z7zp
-----END PGP SIGNATURE-----

PGP signing

To sign InRelease files, you need a PGP public and private keypair. You can generate and use one with GnuPG.

  1. Create a keypair
    gpg --full-generate-key
  2. Get the long alpha-numeric $thumbprint of the newly-generated key
    gpg --list-secret-keys
  3. Export the public key to distribute to users to install on their computers and verify your repository.
    gpg --export $thumbprint > myrepo.gpg
  4. If you use GnuPG to sign your InRelease files (gpg --sign), you don't have to export your private key.
    If you need to use an external tool like BouncyCastle, you can export the private key to a file for use in the external tool.
    ⚠ Do not share this file with ❝threat actors❞ or else they could impersonate you and create malicious packages.
    gpg --export-secret-keys --armor $thumbprint > myrepo.priv.asc

To back up and restore your GPG keys, see How to Backup and Restore Your GPG Key (Risan Bagja) or Backup and Restore a GPG Key (Jordan Williams).

Installation

Repository

To add this repository to a Debian installation so that you can install packages from it, create a new text file /etc/apt/sources.list.d/myrepo.list with the following format.

deb $repoBaseUrl $distribution $component

For example,

deb http://domain.com/path/to/repo bookworm main

/path/to/repo should be the parent directory of dists. This tells apt where to download the InRelease file for your Debian version (it will automatically construct the full URL with /dists/).

PGP public key

To add the public PGP key that signs this repository, download the binary DER-encoded public key file to /etc/apt/trusted.gpg.d/myrepo.gpg.

If you use a PEM-encoded ASCII-armored public key, some versions of APT will throw an error, so make sure the key is exported in DER format (without the --armor argument).

Install packages

Now you can install a package using its name.

sudo apt update
sudo apt install dotnet-runtime-8.0

Complete repository structure example

https://raspbian.aldaviva.com/

β”‚ πŸ“„ aldaviva.gpg.key
β”‚ πŸ“„ readme
β”œβ”€πŸ“ dists
β”‚  β”œβ”€πŸ“ bookworm
β”‚  β”‚  β”‚ πŸ“„ InRelease
β”‚  β”‚  β”‚ πŸ“„ Release
β”‚  β”‚  β”‚ πŸ“„ Release.gpg
β”‚  β”‚  β””β”€πŸ“ main
β”‚  β”‚     β”œβ”€πŸ“ binary-arm64
β”‚  β”‚     β”‚    πŸ“„ Packages
β”‚  β”‚     β”‚    πŸ“„ Packages.gz
β”‚  β”‚     β””β”€πŸ“ binary-armhf
β”‚  β”‚          πŸ“„ Packages
β”‚  β”‚          πŸ“„ Packages.gz
β”‚  β”œβ”€πŸ“ bullseye
β”‚  β”‚  β”‚ πŸ“„ InRelease
β”‚  β”‚  β”‚ πŸ“„ Release
β”‚  β”‚  β”‚ πŸ“„ Release.gpg
β”‚  β”‚  β””β”€πŸ“ main
β”‚  β”‚     β”œβ”€πŸ“ binary-arm64
β”‚  β”‚     β”‚    πŸ“„ Packages
β”‚  β”‚     β”‚    πŸ“„ Packages.gz
β”‚  β”‚     β””β”€πŸ“ binary-armhf
β”‚  β”‚          πŸ“„ Packages
β”‚  β”‚          πŸ“„ Packages.gz
β”‚  β””β”€πŸ“ buster
β”‚     β”‚ πŸ“„ InRelease
β”‚     β”‚ πŸ“„ Release
β”‚     β”‚ πŸ“„ Release.gpg
β”‚     β””β”€πŸ“ main
β”‚        β”œβ”€πŸ“ binary-arm64
β”‚        β”‚    πŸ“„ Packages
β”‚        β”‚    πŸ“„ Packages.gz
β”‚        β””β”€πŸ“ binary-armhf
β”‚             πŸ“„ Packages
β”‚             πŸ“„ Packages.gz
β””β”€πŸ“ packages
     πŸ“„ aspnetcore-runtime-6.0.33-0-arm64.deb
     πŸ“„ aspnetcore-runtime-6.0.33-0-armhf.deb
     πŸ“„ aspnetcore-runtime-7.0.20-0-arm64.deb
     πŸ“„ aspnetcore-runtime-7.0.20-0-armhf.deb
     πŸ“„ aspnetcore-runtime-8.0-0-latest-lts.deb
     πŸ“„ aspnetcore-runtime-8.0-0-latest.deb
     πŸ“„ aspnetcore-runtime-8.0.8-0-arm64.deb
     πŸ“„ aspnetcore-runtime-8.0.8-0-armhf.deb
     πŸ“„ dotnet-cli-6.0.33-0-arm64.deb
     πŸ“„ dotnet-cli-6.0.33-0-armhf.deb
     πŸ“„ dotnet-cli-7.0.20-0-arm64.deb
     πŸ“„ dotnet-cli-7.0.20-0-armhf.deb
     πŸ“„ dotnet-cli-8.0.8-0-arm64.deb
     πŸ“„ dotnet-cli-8.0.8-0-armhf.deb
     πŸ“„ dotnet-runtime-6.0.33-0-arm64.deb
     πŸ“„ dotnet-runtime-6.0.33-0-armhf.deb
     πŸ“„ dotnet-runtime-7.0.20-0-arm64.deb
     πŸ“„ dotnet-runtime-7.0.20-0-armhf.deb
     πŸ“„ dotnet-runtime-8.0-0-latest-lts.deb
     πŸ“„ dotnet-runtime-8.0-0-latest.deb
     πŸ“„ dotnet-runtime-8.0.8-0-arm64.deb
     πŸ“„ dotnet-runtime-8.0.8-0-armhf.deb
     πŸ“„ dotnet-sdk-6.0.425-0-arm64.deb
     πŸ“„ dotnet-sdk-6.0.425-0-armhf.deb
     πŸ“„ dotnet-sdk-7.0.410-0-arm64.deb
     πŸ“„ dotnet-sdk-7.0.410-0-armhf.deb
     πŸ“„ dotnet-sdk-8.0-0-latest-lts.deb
     πŸ“„ dotnet-sdk-8.0-0-latest.deb
     πŸ“„ dotnet-sdk-8.0.401-0-arm64.deb
     πŸ“„ dotnet-sdk-8.0.401-0-armhf.deb

References