安装register和register-ui

通过docker-compose安装registerdocker-register-ui

version: "3"

networks:
  registry:
    driver: bridge

x-app: &common
  restart: always
  logging:
    driver: "json-file"
    options:
      max-size: "200k"
      max-file: "10"
  networks:
    - registry

services:
  registry:
    <<: *common
    image: registry:2
    container_name: registry
    volumes:
      - ./registry:/var/lib/registry
    environment:
      # 允许API访问和删除镜像
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[https://registry.example.com]'
      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]'
      # 通过摘要删除图像 blob 和清单
      REGISTRY_STORAGE_DELETE_ENABLED: true
      # 定期从注册表的上传目录中删除孤立文件
      REGISTRY_STORAGE_MAINTENANCE: |-
        uploadpurging:
            enabled: true
            age: 168h
            interval: 24h
            dryrun: false
        readonly:
            enabled: false        
    ports:
      - 5000:5000
    healthcheck:
      test: "wget -q --spider --proxy off 0.0.0.0:5000/v2 || exit 1"
      interval: 5s
      timeout: 10s
      retries: 10

  registry-ui:
    <<: *common
    image: joxit/docker-registry-ui
    container_name: registry-ui
    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
    ports:
      - 80:80
    depends_on:
      registry:
        condition: service_healthy

通过docker-compose up -d启动容器。

默认register和register ui都未设置身份认证,可以在nginx上统一设置basic认证。

注意:registry ui会自动代理register,所以只需要将registry ui的端口暴露到外部网络即可

此时便可通过 https://服务器IP或域名:registry-ui的端口号 访问docker register ui了。

命令行则通过docker login 服务器IP或域名:registry ui的端口号进行认证

docker login registry.example.com

docker pull hello-world:latest

docker tag hello-world:latest registry.example.com/hello-world:latest

docker push registry.example.com/hello-world:latest

docker pull registry.example.com/hello-world:latest

常用API

镜像列表: https://register.example.com/v2/_catalog

标签列表: https://register.example.com/v2/镜像名/tags/list

清理悬空镜像

由于 docker 注册表的限制,垃圾收集器不会删除空镜像。如果要删除悬空镜像,则需要删除注册表数据中的文件夹。

我准备了一个sh脚本 docker-registry-gc.sh,可在界面删除镜像后执行该脚本删除文件夹。

docker exec -it registry sh -c "wget -qO- https://liwt.top/script/docker-registry-gc.sh | sh"