A minimal Debian or Ubuntu container image is around 90MB. The first thing you do
is apt update - and apt downloads another 90-216MB of index files
describing tens of thousands of packages, the overwhelming majority of which will
never be installed on a headless server. They sit in
/var/lib/apt/lists, consuming space and bandwidth on every
container, on every host, on every update cycle, indefinitely.
debthin serves curated Packages.gz indexes filtered to
server-relevant packages across all components. Desktop, GUI,
games, fonts and hardware-specific packages are excluded.
The result is an index 60-96% smaller than upstream depending on suite and component.
Everything else - the actual .deb files - redirects
transparently to the official mirrors. Nothing is rehosted.
The list is rebuilt daily from upstream Packages files, ranked by popcon install counts. Packages not in the index can still be installed by name, or added permanently via pull request.
On a bare container with only curl:
curl -fsSL http://debthin.org/debthin-keyring-binary.gpg \
-o /etc/apt/trusted.gpg.d/debthin.gpg
printf "deb http://deb.debthin.org/debian trixie headless\n\
deb http://security.debian.org/debian-security trixie-security main\n" \
> /etc/apt/sources.list
apt-get update
No gpg, no apt-transport-https, no ca-certificates
required.
| Alias | Codename | Architectures |
|---|
Components: main contrib non-free non-free-firmware
(bullseye: main contrib non-free)
Without gpg - works on bare containers:
curl -fsSL http://debthin.org/debthin-keyring-binary.gpg \
-o /etc/apt/trusted.gpg.d/debthin.gpg
With gpg:
curl -fsSL http://debthin.org/debthin-keyring.gpg \
| gpg --dearmor \
| tee /etc/apt/trusted.gpg.d/debthin.gpg > /dev/null
DEB822 format:
Types: deb URIs: http://debthin.org Suites: trixie trixie-updates Components: main contrib non-free non-free-firmware Signed-By: /etc/apt/trusted.gpg.d/debthin.gpg # Security goes direct - keep it independent Types: deb URIs: http://security.debian.org/debian-security Suites: trixie-security Components: main
Classic sources.list format:
deb http://debthin.org trixie main contrib non-free non-free-firmware deb http://debthin.org trixie-updates main contrib non-free non-free-firmware deb http://security.debian.org/debian-security trixie-security main
apt fetches package indexes uncompressed by default. This config tells apt to request
.gz indexes and keep them compressed on disk - cutting index storage from ~80MB to ~20MB.
Translation files add another ~30MB for languages you'll never need on a headless server.
This works independently of debthin and is worthwhile on any server.
// Strip translation files and keep indexes compressed Acquire::Languages "none"; Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";
FROM debian:trixie-slim RUN curl -fsSL http://debthin.org/debthin-keyring-binary.gpg \ -o /etc/apt/trusted.gpg.d/debthin.gpg \ && printf "deb http://deb.debthin.org/debian trixie main contrib non-free non-free-firmware\ndeb http://deb.debthin.org/debian trixie-updates main contrib non-free non-free-firmware\ndeb http://security.debian.org/debian-security trixie-security main\n" \ > /etc/apt/sources.list \ && apt-get update \ && apt-get install -y --no-install-recommends \ your-package-here \ && rm -rf /var/lib/apt/lists/*
files: - path: /etc/apt/trusted.gpg.d/debthin.gpg generator: download url: http://debthin.org/debthin-keyring-binary.gpg packages: repositories: - name: debthin url: http://deb.debthin.org/debian suite: trixie components: [main, contrib, non-free, non-free-firmware] - name: trixie-updates url: http://deb.debthin.org/debian suite: trixie-updates components: [main, contrib, non-free, non-free-firmware] - name: security url: http://security.debian.org/debian-security suite: trixie-security components: [main]
apt: sources_list: | deb http://deb.debthin.org/debian trixie main contrib non-free non-free-firmware deb http://deb.debthin.org/debian trixie-updates main contrib non-free non-free-firmware deb http://security.debian.org/debian-security trixie-security main runcmd: - curl -fsSL http://debthin.org/debthin-keyring-binary.gpg -o /etc/apt/trusted.gpg.d/debthin.gpg - apt-get update
On a bare container with only curl:
curl -fsSL http://debthin.org/debthin-keyring-binary.gpg \
-o /etc/apt/trusted.gpg.d/debthin.gpg
printf "deb http://deb.debthin.org/ubuntu noble headless\n\
deb http://security.ubuntu.com/ubuntu noble-security main restricted universe multiverse\n" \
> /etc/apt/sources.list
apt-get update
The same debthin GPG key covers both Debian and Ubuntu.
| Alias | Codename | Architectures |
|---|
Components: main restricted universe multiverse -
security goes direct to security.ubuntu.com
Same key as Debian - one install covers both:
curl -fsSL http://debthin.org/debthin-keyring-binary.gpg \
-o /etc/apt/trusted.gpg.d/debthin.gpg
DEB822 format:
Types: deb URIs: http://deb.debthin.org/ubuntu Suites: noble noble-updates noble-backports Components: main restricted universe multiverse Signed-By: /etc/apt/trusted.gpg.d/debthin.gpg # Security goes direct - keep it independent Types: deb URIs: http://security.ubuntu.com/ubuntu Suites: noble-security Components: main restricted universe multiverse
Classic sources.list format:
deb http://deb.debthin.org/ubuntu noble main restricted universe multiverse deb http://deb.debthin.org/ubuntu noble-updates main restricted universe multiverse deb http://deb.debthin.org/ubuntu noble-backports main restricted universe multiverse deb http://security.ubuntu.com/ubuntu noble-security main restricted universe multiverse
Works identically on Ubuntu - cuts /var/lib/apt/lists from 216MB down to under 10MB combined
with debthin.
// Strip translation files and keep indexes compressed Acquire::Languages "none"; Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";
FROM ubuntu:noble RUN curl -fsSL http://debthin.org/debthin-keyring-binary.gpg \ -o /etc/apt/trusted.gpg.d/debthin.gpg \ && printf "deb http://deb.debthin.org/ubuntu noble main restricted universe multiverse\ndeb http://deb.debthin.org/ubuntu noble-updates main restricted universe multiverse\ndeb http://security.ubuntu.com/ubuntu noble-security main restricted universe multiverse\n" \ > /etc/apt/sources.list \ && apt-get update \ && apt-get install -y --no-install-recommends \ your-package-here \ && rm -rf /var/lib/apt/lists/*
apt: sources_list: | deb http://deb.debthin.org/ubuntu noble main restricted universe multiverse deb http://deb.debthin.org/ubuntu noble-updates main restricted universe multiverse deb http://security.ubuntu.com/ubuntu noble-security main restricted universe multiverse runcmd: - curl -fsSL http://debthin.org/debthin-keyring-binary.gpg -o /etc/apt/trusted.gpg.d/debthin.gpg - apt-get update
Loading build status from recent run...
Packages not in the curated index are still installable - apt will resolve
and fetch them from the official mirrors transparently via 301 redirect.
The index just won't list them for apt search or apt-cache.
To add a package to the index permanently, open a pull request against
github.com/debthin/debthin
and add the package name to required_packages/debian.txt.
The index rebuilds daily; merged additions appear within 24 hours.
.deb package format and ecosystem,
consistent with
Debian's trademark policy
for software that works with Debian systems.
debthin does not redistribute packages -
all package files are served directly from official mirrors.
Pipeline, worker and curation scripts are open source.
github.com/debthin/debthin