Skip to content
Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

230 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

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

Security policy

Stars

Watchers

Forks

Releases

Contributors

Languages