Skip to content

TuzelKO/apt-proxy

 
 

Repository files navigation

apt-proxy logo

APT Proxy

Project Status: Active Security Scan Release Go Report Card License Latest Release Go Version Docker Image

Caching proxy for APT (Ubuntu/Debian), YUM (CentOS), and APK (Alpine). Speeds up repeated package downloads by serving them from a local cache. Drop-in replacement for apt-cacher-ng.

apt-proxy web UI

🚀 Quick Start

# Docker
docker run -d -p 3142:3142 -v apt-proxy-cache:/app/.aptcache tuzelko/apt-proxy

# Or download the binary from the releases page
./apt-proxy

The proxy starts immediately and benchmarks mirrors in the background, switching to the fastest one for your network once the benchmark completes.

📦 Supported Platforms

OS Architectures
Linux x86_64, x86_32, ARM64, ARM32v6, ARM32v7
macOS x86_64, Apple Silicon (ARM64)

🔧 Usage

Ubuntu / Debian

# One-off
http_proxy=http://your-host:3142 apt-get update
http_proxy=http://your-host:3142 apt-get install vim -y

# Persistent — /etc/apt/apt.conf.d/01proxy
Acquire::http::Proxy "http://your-host:3142";

CentOS 7

sed -i \
  -e 's/mirrorlist.*$//' \
  -e 's/#baseurl/baseurl/' \
  -e 's#http://mirror.centos.org#http://your-host:3142#' \
  /etc/yum.repos.d/CentOS-Base.repo
yum update

CentOS 8

sed -i \
  -e 's#mirror.centos.org#http://your-host:3142#g' \
  -e 's/#baseurl/baseurl/' \
  -e 's#\$releasever/#8-stream/#' \
  /etc/yum.repos.d/CentOS-*
yum update

Alpine

sed -i 's#https://.*.alpinelinux.org#http://your-host:3142#' /etc/apk/repositories
apk update

⚙️ Configuration

Priority (highest first): CLI flags → environment variables (APT_PROXY_*) → YAML file → defaults.

Flag Env var Default Description
-host APT_PROXY_HOST 0.0.0.0 Interface to bind
-port APT_PROXY_PORT 3142 Port to listen on
-mode APT_PROXY_MODE all all, ubuntu, ubuntu-ports, debian, centos, alpine
-cachedir APT_PROXY_CACHEDIR ./.aptcache Cache directory
-cache-max-size APT_PROXY_CACHE_MAX_SIZE 10 Max cache size, GB (0 = unlimited, LRU eviction)
-cache-ttl APT_PROXY_CACHE_TTL 168 Cache TTL, hours (0 = no expiry)
-cache-cleanup-interval APT_PROXY_CACHE_CLEANUP_INTERVAL 60 Cleanup interval, minutes
-ubuntu / -debian / etc. APT_PROXY_UBUNTU / … auto Mirror URL or shortcut
-distributions-config APT_PROXY_DISTRIBUTIONS_CONFIG (search paths) Path to distributions.yaml
-disable-builtin-distros APT_PROXY_DISABLE_BUILTIN_DISTROS false Disable built-in distributions; use only those defined in distributions.yaml
-async-benchmark APT_PROXY_ASYNC_BENCHMARK true Benchmark mirrors in background on startup
-api-key APT_PROXY_API_KEY Key for management API endpoints
-tls / -tls-cert / -tls-key APT_PROXY_TLS_* HTTPS support
-config APT_PROXY_CONFIG_FILE Path to YAML config file
-debug APT_PROXY_DEBUG false Verbose logging
-version Print version and exit

Mirror shortcuts

cn:tsinghua · cn:ustc · cn:163 · cn:aliyun · cn:huaweicloud · cn:tencent

./apt-proxy --ubuntu=cn:tsinghua --debian=cn:ustc

YAML config

Config file search paths: ./apt-proxy.yaml/etc/apt-proxy/apt-proxy.yaml~/.config/apt-proxy/apt-proxy.yaml~/.apt-proxy.yaml

server:
  host: 0.0.0.0
  port: 3142
  debug: false

cache:
  dir: /var/cache/apt-proxy
  max_size_gb: 20
  ttl_hours: 168
  cleanup_interval_min: 60

mirrors:
  ubuntu: cn:tsinghua
  debian: cn:ustc

security:
  api_key: ${APT_PROXY_API_KEY}
  enable_api_auth: true

🗂 Distributions and Mirrors (distributions.yaml)

Mirror lists and distribution settings are defined in distributions.yaml. You can extend or override them without recompiling.

Search paths: ./config/distributions.yaml./distributions.yaml/etc/apt-proxy/~/.config/apt-proxy/

distributions:
  - id: ubuntu
    name: Ubuntu
    type: 1
    url_pattern: "/ubuntu/(.+)$"
    benchmark_url: "dists/noble/main/binary-amd64/Release"
    geo_mirror_api: "http://mirrors.ubuntu.com/mirrors.txt"
    cache_rules:
      - pattern: "deb$"
        cache_control: "max-age=100000"
        rewrite: true
    mirrors:
      official:
        - "mirrors.tuna.tsinghua.edu.cn/ubuntu/"
    aliases:
      tsinghua: "mirrors.tuna.tsinghua.edu.cn/ubuntu/"

After editing, reload without restart:

kill -HUP $(pgrep apt-proxy)
# or
curl -X POST -H "X-API-Key: $KEY" http://localhost:3142/api/mirrors/refresh

⚠️ Hot reload applies to distributions and mirrors only. Host/port, TLS, and API key require a full restart.

Caching third-party APT repositories

Any HTTP-based APT repository can be proxied and cached. Examples — Docker CE and Proxmox VE:

distributions:
  - id: docker-debian
    name: Docker CE (Debian)
    type: 1
    url_pattern: "/linux/debian/(.+)$"
    benchmark_url: "dists/bookworm/stable/binary-amd64/Release"
    cache_rules:
      - pattern: "\\.deb$"
        cache_control: "max-age=100000"
        rewrite: true
    mirrors:
      official:
        - "download.docker.com/linux/debian/"

  - id: proxmox-ve
    name: Proxmox VE
    type: 1
    url_pattern: "/debian/pve/(.+)$"
    benchmark_url: "dists/bookworm/pve-no-subscription/binary-amd64/Release"
    cache_rules:
      - pattern: "\\.deb$"
        cache_control: "max-age=100000"
        rewrite: true
    mirrors:
      official:
        - "download.proxmox.com/debian/pve/"

Point sources.list at the proxy:

deb http://your-proxy:3142/linux/debian bookworm stable
deb http://your-proxy:3142/debian/pve bookworm pve-no-subscription

The same approach works for any APT-based repo: Grafana, Kubernetes, HashiCorp, etc.

💡 If you only need custom repositories and want to disable Ubuntu/Debian/CentOS/Alpine entirely, use --disable-builtin-distros (or APT_PROXY_DISABLE_BUILTIN_DISTROS=true).

🐳 Docker

docker run -d \
  --name apt-proxy \
  -p 3142:3142 \
  -v apt-proxy-cache:/app/.aptcache \
  tuzelko/apt-proxy

# Use inside another container
http_proxy=http://host.docker.internal:3142 apt-get install -y vim

See example/ for Docker Compose configurations.

Image tags: latest, 0, 0.11, 0.11.0 — all multi-arch (amd64, arm64, armv7).

🔌 API

Public: GET /healthz, /livez, /readyz, /version, /metrics (Prometheus).

Protected (require X-API-Key header or Authorization: Bearer <key>):

Method Path Description
GET /api/cache/stats Size, hit rate, item count
POST /api/cache/purge Clear all cached items
POST /api/cache/cleanup Remove stale entries
POST /api/mirrors/refresh Reload distributions + re-benchmark
curl -H "X-API-Key: your-key" http://localhost:3142/api/cache/stats

📊 Observability

The /metrics endpoint exposes Prometheus metrics:

Metric Description
apt_proxy_cache_* Hits, misses, size, item count, evictions
apt_proxy_cache_upstream_* Upstream request duration and error rate
apt_proxy_cache_request_duration_seconds Request latency by distro and cache status

Health endpoints (/healthz, /readyz) are suitable for Kubernetes probes.

🏗 Architecture

Client → apt-proxy → Cache hit → Client
                  ↘ Cache miss → upstream mirror → Cache → Client
  • URL rewriting — rewrites request URLs to the target mirror; no transparent forwarding
  • Async benchmarking — mirrors benchmarked in background on startup (24h TTL); proxy serves immediately and upgrades once done
  • Dynamic distributions — add any distro via distributions.yaml without code changes
  • Retryable transport — 3 retries, exponential backoff (100ms initial, 2× multiplier, 2s max)
  • LRU eviction — when cache-max-size is exceeded, least recently used files are evicted first
  • State — thread-safe singleton (sync.Once + sync.RWMutex), updated at startup and on hot reload

🛠 Development

make build          # build binary → ./apt-proxy
make test           # run tests
make coverage       # test + coverage summary
make coverage-html  # open coverage report in browser
make vet            # go vet

🐛 Troubleshooting

Packages not being cached — verify the proxy URL is reachable from the client and the URL pattern in distributions.yaml matches the repository path.

Slow first download — expected: the first request populates the cache. Subsequent requests are served locally.

Cache growing too large — set --cache-max-size or call POST /api/cache/cleanup.

Debug logging:

./apt-proxy --debug
# or
APT_PROXY_DEBUG=true ./apt-proxy

📄 License

Apache License 2.0

🙏 Acknowledgements


Maintainer: Eugene Frost · Repository: GitHub · Registry: Docker Hub

❤️ Issues and pull requests are welcome!

About

Lightweight APT / YUM / APK cache proxy

Resources

License

Security policy

Stars

Watchers

Forks

Contributors

Languages

  • Go 93.4%
  • HTML 4.0%
  • Makefile 1.3%
  • Other 1.3%