English | 中文
Lightweight multi-upstream Docker Registry proxy.
- Streaming pull-through — no image layer cache
- Pull records and a simple Stats web UI
- One your own domain entry: Hub references stay unchanged through
registry-mirrors; non-Hub registries use an entry-domain path prefix - No Docker socket, no container management
About domains in this docs
Names likereg.a.c,reg.example.com, andhttps://reg.a.care examples only.
Before production use: (1) register a domain, (2) point A/AAAA (or CNAME) at the proxy host, (3) put the real hostname in Caddy/Nginx and inconfig.yaml→hosts.
Container image: ghcr.io/alexwuyh/easy-docker-proxy
Full install and configuration (currently in Chinese): docs/install.md.
Stats console (demo data). Click for full size.
| Login | Dashboard |
|---|---|
![]() |
![]() |
| Upstream analytics | Images |
|---|---|
![]() |
![]() |
git clone https://github.com/AlexWuYh/easy-docker-proxy.git
cd easy-docker-proxy
cp .env.example .env
EDP_ADMIN_TOKEN="$(openssl rand -hex 32)"
EDP_WEB_PASSWORD="$(openssl rand -base64 24 | tr -d '\n')"
sed -i.bak -e "s|^PROXY_ADMIN_TOKEN=.*|PROXY_ADMIN_TOKEN=$EDP_ADMIN_TOKEN|" \
-e "s|^PROXY_WEB_PASSWORD=.*|PROXY_WEB_PASSWORD=$EDP_WEB_PASSWORD|" .env
rm -f .env.bak
unset EDP_ADMIN_TOKEN EDP_WEB_PASSWORD
cp configs/config.docker.yaml configs/config.yaml
# Also set PROXY_DOMAIN=<your real domain> in .env (feeds config hosts + bundled Caddy)
# Optional: PROXY_PORT=<host port> to change the published data-plane port (default 5000)
docker compose --env-file .env -f deploy/docker-compose.yaml up -d| Item | Detail |
|---|---|
| Image | ghcr.io/alexwuyh/easy-docker-proxy:latest (multi-arch, built by CI on release); add --build to build from source |
| Data plane | Host 127.0.0.1:${PROXY_PORT:-5000} by default; publish through TLS |
| Admin plane | :5001, not published publicly by default |
| HTTPS | Prefer your existing Caddy → 127.0.0.1:5000 |
| Stats UI | Map 127.0.0.1:5001, open /stats/login.html |
Ops and security notes: deploy/README.md.
Replace reg.a.c with your domain everywhere below.
Put this valid JSON in /etc/docker/daemon.json:
{
"registry-mirrors": ["https://reg.a.c"]
}systemctl restart docker # Linux
docker pull nginx:alpineFor plain HTTP endpoints, also set insecure-registries.
docker pull reg.a.c/ghcr.io/owner/app:tag
docker pull reg.a.c/quay.io/prometheus/prometheus:latest
docker pull reg.a.c/docker.io/library/nginx:latest
docker pull reg.a.c/registry.k8s.io/pause:3.9The proxy picks the upstream from the path prefix and strips the prefix before calling the real registry.
Do not hijack official names like ghcr.io via /etc/hosts (TLS certificate mismatch).
Default config: configs/config.docker.yaml.
Path-prefix form:
docker pull <your-domain>/<path-prefix>/...
Docker Hub can also use mirrors with no prefix: docker pull nginx.
| name | Upstream | Path prefix | Pull example | Auth env (optional) |
|---|---|---|---|---|
dockerhub |
Docker Hub | docker.io + mirrors (no prefix) |
nginx or <dom>/docker.io/library/nginx:latest |
DOCKERHUB_USER / DOCKERHUB_TOKEN |
ghcr |
GHCR | ghcr.io |
<dom>/ghcr.io/owner/app:tag |
GITHUB_USER / GITHUB_TOKEN |
quay |
Quay.io | quay.io |
<dom>/quay.io/org/img:tag |
QUAY_USER / QUAY_TOKEN |
gcr |
GCR | gcr.io |
<dom>/gcr.io/project/img:tag |
GCR_USER / GCR_TOKEN |
k8s |
Kubernetes | registry.k8s.io, k8s.gcr.io |
<dom>/registry.k8s.io/pause:3.9 |
anonymous by default |
mcr |
Microsoft MCR | mcr.microsoft.com |
<dom>/mcr.microsoft.com/... |
anonymous by default |
nvcr |
NVIDIA NGC | nvcr.io |
<dom>/nvcr.io/... |
NVCR_USER / NVCR_TOKEN |
elastic |
Elastic | docker.elastic.co |
<dom>/docker.elastic.co/... |
ELASTIC_USER / ELASTIC_TOKEN |
ecr-public |
AWS Public ECR | public.ecr.aws |
<dom>/public.ecr.aws/... |
anonymous by default |
- Env template: .env.example. Empty = public anonymous; set tokens for private pulls or Hub rate limits.
- Set
enabled: falseto disable an upstream, or add your ownregistriesentry. - Field reference: docs/configuration.md (Chinese).
| Doc | Content |
|---|---|
| README.zh-CN.md | Chinese README |
| docs/install.md | Installation tutorial (Chinese) |
| docs/configuration.md | Configuration reference (Chinese) |
| docs/troubleshooting.md | Troubleshooting (Chinese) |
| deploy/README.md | Operations, security, backup and restore (Chinese) |
| configs/config.example.yaml | Local config template |
export PROXY_ADMIN_TOKEN="$(openssl rand -hex 32)"
export PROXY_WEB_PASSWORD='your-long-password'
go run ./cmd/proxy -config configs/config.example.yaml
CGO_ENABLED=0 go test ./...Data-plane ideas inspired by Docker-Proxy (not a fork; no container management).




