A lightweight APT Cache Proxy - just over 2MB in size!
APT Proxy is a lightweight, high-performance caching proxy for package managers. It accelerates package downloads by caching frequently used packages locally, dramatically reducing download times for subsequent installations. Whether you're managing multiple servers, building Docker images, or working in bandwidth-constrained environments, APT Proxy helps you save time and bandwidth.
- Multi-Distribution Support: Works with APT (Ubuntu/Debian), YUM (CentOS), and APK (Alpine Linux)
- Lightweight: Binary size is just over 2MB - minimal resource footprint
- Smart Mirror Selection: Automatically benchmarks and selects the fastest mirror
- Docker-Ready: Seamlessly integrates with Docker containers and build processes
- Drop-in Replacement: Compatible with apt-cacher-ng configurations
- Zero Configuration: Works out of the box with sensible defaults
- Observability: Built-in health checks, Prometheus metrics, and structured logging
- Cache Management: REST API for cache statistics, purging, and cleanup
- Linux: x86_64 / x86_32 / Ubuntu ARM64v8
- ARM: ARM64v8 / ARM32v6 / ARM32v7
- macOS: x86_64 / Apple Silicon (ARM64v8)
Download the latest release for your platform from the releases page, or use Docker:
docker pull soulteary/apt-proxySimply run the binary - no configuration required:
./apt-proxyYou should see output similar to:
2024/01/15 10:30:00 INF starting apt-proxy version=1.0.0 listen=0.0.0.0:3142 protocol=http
2024/01/15 10:30:01 INF Starting benchmark for mirrors
2024/01/15 10:30:01 INF Finished benchmarking mirrors
2024/01/15 10:30:01 INF using fastest mirror mirror=https://mirrors.company.ltd/ubuntu/
2024/01/15 10:30:01 INF server started successfully
The proxy is now running and ready to cache packages. By default, it listens on 0.0.0.0:3142 and automatically selects the fastest mirror for your location.
Configure your system to use the proxy by setting the http_proxy environment variable:
# Update package lists (first run will download and cache)
http_proxy=http://your-domain-or-ip-address:3142 \
apt-get -o pkgProblemResolver=true -o Acquire::http=true update
# Install packages (subsequent installs will use cached packages)
http_proxy=http://your-domain-or-ip-address:3142 \
apt-get -o pkgProblemResolver=true -o Acquire::http=true install vim -yTip: For convenience, you can export the proxy settings in your shell:
export http_proxy=http://your-domain-or-ip-address:3142
apt-get update
apt-get install vim -yAfter the first download, all subsequent package operations will be significantly faster as packages are served from the local cache.
APT Proxy works with YUM repositories. Configure your CentOS system to use the proxy:
For CentOS 7:
# Configure repository to use proxy
cat /etc/yum.repos.d/CentOS-Base.repo | \
sed -e s/mirrorlist.*$// \
-e s/#baseurl/baseurl/ \
-e s#http://mirror.centos.org#http://your-domain-or-ip-address:3142# | \
tee /etc/yum.repos.d/CentOS-Base.repo
# Verify configuration
yum updateFor CentOS 8:
# Update all CentOS repositories to use proxy
sed -i -e "s#mirror.centos.org#http://your-domain-or-ip-address:3142#g" \
-e "s/#baseurl/baseurl/" \
-e "s#\$releasever/#8-stream/#" \
/etc/yum.repos.d/CentOS-*
# Verify configuration
yum updateConfigure Alpine's APK package manager to use the proxy:
# Update repositories to use proxy
cat /etc/apk/repositories | \
sed -e s#https://.*.alpinelinux.org#http://your-domain-or-ip-address:3142# | \
tee /etc/apk/repositories
# Verify configuration
apk updateYou can maintain distributions and mirror lists via an external YAML file without changing code or recompiling.
Config file search order (when not specified):
./config/distributions.yaml./distributions.yaml/etc/apt-proxy/distributions.yaml~/.config/apt-proxy/distributions.yaml
You can also set the path explicitly via --distributions-config or APT_PROXY_DISTRIBUTIONS_CONFIG.
Example config/distributions.yaml:
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/"
- "mirrors.ustc.edu.cn/ubuntu/"
custom:
- "mirrors.163.com/ubuntu/"
aliases:
tsinghua: "mirrors.tuna.tsinghua.edu.cn/ubuntu/"
ustc: "mirrors.ustc.edu.cn/ubuntu/"After editing the file, send SIGHUP or call POST /api/mirrors/refresh to hot-reload without restart.
Adding or editing a distribution: Add or edit an entry under distributions with id, name, type, url_pattern, benchmark_url, cache_rules, mirrors, and aliases. The repo includes an example at config/distributions.yaml that you can extend.
By default, APT Proxy automatically benchmarks available mirrors and selects the fastest one. However, you can specify custom mirrors if needed.
Using Full URLs:
# Cache multiple distributions
./apt-proxy \
--ubuntu=https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ \
--debian=https://mirrors.tuna.tsinghua.edu.cn/debian/
# Cache only Ubuntu packages (reduces memory usage)
./apt-proxy --mode=ubuntu --ubuntu=https://mirrors.tuna.tsinghua.edu.cn/ubuntu/
# Cache only Debian packages
./apt-proxy --mode=debian --debian=https://mirrors.tuna.tsinghua.edu.cn/debian/Using Mirror Shortcuts:
For convenience, you can use predefined shortcuts instead of full URLs:
./apt-proxy --ubuntu=cn:tsinghua --debian=cn:163Available Shortcuts:
cn:tsinghua- Tsinghua University Mirrorcn:ustc- USTC Mirrorcn:163- NetEase Mirrorcn:aliyun- Alibaba Cloud Mirrorcn:huaweicloud- Huawei Cloud Mirrorcn:tencent- Tencent Cloud Mirror
Example output:
2024/01/15 10:55:26 INF starting apt-proxy version=1.0.0
2024/01/15 10:55:26 INF using specified debian mirror mirror=https://mirrors.163.com/debian/
2024/01/15 10:55:26 INF using specified ubuntu mirror mirror=https://mirrors.tuna.tsinghua.edu.cn/ubuntu/
2024/01/15 10:55:26 INF proxy listening on 0.0.0.0:3142
2024/01/15 10:55:26 INF server started successfully
Deploy APT Proxy as a Docker container:
docker run -d \
--name=apt-proxy \
-p 3142:3142 \
-v apt-proxy-cache:/app/.aptcache \
soulteary/apt-proxyThe -v apt-proxy-cache:/app/.aptcache option persists the cache across container restarts.
Accelerate package installation in your Docker containers:
# Start a container (Ubuntu or Debian)
docker run --rm -it ubuntu
# Inside the container, use the proxy
http_proxy=http://host.docker.internal:3142 \
apt-get -o Debug::pkgProblemResolver=true -o Acquire::http=true update
http_proxy=http://host.docker.internal:3142 \
apt-get -o Debug::pkgProblemResolver=true -o Acquire::http=true install vim -yNote: host.docker.internal works on Docker Desktop. For Linux, use the host's IP address or configure Docker networking appropriately.
See the example directory for complete Docker Compose configurations.
View all available options:
./apt-proxy -hAvailable Options:
| Option | Description | Default |
|---|---|---|
-host |
Network interface to bind to | 0.0.0.0 |
-port |
Port to listen on | 3142 |
-mode |
Distribution mode: all, ubuntu, ubuntu-ports, debian, centos, alpine |
all |
-cachedir |
Directory to store cached packages | ./.aptcache |
-ubuntu |
Ubuntu mirror URL or shortcut | (auto-select) |
-ubuntu-ports |
Ubuntu Ports mirror URL or shortcut | (auto-select) |
-debian |
Debian mirror URL or shortcut | (auto-select) |
-centos |
CentOS mirror URL or shortcut | (auto-select) |
-alpine |
Alpine mirror URL or shortcut | (auto-select) |
-distributions-config |
Path to distributions/mirrors YAML (distributions.yaml) | (optional) |
-cache-max-size |
Maximum cache size in GB (0 to disable) | 10 |
-cache-ttl |
Cache TTL in hours (0 to disable) | 168 (7 days) |
-cache-cleanup-interval |
Cache cleanup interval in minutes | 60 |
-tls |
Enable TLS/HTTPS | false |
-tls-cert |
Path to TLS certificate file | |
-tls-key |
Path to TLS private key file | |
-api-key |
API key for protected endpoints | |
-config |
Path to YAML configuration file | |
-debug |
Enable verbose debug logging | false |
Example with Custom Configuration:
./apt-proxy \
--host=0.0.0.0 \
--port=3142 \
--cachedir=/var/cache/apt-proxy \
--mode=ubuntu \
--ubuntu=cn:tsinghua \
--cache-max-size=20 \
--debugAPT Proxy supports YAML configuration files for more complex setups. Create a file named 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
tls:
enabled: false
cert_file: /etc/ssl/certs/apt-proxy.crt
key_file: /etc/ssl/private/apt-proxy.key
security:
api_key: ${APT_PROXY_API_KEY} # Supports environment variable expansion
enable_api_auth: true
mode: allConfiguration Priority: CLI flags > Environment variables > Config file > Default values
Config file search paths (in order):
- Path specified via
-configflag orAPT_PROXY_CONFIG_FILEenvironment variable ./apt-proxy.yaml(current directory)/etc/apt-proxy/apt-proxy.yaml~/.config/apt-proxy/apt-proxy.yaml~/.apt-proxy.yaml
The cache supports a size limit configured via max_size_gb (YAML), --cache-max-size (CLI), or APT_PROXY_CACHE_MAX_SIZE (environment variable). When the total cache size exceeds this limit, the proxy automatically evicts the least recently used (LRU) files until the total size is within the limit. Eviction runs both when storing new items and during periodic cleanup.
- Set a positive value (e.g.
20for 20 GB) to enable the capacity limit and LRU eviction. - Set to
0to disable the size limit; no size-based eviction is performed.
After a process restart, the LRU order is approximated using file modification time until new accesses update it.
APT Proxy provides REST API endpoints for monitoring and management:
| Endpoint | Description |
|---|---|
GET /healthz |
Comprehensive health check |
GET /livez |
Kubernetes liveness probe |
GET /readyz |
Kubernetes readiness probe |
GET /version |
Version information |
GET /metrics |
Prometheus metrics |
| Endpoint | Method | Description |
|---|---|---|
/api/cache/stats |
GET | Cache statistics (size, hit rate, item count) |
/api/cache/purge |
POST | Purge all cached items |
/api/cache/cleanup |
POST | Remove stale cache entries |
| Endpoint | Method | Description |
|---|---|---|
/api/mirrors/refresh |
POST | Reload distributions/mirrors config (distributions.yaml) and refresh mirrors |
When an API key is configured, all management endpoints require authentication. Provide the API key using one of these methods:
-
X-API-Key Header (recommended):
curl -H "X-API-Key: your-api-key" http://localhost:3142/api/cache/stats -
Authorization Bearer Token:
curl -H "Authorization: Bearer your-api-key" http://localhost:3142/api/cache/stats
Example: Get Cache Statistics (with authentication)
curl -H "X-API-Key: your-api-key" http://localhost:3142/api/cache/statsResponse:
{
"total_size_bytes": 1073741824,
"total_size_human": "1.00 GB",
"item_count": 150,
"stale_count": 5,
"hit_count": 1250,
"miss_count": 150,
"hit_rate": 0.893
}APT Proxy supports hot reloading of distributions and mirror config only (including distributions.yaml) without restart. Changes to the main configuration (e.g. apt-proxy.yaml: server host/port, cache limits, TLS, security, API key) do not hot-reload and require a process restart.
To reload distributions and mirrors:
# Send SIGHUP to reload config and refresh mirrors
kill -HUP $(pgrep apt-proxy)Or use the API:
curl -X POST http://localhost:3142/api/mirrors/refreshflowchart LR
Client[APT Client] --> Proxy[apt-proxy]
Proxy --> Cache[(Local Cache)]
Proxy --> Mirror1[Mirror 1]
Proxy --> Mirror2[Mirror 2]
subgraph aptproxy [apt-proxy internals]
Handler[Handler] --> Rewriter[URL Rewriter]
Rewriter --> Benchmark[Mirror Benchmark]
Handler --> HTTPCache[HTTP Cache]
Auth[Auth Middleware] --> Handler
end
subgraph monitoring [Observability]
Metrics[Prometheus /metrics]
Health[Health Checks]
API[Management API]
end
- Client Request: APT client sends package request to apt-proxy
- Cache Check: Handler checks if package exists in local cache
- Cache Hit: If cached and fresh, return immediately from cache
- Cache Miss: Rewrite URL to fastest mirror, fetch from upstream
- Store & Respond: Cache response and return to client
apt-proxy/
├── cmd/
│ └── apt-proxy/ # Application entrypoint
│ └── main.go # Main entry point
├── internal/ # Private application code
│ ├── api/ # REST API handlers
│ │ ├── auth.go # API authentication middleware
│ │ ├── cache.go # Cache management endpoints
│ │ ├── mirrors.go # Mirror management endpoints
│ │ └── response.go # Response utilities
│ ├── benchmarks/ # Mirror benchmarking (sync & async)
│ ├── cli/ # CLI and daemon management
│ │ ├── cli.go # Configuration parsing & re-exports
│ │ └── daemon.go # Server lifecycle management
│ ├── config/ # Configuration management
│ │ ├── config.go # Configuration structures
│ │ ├── defaults.go # Default values
│ │ └── loader.go # Configuration loading (CLI, ENV, YAML)
│ ├── distro/ # Distribution definitions
│ │ ├── distro.go # Common types and utilities
│ │ ├── ubuntu.go # Ubuntu configuration
│ │ ├── debian.go # Debian configuration
│ │ ├── centos.go # CentOS configuration
│ │ └── alpine.go # Alpine configuration
│ ├── errors/ # Unified error handling
│ │ └── errors.go # Error codes and types
│ ├── mirrors/ # Mirror management
│ ├── proxy/ # Core proxy functionality
│ │ ├── handler.go # HTTP request handling
│ │ ├── rewriter.go # URL rewriting
│ │ ├── page.go # Home page rendering
│ │ └── stats.go # Statistics
│ ├── state/ # Application state management
│ └── system/ # System utilities (disk, gc, filesize)
├── pkg/ # Reusable packages (importable by others)
│ ├── httpcache/ # HTTP caching layer with metrics
│ └── vfs/ # Virtual filesystem
├── tests/ # Integration tests
│ └── integration/ # End-to-end tests
└── docker/, example/, docs/ # Deployment and documentation
git clone https://github.com/soulteary/apt-proxy.git
cd apt-proxy
go build -o apt-proxy ./cmd/apt-proxy# Run all tests with coverage
go test -cover ./...
# Generate detailed coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.outContributions are welcome! Please feel free to submit a Pull Request.
Enable debug logging to troubleshoot issues:
./apt-proxy --debugFor detailed debugging of package manager operations (Ubuntu/Debian):
# Enable verbose debugging
http_proxy=http://192.168.33.1:3142 \
apt-get -o Debug::pkgProblemResolver=true \
-o Debug::Acquire::http=true \
update
http_proxy=http://192.168.33.1:3142 \
apt-get -o Debug::pkgProblemResolver=true \
-o Debug::Acquire::http=true \
install apache2Issue: Packages not being cached Solution: Ensure the proxy URL is correctly configured and accessible from your client machines.
Issue: Slow first-time downloads Solution: This is expected - the first download populates the cache. Subsequent downloads will be faster.
Issue: Cache directory growing too large
Solution: Configure cache limits with --cache-max-size or use the cleanup API endpoint.
This project is licensed under the Apache License 2.0.
This project builds upon the excellent work of:
- lox/apt-proxy - Original APT proxy implementation
- lox/httpcache - HTTP caching library (MIT License)
- djherbis/stream - Stream handling library (MIT License)
- rainycape/vfs - Virtual filesystem library (Mozilla Public License 2.0)
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made with ❤️ by the APT Proxy community

