Why?

If you’re reading this — you probably already know why you need it. But just to be clear:

Public Cloud

If you’re a compute provider or host virtual machines for customers, you might want to reduce outbound bandwidth usage by caching package downloads.

CI/CD

If your CI pipeline runs non-cached Docker builds, you could benefit from caching APT (Debian) packages — again, saving bandwidth and speeding up builds.

Examples

Used by:

  1. OvH
  2. Hetzner
  3. Smaller vendors

Plan

┌ ║ └ ┌ ┌ V ─ " ┬ ┼ │ ┴ M │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┐ │ ┘ ┐ ┐ 2 ─ < ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ c ─ a ─ ─ c a ─ h ─ p ─ e ┌ ║ └ ┌ ┌ V t ─ d ─ ─ " ┬ ┼ │ ┴ M │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ─ │ │ │ │ │ │ │ │ │ ┐ │ ┘ ┐ ┐ 1 ─ < u ─ r ─ ─ ─ p ─ e ─ d ─ s ─ a ─ ─ a ─ p p ─ r t ─ o ─ t ─ e ─ e ─ n ─ s ─ s ─ u ─ p ─ ─ e p ─ o ─ ─ d ─ n ─ ─ a ─ s ─ ─ t ─ e ─ ─ ┌ │ └ e ─ ─ ─ ─ N ─ ─ ─ ─ ─ G ─ ─ ─ ─ ─ I ─ ─ ─ ─ ─ N ─ ─ ─ ─ ─ X ─ > ─ > ─ ┬ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ─ P ─ ─ < ─ < ─ ─ < ─ r ─ ─ ─ ─ ─ ─ ─ ─ ─ o ─ ─ ─ ─ ─ ─ ─ ─ x ─ ─ ─ ─ ─ s ─ ─ ─ ─ y ─ ─ ─ ─ t ─ ─ ─ ┐ │ ┘ c ─ c ─ ─ ─ o ─ c ─ ─ h ─ a ─ ─ r ─ h ─ c ─ e ─ c ─ ─ ─ e ─ e ─ a ─ c ─ h ─ ─ ─ c ─ c ─ k ─ e ─ ─ ─ i ─ k ─ h ─ ─ ─ ─ n ─ ─ e ─ c ─ m ─ ─ ─ ─ c ─ ─ a ─ i ─ ─ c ─ a ─ h ─ c ─ s ─ ─ ─ a ─ c ─ i ─ h ─ s ─ F ─ c ─ h ─ t ─ e ─ ─ o ─ ─ h ─ e ─ ─ ┌ │ └ ─ ─ r ─ e ─ ─ ─ ─ N ─ ─ ─ w ─ ─ ─ ─ ─ ─ G ─ ─ ─ a ─ ─ ─ ─ ─ I ─ ─ ─ r ─ r ─ ─ ─ ─ ─ N ─ ─ ─ d ─ e ─ ─ ─ ─ X ─ > ─ i ─ s ─ > > ─ ─ ┬ │ │ │ │ │ │ │ │ │ n ─ │ p │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ─ C ─ g ─ o ─ ─ a ─ ─ n ─ c ─ r ─ s ─ ─ h ─ e ─ e ─ e ─ q ─ ─ ┐ │ ┘ u ─ e ─ ─ s ─ t ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┌ │ └ ─ ─ ─ d ─ ─ ─ e ─ ─ ─ ─ b ─ ─ ─ . ─ ─ ─ ─ d ─ ─ ─ e ─ ─ ─ ─ b ─ > ─ i ┬ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ─ a ─ ─ n ─ ─ . ─ ─ o ─ ─ r ─ ─ g ─ ┐ │ ┘

Setup

Requirements

  1. Machine running NGINX (can be a container)
  2. Machines for testing (clients pulling APT packages)

Execution

Docker

Download the setup:

📦Docker.zip

nginx.dockerfile

FROM debian:stable-slim
LABEL maintainer="devs.boo"
LABEL description="Debian Caching Mirror via NGINX"
LABEL version="1.0"

RUN apt update
RUN apt install -y nginx

RUN mkdir /var/cache/nginx
RUN chown -R www-data:www-data /var/cache/nginx

ADD nginx.conf /etc/nginx/nginx.conf
ADD *_cache /etc/nginx/sites-enabled/

CMD ["nginx", "-g", "daemon off;"]

nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 2048;
}

http {


    sendfile on;
    tcp_nopush on;
    types_hash_max_size 2048;


    include /etc/nginx/mime.types;
    default_type application/octet-stream;


    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    gzip on;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

deb_debian_cache

proxy_cache_path /var/cache/nginx/deb_debian_cache levels=1:2 keys_zone=deb_debian_cache:10m max_size=20g inactive=24h use_temp_path=off;

server {
    listen 80;
    server_name deb.debian.local;

    location /debian/ {
        proxy_pass https://deb.debian.org/debian/;
        proxy_set_header Host deb.debian.org;

        proxy_cache deb_debian_cache;
        proxy_cache_valid 200 302 24h;
        proxy_cache_use_stale error timeout updating;
        add_header X-Cache-Status $upstream_cache_status;
    }

    location / {
        add_header Content-Type text/plain;
        return 200 'deb.debian.org cache\n';
    }
}

security_debian_cache

proxy_cache_path /var/cache/nginx/security_debian_cache levels=1:2 keys_zone=security_debian_cache:10m max_size=20g inactive=24h use_temp_path=off;

server {
    listen 80;
    server_name security.debian.local;

    location /debian-security/ {
        proxy_pass https://security.debian.org/debian-security/;
        proxy_set_header Host deb.debian.org;

        proxy_cache security_debian_cache;
        proxy_cache_valid 200 302 24h;
        proxy_cache_use_stale error timeout updating;
        add_header X-Cache-Status $upstream_cache_status;
    }

    location / {
        add_header Content-Type text/plain;
        return 200 'security.debian.org cache\n';
    }
}

Testing

Run this inside a Debian container to test:

docker run --network=host -it debian:stable-slim bash
sed -i "s|debian.org|debian.local|g" /etc/apt/sources.list.d/*
echo "127.0.0.1 deb.debian.local security.debian.local" >> /etc/hosts

Now you can run apt update && apt install ... as usual — and watch your local cache kick in.