Due to well-known reasons, Docker Hub is no longer accessible for image pulling operations. This article serves as a memorandum, documenting a configuration to unlock the image pulling functionality of Docker Hub without using external image servers. This article assumes that readers are familiar with common operating system software installation methods (apt, yum, apk, brew, etc.), basic Nginx configuration methods, and basic Docker commands. There are many reasons for not using image sites, such as the possibility that image sites may record your pull image history.
Things to Prepare#
- Nginx
- ndk_http_module
- ngx_http_lua_module
- https://www.nslookup.io/ (for obtaining unpolluted IP addresses)
Nginx Configuration#
worker_processes auto;
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_lua_module.so;
events {
worker_connections 1024;
}
http {
upstream production_servers {
server 104.16.99.215:443;
server 104.16.97.215:443;
server 104.16.100.215:443;
server 104.16.98.215:443;
server 104.16.101.215:443;
}
upstream registry_servers {
server 3.94.224.37:443;
server 44.208.254.194:443;
server 98.85.153.80:443;
}
server {
listen 127.0.0.1:9999;
listen [::1]:9999;
server_name localhost;
location / {
proxy_pass https://registry_servers;
proxy_set_header Host registry-1.docker.io;
proxy_buffering off;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_intercept_errors on;
recursive_error_pages on;
error_page 301 302 307 = @handle_redirect;
proxy_ssl_verify off;
header_filter_by_lua_block {
local auth = ngx.header["www-authenticate"]
if auth then
auth = string.gsub(auth,"https://auth.docker.io", "http://localhost:9999")
ngx.header["www-authenticate"] = auth
end
}
}
location /token {
proxy_pass https://registry_servers;
proxy_set_header Host auth.docker.io;
proxy_ssl_verify off;
}
location @handle_redirect {
set $saved_redirect_location '$upstream_http_location';
if ($saved_redirect_location ~ ^(?<protocol>\w+)://(?<domain>[^/]+)(?<path>(/[^?]*)?)(?:\?(?<params>.*))?$) {
proxy_pass $protocol://production_servers$path?$params;
}
proxy_set_header Host production.cloudflare.docker.com;
proxy_ssl_verify off;
}
}
}
Principle#
- SNI removal
- The built-in Docker image server includes localhost
Usage Example#
Note that the default image organization name for dockerhub is written as library, and other images only need to prepend localhost:9999/ to the front.