吃枣药丸

吃枣药丸

Docker Hub Direct Access Unlock Guide for Mainland China

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 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.
Screenshot 2025-06-04 17.43.39

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.