3-tier implementation of manifest caching; refactor config with includes, and generate from ENVs in entrypoint.sh
- disabled by default; enable with -e ENABLE_MANIFEST_CACHE=true - default times and regexes are a wild guess, make sure to tune for your use case.cache-manifests-tiers
parent
227a397225
commit
3bfd778757
24
Dockerfile
24
Dockerfile
|
@ -42,6 +42,8 @@ VOLUME /ca
|
|||
|
||||
# Add our configuration
|
||||
ADD nginx.conf /etc/nginx/nginx.conf
|
||||
ADD nginx.manifest.common.conf /etc/nginx/nginx.manifest.common.conf
|
||||
ADD nginx.manifest.stale.conf /etc/nginx/nginx.manifest.stale.conf
|
||||
|
||||
# Add our very hackish entrypoint and ca-building scripts, make them executable
|
||||
ADD entrypoint.sh /entrypoint.sh
|
||||
|
@ -70,5 +72,27 @@ ENV DEBUG_HUB="false"
|
|||
# Enable nginx debugging mode; this uses nginx-debug binary and enabled debug logging, which is VERY verbose so separate setting
|
||||
ENV DEBUG_NGINX="false"
|
||||
|
||||
# Manifest caching tiers. Disabled by default, to mimick 0.4/0.5 behaviour.
|
||||
# Setting it to true enables the processing of the ENVs below.
|
||||
# Once enabled, it is valid for all registries, not only DockerHub.
|
||||
# The envs *_REGEX represent a regex fragment, check entrypoint.sh to understand how they're used (nginx ~ location, PCRE syntax).
|
||||
ENV ENABLE_MANIFEST_CACHE="false"
|
||||
|
||||
# 'Primary' tier defaults to 10m cache for frequently used/abused tags.
|
||||
# - People publishing to production via :latest (argh) will want to include that in the regex
|
||||
# - Heavy pullers who are being ratelimited but don't mind getting outdated manifests should (also) increase the cache time here
|
||||
ENV MANIFEST_CACHE_PRIMARY_REGEX="(stable|nightly|production|test)"
|
||||
ENV MANIFEST_CACHE_PRIMARY_TIME="10m"
|
||||
|
||||
# 'Secondary' tier defaults any tag that has 3 digits or dots, in the hopes of matching most explicitly-versioned tags.
|
||||
# It caches for 60d, which is also the cache time for the large binary blobs to which the manifests refer.
|
||||
# That makes them effectively immutable. Make sure you're not affected; tighten this regex or widen the primary tier.
|
||||
ENV MANIFEST_CACHE_SECONDARY_REGEX="(.*)(\d|\.)+(.*)(\d|\.)+(.*)(\d|\.)+"
|
||||
ENV MANIFEST_CACHE_SECONDARY_TIME="60d"
|
||||
|
||||
# The default cache duration for manifests that don't match either the primary or secondary tiers above.
|
||||
# In the default config, :latest and other frequently-used tags will get this value.
|
||||
ENV MANIFEST_CACHE_DEFAULT_TIME="1h"
|
||||
|
||||
# Did you want a shell? Sorry, the entrypoint never returns, because it runs nginx itself. Use 'docker exec' if you need to mess around internally.
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
|
|
@ -78,6 +78,49 @@ CACHE_MAX_SIZE=${CACHE_MAX_SIZE:-32g}
|
|||
# Set to 32gb which should be enough
|
||||
echo "proxy_cache_path /docker_mirror_cache levels=1:2 max_size=$CACHE_MAX_SIZE inactive=60d keys_zone=cache:10m use_temp_path=off;" > /etc/nginx/conf.d/cache_max_size.conf
|
||||
|
||||
# Manifest caching configuration. We generate config based on the environment vars.
|
||||
echo -n "" >/etc/nginx/nginx.manifest.caching.config.conf
|
||||
|
||||
[[ "a${ENABLE_MANIFEST_CACHE}" == "atrue" ]] && [[ "a${MANIFEST_CACHE_PRIMARY_REGEX}" != "a" ]] && cat <<EOD >>/etc/nginx/nginx.manifest.caching.config.conf
|
||||
# First tier caching of manifests; configure via MANIFEST_CACHE_PRIMARY_REGEX and MANIFEST_CACHE_PRIMARY_TIME
|
||||
location ~ ^/v2/(.*)/manifests/${MANIFEST_CACHE_PRIMARY_REGEX} {
|
||||
set \$docker_proxy_request_type "manifest-primary";
|
||||
proxy_cache_valid ${MANIFEST_CACHE_PRIMARY_TIME};
|
||||
include "/etc/nginx/nginx.manifest.stale.conf";
|
||||
}
|
||||
EOD
|
||||
|
||||
[[ "a${ENABLE_MANIFEST_CACHE}" == "atrue" ]] && [[ "a${MANIFEST_CACHE_SECONDARY_REGEX}" != "a" ]] && cat <<EOD >>/etc/nginx/nginx.manifest.caching.config.conf
|
||||
# Secondary tier caching of manifests; configure via MANIFEST_CACHE_SECONDARY_REGEX and MANIFEST_CACHE_SECONDARY_TIME
|
||||
location ~ ^/v2/(.*)/manifests/${MANIFEST_CACHE_SECONDARY_REGEX} {
|
||||
set \$docker_proxy_request_type "manifest-secondary";
|
||||
proxy_cache_valid ${MANIFEST_CACHE_SECONDARY_TIME};
|
||||
include "/etc/nginx/nginx.manifest.stale.conf";
|
||||
}
|
||||
EOD
|
||||
|
||||
[[ "a${ENABLE_MANIFEST_CACHE}" == "atrue" ]] && cat <<EOD >>/etc/nginx/nginx.manifest.caching.config.conf
|
||||
# Default tier caching for manifests. Caches for ${MANIFEST_CACHE_DEFAULT_TIME} (from MANIFEST_CACHE_DEFAULT_TIME)
|
||||
location ~ ^/v2/(.*)/manifests/ {
|
||||
set \$docker_proxy_request_type "manifest-default";
|
||||
proxy_cache_valid ${MANIFEST_CACHE_DEFAULT_TIME};
|
||||
include "/etc/nginx/nginx.manifest.stale.conf";
|
||||
}
|
||||
EOD
|
||||
|
||||
[[ "a${ENABLE_MANIFEST_CACHE}" != "atrue" ]] && cat <<EOD >>/etc/nginx/nginx.manifest.caching.config.conf
|
||||
# Manifest caching is disabled. Enable it with ENABLE_MANIFEST_CACHE=true
|
||||
location ~ ^/v2/(.*)/manifests/ {
|
||||
set \$docker_proxy_request_type "manifest-default-disabled";
|
||||
proxy_cache_valid 0s;
|
||||
include "/etc/nginx/nginx.manifest.stale.conf";
|
||||
}
|
||||
EOD
|
||||
|
||||
echo "Manifest caching config: ---"
|
||||
cat /etc/nginx/nginx.manifest.caching.config.conf
|
||||
echo "---"
|
||||
|
||||
# normally use non-debug version of nginx
|
||||
NGINX_BIN="/usr/sbin/nginx"
|
||||
|
||||
|
|
44
nginx.conf
44
nginx.conf
|
@ -267,57 +267,27 @@ echo "Docker configured with HTTPS_PROXY=$scheme://$http_host/"
|
|||
# For blob requests by digest, do cache, and treat redirects.
|
||||
location ~ ^/v2/(.*)/blobs/sha256:(.*) {
|
||||
set $docker_proxy_request_type "blob-by-digest";
|
||||
add_header X-Docker-Registry-Proxy-Cache-Upstream-Status "$upstream_cache_status";
|
||||
add_header X-Docker-Registry-Proxy-Cache-Type "$docker_proxy_request_type";
|
||||
proxy_pass https://$targetHost;
|
||||
proxy_cache cache;
|
||||
proxy_cache_key $uri;
|
||||
proxy_intercept_errors on;
|
||||
error_page 301 302 307 = @handle_redirects;
|
||||
include "/etc/nginx/nginx.manifest.common.conf";
|
||||
}
|
||||
|
||||
# For manifest requests by digest, do cache, and treat redirects.
|
||||
# These are some of the requests that DockerHub will throttle.
|
||||
location ~ ^/v2/(.*)/manifests/sha256:(.*) {
|
||||
set $docker_proxy_request_type "manifest-by-digest";
|
||||
add_header X-Docker-Registry-Proxy-Cache-Upstream-Status "$upstream_cache_status";
|
||||
add_header X-Docker-Registry-Proxy-Cache-Type "$docker_proxy_request_type";
|
||||
proxy_pass https://$targetHost;
|
||||
proxy_cache cache;
|
||||
proxy_cache_key $uri;
|
||||
proxy_intercept_errors on;
|
||||
error_page 301 302 307 = @handle_redirects;
|
||||
include "/etc/nginx/nginx.manifest.common.conf";
|
||||
}
|
||||
|
||||
# Cache manifest requests that are not by digest (e.g. tags)
|
||||
# Since these are mutable, we invalidate them immediately and keep them only in case the backend is down
|
||||
# These are some of the requests that DockerHub will throttle.
|
||||
location ~ ^/v2/(.*)/manifests/ {
|
||||
set $docker_proxy_request_type "manifest-mutable";
|
||||
add_header X-Docker-Registry-Proxy-Cache-Upstream-Status "$upstream_cache_status";
|
||||
add_header X-Docker-Registry-Proxy-Cache-Type "$docker_proxy_request_type";
|
||||
proxy_pass https://$targetHost;
|
||||
proxy_cache cache;
|
||||
proxy_cache_key $uri;
|
||||
proxy_intercept_errors on;
|
||||
proxy_cache_use_stale error timeout http_500 http_502 http_504 http_429;
|
||||
proxy_cache_valid 0s;
|
||||
error_page 301 302 307 = @handle_redirects;
|
||||
}
|
||||
# Config for manifest URL caching is generated by the entrypoint based on ENVs.
|
||||
# Go check it out, entrypoint.sh
|
||||
include "/etc/nginx/nginx.manifest.caching.config.conf";
|
||||
|
||||
|
||||
# Cache blobs requests that are not by digest
|
||||
# Since these are mutable, we invalidate them immediately and keep them only in case the backend is down
|
||||
location ~ ^/v2/(.*)/blobs/ {
|
||||
set $docker_proxy_request_type "blob-mutable";
|
||||
add_header X-Docker-Registry-Proxy-Cache-Upstream-Status "$upstream_cache_status";
|
||||
add_header X-Docker-Registry-Proxy-Cache-Type "$docker_proxy_request_type";
|
||||
proxy_pass https://$targetHost;
|
||||
proxy_cache cache;
|
||||
proxy_cache_key $uri;
|
||||
proxy_intercept_errors on;
|
||||
proxy_cache_use_stale error timeout http_500 http_502 http_504 http_429;
|
||||
proxy_cache_valid 0s;
|
||||
error_page 301 302 307 = @handle_redirects;
|
||||
include "/etc/nginx/nginx.manifest.stale.conf";
|
||||
}
|
||||
|
||||
location @handle_redirects {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# nginx config fragment included in every manifest-related location{} block.
|
||||
add_header X-Docker-Registry-Proxy-Cache-Upstream-Status "$upstream_cache_status";
|
||||
add_header X-Docker-Registry-Proxy-Cache-Type "$docker_proxy_request_type";
|
||||
proxy_pass https://$targetHost;
|
||||
proxy_cache cache;
|
||||
proxy_cache_key $uri;
|
||||
proxy_intercept_errors on;
|
||||
error_page 301 302 307 = @handle_redirects;
|
|
@ -0,0 +1,3 @@
|
|||
# Just like the common block, but adds proxy_cache_use_stale
|
||||
include "/etc/nginx/nginx.manifest.common.conf";
|
||||
proxy_cache_use_stale error timeout http_500 http_502 http_504 http_429;
|
Loading…
Reference in New Issue