A multi-registry docker image cache.
It uses Docker's official registry internally and spawns one instance for each configured registry while it proxies requests to the corresponding registry.
Instead of my/image:latest you just specify 127.0.0.1:5000/my/image:latest.
This also works for 127.0.0.1:5000/ghcr.io/my/image:latest and 127.0.0.1:5000/debian.
- Deploy the stack config as shown below
- Add the following to your
/etc/docker/daemon.json:
{
"insecure-registries" : ["127.0.0.1:5000"]
}- Restart the docker daemon (or reload)
- Change all image references that you want to cache from
my/image:latestto127.0.0.1:5000/my/image:latest
version: '3.8'
services:
proxy:
image: ghcr.io/lhns/docker-registry-cache:0.3.0
environment:
CONFIG: |
[
{"registry": "registry-1.docker.io", "variables": {"REGISTRY_PROXY_USERNAME": "my_dockerhub_id", "REGISTRY_PROXY_PASSWORD": "my_dockerhub_token"}},
"ghcr.io",
"gcr.io"
]
#REGISTRY_STORAGE_DELETE_ENABLED: 'true' bug https://forums.docker.com/t/private-registry-not-working-after-deleting-an-image/105227
volumes:
- /docker-registry-cache:/var/lib/registry
ports:
- "5000:5000"
zzz_proxy:
# This dummy service prevents the image from getting pruned
image: ghcr.io/lhns/docker-registry-cache:0.3.0
entrypoint: tail -f /dev/null
deploy:
mode: globalversion: '3.8'
services:
proxy:
image: ghcr.io/lhns/docker-registry-cache:0.3.0
environment:
CONFIG: |
[
{"registry": "registry-1.docker.io", "variables": {"REGISTRY_PROXY_USERNAME": "my_dockerhub_id", "REGISTRY_PROXY_PASSWORD": "my_dockerhub_token"}},
"ghcr.io",
"gcr.io"
]
REGISTRY_STORAGE: 's3'
REGISTRY_STORAGE_S3_BUCKET: 'registry'
REGISTRY_STORAGE_S3_REGION: 'minio'
REGISTRY_STORAGE_S3_REGIONENDPOINT: 'http://s3:9000'
REGISTRY_STORAGE_S3_ACCESSKEY: 'minioadmin'
REGISTRY_STORAGE_S3_SECRETKEY: 'minioadmin'
#REGISTRY_STORAGE_DELETE_ENABLED: 'true' bug https://forums.docker.com/t/private-registry-not-working-after-deleting-an-image/105227
networks:
- s3
ports:
- "5000:5000"
deploy:
update_config:
order: start-first
s3:
image: minio/minio
entrypoint: /bin/sh -c 'mkdir /data/registry & exec /usr/bin/docker-entrypoint.sh "$$@"' --
command: server --address 0.0.0.0:9000 /data
environment:
MINIO_ACCESS_KEY: 'minioadmin'
MINIO_SECRET_KEY: 'minioadmin'
volumes:
- /docker-registry-cache:/data
networks:
- s3
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 15s
zzz_proxy:
# This dummy service prevents the image from getting pruned
image: ghcr.io/lhns/docker-registry-cache:0.3.0
entrypoint: tail -f /dev/null
deploy:
mode: global
zzz_s3:
# This dummy service prevents the image from getting pruned
image: minio/minio
entrypoint: tail -f /dev/null
deploy:
mode: global
networks:
s3:
driver: overlayversion: '3.8'
services:
traefik:
image: 127.0.0.1:5000/traefik environment:
http_proxy: 'https://my-proxy:8080'
https_proxy: 'https://my-proxy:8080'
no_proxy: '127.0.0.0/8,localhost,s3'CONFIG must contain a JSON list of either registry host strings or objects with the following structure {"registry": "ghcr.io", "variables": {"TEST": "foo"}}
The internally spawned registry processes will also inherit all environment variables so you can configure all internal registries as described in the official documentation.
You can also configure the internal registries individually using the variables section in the aforementioned JSON structure.
PROXY_RESPONSE_HEADER_TIMEOUT (default 30s) bounds how long the proxy waits for an upstream registry to start responding (time-to-first-byte) before failing the request with 504 Gateway Timeout. Once a response begins, body streaming is uncapped so large blobs over slow storage are never interrupted. This prevents a wedged storage read (e.g. a stalled network filesystem) from hanging pulls indefinitely.
PROXY_MANIFEST_REQUEST_TIMEOUT (default 60s) is an additional hard total-request cap applied to manifest requests only (manifests are tiny and should return quickly). Blobs are intentionally not subject to a total cap.
Both accept any Scala Duration string, e.g. 30s, 500ms, 2min.
https://github.com/users/lhns/packages/container/package/docker-registry-cache
https://hub.docker.com/r/lolhens/docker-registry-cache
This project uses the Apache 2.0 License. See the file called LICENSE.