APT package mirror cache powered by Cloudflare Workers. Accelerates package downloads by caching upstream repositories on Cloudflare's global edge network with automatic failover across multiple upstreams.
Note: This project is for experimental purposes only.
| Path | Upstreams |
|---|---|
/proxmox |
download.proxmox.com, mirror.twds.com.tw |
/debian |
NCHC, TWDS, deb.debian.org |
/debian-security |
NCHC, TWDS, security.debian.org |
/ubuntu |
NCHC, TWDS, archive.ubuntu.com |
/ubuntu-security |
NCHC, TWDS, security.ubuntu.com |
- Parallel upstream racing — All upstreams are fetched simultaneously; the fastest 2xx response wins, the rest are cancelled immediately
- Edge caching — Responses are cached on Cloudflare's CDN with per-file-type TTLs
- Automatic failover — If an upstream returns 401/403/5xx or times out (10s), other upstreams continue racing
- HTML link rewriting — Directory listings from upstream are rewritten so relative links stay within the correct mirror prefix
- Trailing slash redirect —
/proxmox→301 /proxmox/to prevent broken relative URL resolution
npm install -g wrangler
wrangler login
wrangler deployReplace mirror.yourdomain.com with your deployed domain.
deb https://mirror.yourdomain.com/proxmox/debian/pve bookworm pve-no-subscription
deb https://mirror.yourdomain.com/debian bookworm main contrib non-free non-free-firmware
deb https://mirror.yourdomain.com/debian bookworm-updates main contrib non-free non-free-firmware
deb https://mirror.yourdomain.com/debian-security bookworm-security main contrib non-free non-free-firmware
deb https://mirror.yourdomain.com/ubuntu noble main restricted universe multiverse
deb https://mirror.yourdomain.com/ubuntu noble-updates main restricted universe multiverse
deb https://mirror.yourdomain.com/ubuntu-security noble-security main restricted universe multiverse
| Endpoint | Description |
|---|---|
GET / |
List all available mirrors |
GET /health |
Health check |
GET /<mirror>/... |
Proxy request to upstream |
| File Type | TTL | Strategy |
|---|---|---|
.deb / .udeb / .ddeb |
30 days | immutable |
/by-hash/ |
1 year | immutable |
/pool/ (source packages, etc.) |
30 days | immutable |
| Release / Packages / Sources / InRelease | 30 min | stale-while-revalidate: 1d |
| Everything else | 1 day | — |
All cache entries include stale-if-error=7d so Cloudflare's edge can serve stale content when upstreams are unavailable.
HTML responses (text/html) are never cached.
A benchmark script is included to compare mirror performance against direct upstream access:
bash scripts/bench.sh https://mirror.yourdomain.comThe script tests:
- TTFB comparison — Mirror vs NCHC / TWDS / Official for each repo
- Download speed — Large file throughput from each source
- Cache stability — 5x burst requests to verify consistent cache hits
- Recommendation — Automated verdict on whether to use the mirror or direct upstream
Edit src/mirrors.js and add a new entry. No other files need to be changed.
"my-repo": {
name: "My Repository",
prefix: "/my-repo",
upstreams: [
"https://primary.example.com/repo",
"https://fallback.example.com/repo",
],
stripPrefix: true,
},Client → Cloudflare Edge (cache) → Worker → Upstream (parallel race)
| File | Description |
|---|---|
src/index.js |
Request handler, cache lookup/store, HTML rewriting |
src/router.js |
Path-based mirror matching |
src/upstream.js |
Parallel upstream racing with timeout and header sanitization |
src/cache.js |
Per-file-type TTL rules and cache eligibility |
src/mirrors.js |
Mirror registry (upstreams, prefixes) |