把一个 OpenResty 站点变成 Docker Hub 镜像
TL;DR
将下面的代码粘贴到 OpenResty 站点配置 (server { } 块)内即可。
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
client_max_body_size 0;
chunked_transfer_encoding on;
resolver 8.8.8.8 1.1.1.1 valid=300s;
location /token {
proxy_pass https://auth.docker.io;
proxy_set_header Host auth.docker.io;
proxy_ssl_server_name on;
}
location /v2/ {
proxy_pass https://registry-1.docker.io;
proxy_set_header Host registry-1.docker.io;
proxy_ssl_server_name on;
proxy_set_header Authorization $http_authorization;
proxy_hide_header WWW-Authenticate;
add_header WWW-Authenticate 'Bearer realm="https://$http_host/token",service="registry.docker.io"' always;
proxy_redirect ~^https://([^/]+)/(.*)$ /blob/$1/$2;
proxy_buffering off;
proxy_read_timeout 900;
}
location ~ ^/blob/(?<blob_host>[^/]+)/(?<blob_path>.*)$ {
access_by_lua_block {
local host = ngx.var.blob_host
local allowed = host:match("%.docker%.io$")
or host:match("%.docker%.com$")
or host:match("%.cloudflare%.docker%.com$")
or host:match("%.amazonaws%.com$")
or host == "docker.io"
if not allowed then
ngx.log(ngx.WARN, "rejected proxy target: ", host)
return ngx.exit(403)
end
}
proxy_pass https://$blob_host/$blob_path$is_args$args;
proxy_set_header Host $blob_host;
proxy_ssl_server_name on;
proxy_ssl_name $blob_host;
proxy_buffering off;
proxy_read_timeout 900;
}
补充说明
缓存问题
这个代码只是作为反向代理,使得 Docker 可以透过它去拉取镜像,并不会真的将镜像存储于你的服务器,所以每次请求的时候都会真的走一遍完整的流量,通过 CloudFlare + 缓存控制可缓解该问题。