Follow redirects and cache them properly

pull/33/head
Ruud Kamphuis 2020-03-23 10:07:19 +01:00
parent 8ad0aaa25e
commit e90d203fc0
No known key found for this signature in database
GPG Key ID: 059472B12AA29D01
2 changed files with 37 additions and 36 deletions

21
Makefile 100644
View File

@ -0,0 +1,21 @@
clean:
rm -rf docker_mirror_cache/*
build:
docker build --tag docker-registry-proxy .
start:
docker run --rm --name=docker-registry-proxy -it \
-p 0.0.0.0:3128:3128 \
-p 0.0.0.0:8081:8081 \
-e DEBUG=true \
-v $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/docker_mirror_cache:/docker_mirror_cache \
-v $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/docker_mirror_certs:/ca \
docker-registry-proxy
stop:
docker stop docker-registry-proxy
test: build start
.INTERMEDIATE: clean stop

View File

@ -198,8 +198,8 @@ echo "Docker configured with HTTPS_PROXY=$scheme://$http_host/"
proxy_cache_lock on; proxy_cache_lock on;
proxy_cache_lock_timeout 880s; proxy_cache_lock_timeout 880s;
# Cache all 200, 301, 302, and 307 (emitted by private registries) for 60 days. # Cache all 200, 206 for 60 days.
proxy_cache_valid 200 301 302 307 60d; proxy_cache_valid 200 206 60d;
# Some extra settings to maximize cache hits and efficiency # Some extra settings to maximize cache hits and efficiency
proxy_force_ranges on; proxy_force_ranges on;
@ -225,47 +225,28 @@ echo "Docker configured with HTTPS_PROXY=$scheme://$http_host/"
return 405 "docker-registry-proxy: docker is trying to use v1 API. Either the image does not exist upstream, or you need to configure docker-registry-proxy to authenticate against $host"; return 405 "docker-registry-proxy: docker is trying to use v1 API. Either the image does not exist upstream, or you need to configure docker-registry-proxy to authenticate against $host";
} }
# for the /v2/..../blobs/.... URIs, do cache, and treat redirects. # for the /v2/..../blobs/.... URIs, do cache, and treat redirects.
location ~ ^/v2/(.*)/blobs/ { location ~ ^/v2/(.*)/blobs/ {
proxy_pass https://$targetHost; proxy_pass https://$targetHost;
proxy_cache cache; proxy_cache cache;
add_header X-Docker-Caching-Proxy-Debug-Cache "yes:blobs"; proxy_cache_key $uri;
proxy_intercept_errors on;
# Handling of redirects. error_page 301 302 307 = @handle_redirects;
# Many registries (eg, quay.io, or k8s.gcr.io) emit a Location redirect
# pointing to something like cloudfront, or google storage.
# We hack into the response, extracting the host and URI parts, injecting them into a URL that points back to us
# That gives us a chance to intercept and cache those, which are the actual multi-megabyte blobs we originally wanted to cache.
# We to it twice, one for http and another for https.
proxy_redirect ~^https://([^:/]+)(/.+)$ https://docker.caching.proxy.internal/forcecachesecure/$1/originalwas$2;
proxy_redirect ~^http://([^:/]+)(/.+)$ http://docker.caching.proxy.internal/forcecacheinsecure/$1/originalwas$2;
} }
location @handle_redirects {
#store the current state of the world so we can reuse it in a minute
# We need to capture these values now, because as soon as we invoke
# the proxy_* directives, these will disappear
set $original_uri $uri;
set $orig_loc $upstream_http_location;
# handling for the redirect case explained above, with https. # nginx goes to fetch the value from the upstream Location header
# The $realHost and $realPath variables come from a map defined at the top of this file. proxy_pass $orig_loc;
location /forcecachesecure {
proxy_pass https://$realHost$realPath;
proxy_cache cache; proxy_cache cache;
# But we store the result with the cache key of the original request URI
# Change the cache key, so that we can cache signed S3 requests and such. Only host and path are considered. # so that future clients don't need to follow the redirect too
proxy_cache_key $proxy_host$uri; proxy_cache_key $original_uri;
add_header X-Docker-Caching-Proxy-Debug-Cache "yes:forcecachesecure";
}
# handling for the redirect case explained above, with http.
# The $realHost and $realPath variables come from a map defined at the top of this file.
location /forcecacheinsecure {
proxy_pass http://$realHost$realPath;
proxy_cache cache;
# Change the cache key, so that we can cache signed S3 requests and such. Only host and path are considered.
proxy_cache_key $proxy_host$uri;
add_header X-Docker-Caching-Proxy-Debug-Cache "yes:forcecacheinsecure";
} }
# by default, dont cache anything. # by default, dont cache anything.
@ -274,6 +255,5 @@ echo "Docker configured with HTTPS_PROXY=$scheme://$http_host/"
proxy_cache off; proxy_cache off;
add_header X-Docker-Caching-Proxy-Debug-Cache "no:default"; add_header X-Docker-Caching-Proxy-Debug-Cache "no:default";
} }
} }
} }