A self-hosted, read-only caching proxy for package registries, Linux repositories, container images, Git repositories, and HTTP files.
Reduce repeated downloads across machines and CI jobs while continuing to use native package clients. Run multiple instances in one process, each with its own upstream, persistent cache, and refresh settings.
Quick Start | Installation | Configuration | Client Setup | Operations
- Protocol-aware caching and content verification.
- Persistent downloads shared across clients and service restarts.
- Shared upstream transfers for concurrent requests to the same object.
- Configurable refresh intervals, download concurrency, and request pacing.
- Built-in dashboard with client configuration, cache usage, and maintenance status.
- Prometheus metrics for monitoring.
| Mode | Content |
|---|---|
file |
HTTP files selected by cache rules |
npm |
Package metadata and tarballs; audit queries pass through |
go |
Go modules and an optional checksum database |
maven |
Metadata, artifacts, signatures, and checksums |
cargo |
Sparse and Git registry indexes, and crates |
pypi |
Simple HTML/JSON indexes and distributions |
deb |
Debian standard, nested, and flat repositories |
apk |
Alpine package indexes, packages, and signatures |
rpm |
rpm-md metadata and RPM packages |
pacman |
Arch Linux package databases, packages, deltas, and signatures |
flatpak |
Flatpak/OSTree summaries, objects, and static deltas |
oci |
OCI Distribution manifests and blobs |
git |
Git repositories over smart HTTP |
Each instance uses one HTTP(S) upstream. Repository layouts are detected
automatically; each git instance mirrors one repository. All upstream access
is read-only. Offline availability depends on which content is cached and whether
its freshness and protocol policies permit reuse.
The following example runs an npm cache on the local machine using Docker. Podman can be used in place of Docker.
- Create
cache-proxy.yaml:
server:
bind: 0.0.0.0:18080
backend: /data
public_url: http://127.0.0.1:18080
instances:
- name: npm
enabled: true
mode: npm
path: /npm
upstream: https://registry.npmjs.org- Start the service with persistent storage:
docker run -d --name cache-proxy \
-p 127.0.0.1:18080:18080 \
-v "$PWD/cache-proxy.yaml:/etc/cache-proxy.yaml:ro" \
-v cache-proxy-data:/data \
ghcr.io/d7z-project/cache-proxy:main \
-config /etc/cache-proxy.yaml- Open the dashboard at
http://127.0.0.1:18080/and configure npm:
npm config set registry http://127.0.0.1:18080/npmThe service is accessible only from the host. For shared access, adjust the
published address and server.public_url, and configure TLS and access controls
at your ingress. The dashboard and proxy routes do not provide client
authentication.
Images are published to ghcr.io/d7z-project/cache-proxy. The main tag follows
the default branch; use a specific release image tag for repeatable deployments.
See GitHub Releases for
available releases and Quick Start for container configuration.
Download the binary for amd64, arm64, or loong64 and SHA256SUMS from
GitHub Releases.
Verify its checksum, then run it with a configuration file:
chmod +x cache-proxy-amd64
./cache-proxy-amd64 -config config.example.yaml -validate
./cache-proxy-amd64 -config config.example.yamlReplace amd64 with your architecture. The
example configuration enables Debian and npm on
127.0.0.1:18080 and stores data in ./data.
Requires Go 1.26 or newer and Make:
git clone https://github.com/d7z-project/cache-proxy.git
cd cache-proxy
make cache-proxy
./cache-proxy -config config.example.yamlconfig.example.yaml documents settings and defaults, with an instance example for every mode. Enable and customize only the instances you need. Validate your configuration before starting the service:
./cache-proxy -config cache-proxy.yaml -validateserver.bindsets the main listener;server.public_urlsets its public address for dashboard client instructions.server.backendsets the persistent storage directory. Use a dedicated volume in containers and allow only one writer process per backend.- Each instance requires a unique
name, amode, anupstream, and exactly one ofpathorbind. Setenabled: trueto start it. - OCI requires a dedicated
bind; setdisplay_urlto its public client address. refresh.intervalcontrols repository background polling or mutable-object freshness. Git usesoptions.sync_interval.transportconfigures outbound connections, proxies, and timeouts;storage.downloadcontrols shared concurrency and request pacing.
Unknown YAML fields and invalid settings are rejected. Durations use Go syntax
such as 500ms, 15m, and 24h; sizes accept binary units such as MiB and GiB.
For refresh behavior, upstream credentials, rate limits, storage, and deployment security, see the operations guide.
The dashboard provides configuration for every enabled instance, including Maven, Alpine, RPM, Pacman, and Flatpak. Use the instance URL in place of the upstream address. The examples below assume matching instances are enabled and exposed through TLS at your public hostname.
npm config set registry https://mirrors.example.com/npm
go env -w GOPROXY=https://mirrors.example.com/go
pip install --index-url https://mirrors.example.com/pypi/simple PACKAGE
git clone https://mirrors.example.com/git/cache-proxy.gitFor Cargo, add this to .cargo/config.toml. The sparse registry URL must end in
a slash:
[source.cache-proxy]
registry = "sparse+https://mirrors.example.com/cargo/"
[source.crates-io]
replace-with = "cache-proxy"Linux clients retain their upstream distribution, components, and signing keys.
For example, standard and flat Debian sources in
/etc/apt/sources.list.d/cache-proxy.list:
deb https://mirrors.example.com/debian bookworm main
deb [signed-by=/usr/share/keyrings/vendor-archive-keyring.gpg] https://mirrors.example.com/debian-flat ./
These require instances mounted at /debian and /debian-flat. The flat example
assumes the vendor's key is installed at the specified path.
For OCI, expose its dedicated listener through a TLS endpoint, for example
https://registry.example.com, and set display_url accordingly. With the
example configuration's Docker Hub upstream:
docker pull registry.example.com/library/alpine:3.20Use the dashboard at / to inspect instances, storage usage, network activity,
and maintenance errors. Prometheus metrics are served at /metrics by default.
Container logs are available with:
docker logs --tail 100 -f cache-proxySee the operations guide for offline behavior, upgrades, status endpoints, and troubleshooting. Report bugs through GitHub Issues, including the build or image tag, mode, configuration without credentials, and relevant logs.
See CONTRIBUTING.md for build and test requirements. Pull requests should include tests for the affected behavior.