2024年6月6日

SJTUG(上海交通大学 Linux 用户组)宣布下架了其Docker Hub镜像服务。
Docker Hub是Docker官方的镜像存储库,提供给开发者上传/下载容器的镜像。

然而因为某些原因(大家都懂),国内无法直接访问Docker Hub。所以国内一些公司和学校就搭建了许多镜像源来加速下载。

比如:阿里云、腾讯云、网易云、中科大、讯飞、百度等,以及SJTUG。

然而随着SJTUG镜像站的下架,国内使用Docker变得更加困难了,虽然目前还仅限于SJTUG的途径被阻断,国内其他的镜像站还正常运行,但是各种小道消息透露,后续国内其他镜像站也会被下架,还包括 Github CDN 镜像,NPM,Python PIP,OpenWrt OPKG 等未受内容审查的镜像服务器同样也会被下架。

因此,必须找到一种长久的解决办法————自建代理。

以下就是我整理的一种低成本、易部署的搭建教程。
原理是利用一台能够正常访问DockerHub(即能够访问外网)的服务器,在这台服务器上搭建一自己的私有仓库,并利用Nginx代理实现国内访问。

开始搭建

步骤一

准备一台新加坡服务器,我选用的是阿里云的新加坡轻量应用服务器。
2C1G,每月1TB流量,30Mbps带宽——————仅需24元/月。

并且为这台服务器的公网IP购买一个域名,无需备案,提前申请SSL证书(阿里云有免费证书,每年20个,每个有效期3个月)。

步骤二

安装Docker和Docker Compose(这里不做介绍)。
安装Nginx:
sudo apt-get install nginx

步骤三

新建一个目录:
mkdir MyDockerHub
进入目录:
cd MyDockerHub
新建docker-compose.yml文件:
vim docker-compose.yml
写入:

services:
  registry-server:
    image: registry:latest
    container_name: my-docker-registry
    restart: always
    ports:
      - "5000:5000"
    volumes:
      - registry-data:/var/lib/registry
    environment:
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
      REGISTRY_HTTP_ADDR: "0.0.0.0:5000"
      REGISTRY_HTTP_HEADERS_X_Content_Type_Options: "[nosniff]"
      REGISTRY_HTTP_HEADERS_Access_Control_Allow_Origin: "['*']"
      REGISTRY_HTTP_HEADERS_Access_Control_Allow_Methods: "['HEAD', 'GET', 'OPTIONS', 'DELETE']"
      REGISTRY_HTTP_HEADERS_Access_Control_Allow_Headers: "['Authorization', 'Accept', 'Cache-Control']"
      REGISTRY_PROXY_REMOTEURL: "https://registry-1.docker.io"

  registry-ui:
    image: joxit/docker-registry-ui:main
    container_name: registry-ui
    restart: always
    ports:
      - "8000:80"
    environment:
      SINGLE_REGISTRY: "true"
      REGISTRY_TITLE: "Docker Registry UI"
      DELETE_IMAGES: "true"
      SHOW_CONTENT_DIGEST: "true"
      NGINX_PROXY_PASS_URL: "http://registry-server:5000"
      SHOW_CATALOG_NB_TAGS: "true"
      CATALOG_MIN_BRANCHES: "1"
      CATALOG_MAX_BRANCHES: "1"
      TAGLIST_PAGE_SIZE: "100"
      REGISTRY_SECURED: "false"
      CATALOG_ELEMENTS_LIMIT: "1000"

volumes:
  registry-data:

解释一下,这个docker-compose.yml里面定义了两个容器的启动信息:
registry-server容器:使用Docker官方的registry镜像,用来搭建Docker仓库用的。这里指向了Docker官方的Hub地址registry-1.docker.io。
registry-ui容器:使用GitHub开源的registry UI项目提供的joxit/docker-registry-ui,在这里感谢开源作者joxit

接着,启动docker:
docker-compose up -d

验证一下:

步骤四

上传SSL证书到MyDockerHub目录下:

配置Nginx:
vim /etc/nginx/conf.d/registry-proxy.conf
写入:

server {
    listen       80;
    listen       443 ssl;

    ## 填写绑定证书的域名
    server_name  ui.hub.thechen.top;
    ## 证书文件名称(填写你证书存放的路径和名称)
    ssl_certificate /root/MyDockerHub/ui.hub.thechen.top.pem;
    ## 私钥文件名称(填写你证书存放的路径和名称)
    ssl_certificate_key /root/MyDockerHub/ui.hub.thechen.top.key;
    ssl_session_timeout 1d;
    ssl_session_cache   shared:SSL:50m;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    ssl_buffer_size 8k;

    proxy_connect_timeout 600;
    proxy_send_timeout    600;
    proxy_read_timeout    600;
    send_timeout          600;

    location / {
        proxy_pass   http://localhost:8000;
        proxy_set_header  Host $host;
        proxy_set_header  Origin $scheme://$host;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Proto $scheme;
        proxy_set_header  X-Forwarded-Ssl on; # Optional
        proxy_set_header  X-Forwarded-Port $server_port;
        proxy_set_header  X-Forwarded-Host $host;
    }
}

server {
    listen       80;
    listen       443 ssl;

    ## 填写绑定证书的域名
    server_name  hub.thechen.top;
    ## 证书文件名称(填写你证书存放的路径和名称)
    ssl_certificate /root/MyDockerHub/hub.thechen.top.pem;
    ## 私钥文件名称(填写你证书存放的路径和名称)
    ssl_certificate_key /root/MyDockerHub/hub.thechen.top.key;
    ssl_session_timeout 1d;
    ssl_session_cache   shared:SSL:50m;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    ssl_buffer_size 8k;

    proxy_connect_timeout 600;
    proxy_send_timeout    600;
    proxy_read_timeout    600;
    send_timeout          600;

    location / {
        proxy_pass   http://localhost:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        
        proxy_set_header X-Nginx-Proxy true;
        proxy_buffering off;
        proxy_redirect off;
    }
}

检查配置文件语法:
sudo nginx -t

重新加载配置文件:
sudo nginx -s reload

重启Nginx:
sudo systemctl restart nginx
如下是正常的结果:

测试验证————registry ui:
浏览器输出你的ui界面的域名,此时显示的是:0 images in 0 repositories
这是正常的,因为你还没有pull镜像,不会有记录

步骤五

开始配置国内的服务器(需要被加速的服务器)
配置提前安装好Docker环境哦

配置加速地址:
vim /etc/docker/daemon.json

写入:

{
    "registry-mirrors": [
        "https://hub.thechen.top"
    ]
}

重载配置:
sudo systemctl daemon-reload

重启Docker生效:
sudo systemctl restart docker

pull测试:
docker pull mysql

能够成功拉取镜像了,再回UI界面看看,出现了mysql的镜像信息:

点击进去可以查看Docker Hub上的所有mysql的tag版本:

优化建议

  1. 建议添加自定义身份验证功能,比如用户密码验证,实现安全的私有化仓库。
  2. 合理的配置安全组端口,以及请求IP白名单。
  3. 对于高需求的个人/企业,可选购更高配置的云服务器(不是轻量应用服务器),并且可以购买多台,配合负载均衡,实现高并发的请求。

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:https://thechen.work/subject/article/slug_docker_hub/

许可协议:署名-非商业性使用 4.0 国际许可协议