Skip to content

Commit e90d203

Browse files
committed
Follow redirects and cache them properly
1 parent 8ad0aaa commit e90d203

File tree

2 files changed

+37
-36
lines changed

2 files changed

+37
-36
lines changed

Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
clean:
2+
rm -rf docker_mirror_cache/*
3+
4+
build:
5+
docker build --tag docker-registry-proxy .
6+
7+
start:
8+
docker run --rm --name=docker-registry-proxy -it \
9+
-p 0.0.0.0:3128:3128 \
10+
-p 0.0.0.0:8081:8081 \
11+
-e DEBUG=true \
12+
-v $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/docker_mirror_cache:/docker_mirror_cache \
13+
-v $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/docker_mirror_certs:/ca \
14+
docker-registry-proxy
15+
16+
stop:
17+
docker stop docker-registry-proxy
18+
19+
test: build start
20+
21+
.INTERMEDIATE: clean stop

nginx.conf

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ echo "Docker configured with HTTPS_PROXY=$scheme://$http_host/"
198198
proxy_cache_lock on;
199199
proxy_cache_lock_timeout 880s;
200200

201-
# Cache all 200, 301, 302, and 307 (emitted by private registries) for 60 days.
202-
proxy_cache_valid 200 301 302 307 60d;
201+
# Cache all 200, 206 for 60 days.
202+
proxy_cache_valid 200 206 60d;
203203

204204
# Some extra settings to maximize cache hits and efficiency
205205
proxy_force_ranges on;
@@ -225,47 +225,28 @@ echo "Docker configured with HTTPS_PROXY=$scheme://$http_host/"
225225
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";
226226
}
227227

228-
229228
# for the /v2/..../blobs/.... URIs, do cache, and treat redirects.
230229
location ~ ^/v2/(.*)/blobs/ {
231230
proxy_pass https://$targetHost;
232231
proxy_cache cache;
233-
add_header X-Docker-Caching-Proxy-Debug-Cache "yes:blobs";
234-
235-
# Handling of redirects.
236-
# Many registries (eg, quay.io, or k8s.gcr.io) emit a Location redirect
237-
# pointing to something like cloudfront, or google storage.
238-
# We hack into the response, extracting the host and URI parts, injecting them into a URL that points back to us
239-
# That gives us a chance to intercept and cache those, which are the actual multi-megabyte blobs we originally wanted to cache.
240-
# We to it twice, one for http and another for https.
241-
proxy_redirect ~^https://([^:/]+)(/.+)$ https://docker.caching.proxy.internal/forcecachesecure/$1/originalwas$2;
242-
proxy_redirect ~^http://([^:/]+)(/.+)$ http://docker.caching.proxy.internal/forcecacheinsecure/$1/originalwas$2;
232+
proxy_cache_key $uri;
233+
proxy_intercept_errors on;
234+
error_page 301 302 307 = @handle_redirects;
243235
}
244236

237+
location @handle_redirects {
238+
#store the current state of the world so we can reuse it in a minute
239+
# We need to capture these values now, because as soon as we invoke
240+
# the proxy_* directives, these will disappear
241+
set $original_uri $uri;
242+
set $orig_loc $upstream_http_location;
245243

246-
# handling for the redirect case explained above, with https.
247-
# The $realHost and $realPath variables come from a map defined at the top of this file.
248-
location /forcecachesecure {
249-
proxy_pass https://$realHost$realPath;
250-
proxy_cache cache;
251-
252-
# Change the cache key, so that we can cache signed S3 requests and such. Only host and path are considered.
253-
proxy_cache_key $proxy_host$uri;
254-
255-
add_header X-Docker-Caching-Proxy-Debug-Cache "yes:forcecachesecure";
256-
257-
}
258-
259-
# handling for the redirect case explained above, with http.
260-
# The $realHost and $realPath variables come from a map defined at the top of this file.
261-
location /forcecacheinsecure {
262-
proxy_pass http://$realHost$realPath;
244+
# nginx goes to fetch the value from the upstream Location header
245+
proxy_pass $orig_loc;
263246
proxy_cache cache;
264-
265-
# Change the cache key, so that we can cache signed S3 requests and such. Only host and path are considered.
266-
proxy_cache_key $proxy_host$uri;
267-
268-
add_header X-Docker-Caching-Proxy-Debug-Cache "yes:forcecacheinsecure";
247+
# But we store the result with the cache key of the original request URI
248+
# so that future clients don't need to follow the redirect too
249+
proxy_cache_key $original_uri;
269250
}
270251

271252
# by default, dont cache anything.
@@ -274,6 +255,5 @@ echo "Docker configured with HTTPS_PROXY=$scheme://$http_host/"
274255
proxy_cache off;
275256
add_header X-Docker-Caching-Proxy-Debug-Cache "no:default";
276257
}
277-
278258
}
279259
}

0 commit comments

Comments
 (0)