缘起
由于国内的网络环境问题,我们无法直接从dockerhub拉取容器镜像。为了能在国内的电脑上方便地部署一些容器服务,我决定在一台位于国外的服务器上自建一个容器镜像仓库(即Registry)。
方案
Docker官方提供了容器镜像仓库的镜像Registry,我们可以用这个镜像来部署自己的容器镜像仓库。
我们还需要给这个仓库配置一个图形界面,便于查看。网上有不少第三方的图形界面,这里我选用了Joxit/docker-registry-ui。
部署、配置与使用
部署镜像仓库服务
-
部署容器
使用下面的
docker-compose.yml文件来部署镜像仓库服务:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46services: registry-ui: image: joxit/docker-registry-ui:main restart: always ports: - 8002:80 environment: - SINGLE_REGISTRY=true - REGISTRY_TITLE=Docker Registry UI - DELETE_IMAGES=true - SHOW_CONTENT_DIGEST=true - NGINX_PROXY_PASS_URL=http://registry: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 container_name: registry-ui networks: traefik-net: aliases: - registry-ui registry: image: registry:3 container_name: registry restart: always environment: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://registry-ui.jinli.io]' REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]' REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]' REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]' REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]' REGISTRY_STORAGE_DELETE_ENABLED: 'true' volumes: - ${DATA_DIR}:/var/lib/registry networks: traefik-net: aliases: - registry networks: traefik-net: external: true这里我们使用了两个镜像:
registry: Docker官方提供了容器镜像仓库的镜像docker-registry-ui:Joxit开发的第三方镜像仓库图形界面
-
反向代理
我们还是使用之前的Traefik加Cloudflare Tunnel的方案,我们需要为仓库服务和图形界面服务分别配置Traefik。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15http: routers: registry-router: rule: "Host(`registry.example.com`)" entryPoints: - web service: registry-service #tls: # certResolver: le services: registry-service: loadBalancer: servers: - url: "http://registry:5000"1 2 3 4 5 6 7 8 9 10 11 12 13 14 15http: routers: registry-ui-router: rule: "Host(`registry-ui.example.com`)" entryPoints: - web service: registry-ui-service #tls: # certResolver: le services: registry-ui-service: loadBalancer: servers: - url: "http://registry-ui:80"
测试
部署完成后我们可以测试是否进入图形界面,例如上述设置将图形界面发布到了https://registry-ui.example.com。打开浏览器输入上述网址,如果之前设置都正确的话,可以看到下面的页面:

我们还没往仓库里推送镜像,所以显示仓库是空的。
使用
假设容器镜像仓库服务部署到了电脑A上,我们想在电脑B上拉取使用某个镜像。其步骤如下:
电脑A:将镜像发布到仓库
在电脑A上需要如下操作:
- 在本地编译镜像,或者从dockerhub/github等平台拉取镜像。例如从dockerhub拉取
registry镜像:1docker pull registry:3 - 给镜像打上新的标签:
1docker tag registry:3 registry.example.com/registry:3 - 将镜像推送到自建仓库:
1docker push registry.example.com/registry:3
完成上述操作后,可以在https://registry-ui.example.com上看到registry镜像已经成功上传:

电脑B:从我们的仓库拉取镜像
在电脑B上使用Docker时,只需要在所需要的镜像名前加上我们的仓库名registry.example.com/就行了,例如:
|
|
如果使用docker compose也一样,将docker-compose.yml里的镜像名做相应的替换即可。