Docker Registry UI

Docker Registry UI 是一个基于Web的用户界面,它提供了一个图形界面来管理 Docker Registry 中的镜像。这对于那些希望以更加直观的方式浏览、搜索和操作Docker镜像的用户来说非常有用。

概述

本项目旨在为您的私有 Docker 仓库提供一个简洁而全面的用户界面。您可以通过多种选项自定义界面,其中主要选项 SINGLE_REGISTRY 允许您禁用 Docker 仓库的动态选择功能(与旧版静态标签行为一致)。

您可能需要查阅 1.x 至 2.x 版本的迁移指南 或 1.x 版本的说明文档 。该项目同时支持 Docker Registry v2 和 Docker Registry v3。

支持的 Docker 标签

  • latest :基于 nginx:alpine 的 Docker Registry UI 最新发布镜像
  • latest -debian:基于 nginx:debian 的 Docker Registry UI 最新发布版镜像
  • main ,master:基于 nginx:alpine 的 Docker Registry UI 测试版镜像
  • main -debian,master-debian: 基于 nginx:debian 的 Docker Registry UI 测试版镜像
  • 2:包含最新发布的 Docker Registry UI v2 镜像(含最新次要及补丁版本)
  • 2.x:包含最新发布的 Docker Registry UI v2.x 镜像(含最新补丁版本)
  • 2.x.y:特定版本的 Docker Registry UI v2.x.y 镜像

隐藏功能

  • 多种方式一次性删除多张图片
    • 通过复选框选择多个标签进行删除。
    • 使用 ALT + Click 不确定的复选框来选择页面上的所有标签。
    • 通过 Shift + Click 第一个标签,再 Shift + Click 第二个标签,选择两者之间的所有连续标签。
  • 显示特定标签的 sha256 值(悬停在图片标签上)。
  • 按数字兼容性排序标签列表(参见 #45 和 #46)。
  • 无需安装即可分享您的 Docker Registry UI,或在部署 UI 时 SINGLE_REGISTRY=false.
    • 使用公共演示版并通过查询参数 url(例如 https://joxit.dev/docker-registry-ui/demo?url=https://registry.example.com)。若需在私有注册表上使用凭据,必须将 Access-Control-Allow-Origin设置为 https://joxit.dev
  • 您可以通过单一界面管理多个 Registry ,只需在页面右上角的菜单中添加它们即可。
  • 通过搜索栏筛选图片和标签。
  • 您可以使用快捷键 CTRL + FF3 来选中搜索栏。当搜索栏已处于聚焦状态时,快捷键将恢复默认行为。
  • 历史页面支持多架构。
  • 显示 Dockerfile 的内容。
  • 用户界面将缓存来自您的 Registry 的请求,例如 blob 和部分清单(带有 sha256: 的 URL)。

常见问题解答

  • SINGLE_REGISTRY=falseSINGLE_REGISTRY=true 选项有什么区别 ?
    • 当 SINGLE_REGISTRY 设置为 false 时,界面上会出现一个菜单,允许您动态更改 docker registry 的 URL。
  • 为什么当我删除一个镜像的所有标签后,该镜像仍显示在用户界面中?
    • 这是 Docker Registry 的一个限制,垃圾回收器不会移除空镜像。若需删除悬空镜像,您需手动删除 Registry 数据中的对应文件夹。
  • 为什么 UI 中显示的镜像大小与通过 docker images 命令获取的,显示的不一致?
    • 用户界面显示的是镜像的压缩后大小,而非解压后的版本大小。
  • 我可以在用户界面上使用 HTTPS 吗?
    • 是的,在用户界面(UI)前端部署您偏好的反向代理即可。该反向代理将负责处理 HTTPS 连接。
  • UI 是否支持认证?
    • 是的,但它仅支持基础认证。这是一个简单的独立前端,将通过您的浏览器窗口进行身份验证。
  • 我能否在不安全的 registry (非 HTTPS 的 registry URL)上使用 UI 和 docker 客户端?
    • 是的,你可以使用,但首先需要配置你的 Docker 客户端。
  • 混合内容错误是什么意思?
    • 这意味着您当前使用的是 HTTPS 用户界面,而注册表服务仍在使用 HTTP(未加密)。当您访问 HTTPS 网站时,无法加载 HTTP 内容。请将注册表升级为 HTTPS 连接以确保安全。
  • 为什么默认的 nginx设置为$http_host ?
    这解决了问题 #88。更多详情请见 #113。
  • 为什么 OPTIONS(即预检请求)和 DELETE 请求在使用基本认证时会失败并返回 401 状态码,或者为什么用户界面提示我检查我的 Access-Control-Allow-Origin ?
    • 此问题源于 Docker Registry 的一个缺陷,它会在预检请求时返回 401 状态码,这违反了 W3C 预检请求规范 。我已联系 Docker Registry 维护者,但此问题将不会被修复(参见 distribution/distribution#4458)。建议您将用户界面与注册表置于同一域名下,例如 registry.example.com/ui/,或者使用 NGINX_PROXY_PASS_URL,亦或在注册表前配置 nginx/apache/haproxy,使其对所有 OPTIONS 请求返回 200 状态码(详见 #104,#204,#207,#214,#266,#278)。
  • 我可以将 Docker 注册表 UI 作为绿色软体(使用 Electron)使用吗?
    • 是的,查看示例 此处 。(参见 #129)
  • 我通过 UI 删除了镜像,但它们仍然存在于服务器上。我该如何彻底删除它们?
    • 通过用户界面删除镜像时,仅会删除引用而非实际内容。若要清除残留的镜像文件,需运行注册表的垃圾回收器,执行命令‘registry garbage-collect config.yml‘或‘docker exec registry registry garbage-collect config.yml‘(参见 #77、#147)。
  • 为什么当我删除一个标签时,所有具有相同 SHA 的标签也会被删除?
    This a docker registry API limitation, there is only one way to delete images with tag, it’s by its name and its manifest (it’s a sha of the content). So when you delete a tag, this will delete all tags of this image with the same SHA/manifest.
  • 我可以用非特权用户运行容器吗?
    是的,您可以通过添加选项‘——user nginx‘以 nginx 用户身份运行容器,同时该操作会将监听端口更新为 8080(参见 #224 和 #234)。
  • 我是否可以在使用 Docker Hub 镜像时使用 UI 并显示library/* images ?
    可以,但使用两个注册服务器存在风险,需自行承担,请参阅评论 #155。
  • 如何修复 S3 存储桶上的 CORS 问题?
    您应该在您的存储桶上添加 CORS 策略,请查看问题 #193。
  • 为什么我的 Docker 注册服务器返回错误pagination number invalid ?
    自 Docker 注册表服务器 2.8.2 版本起,目录中默认限制为 1000 个镜像。若需更多镜像,请更新配置项 REGISTRY_CATALOG_MAXENTRIES 为您所需的最大值,并查阅问题 #306。
  • 我正在使用我的注册表服务器已重新创建,但 UI 无法连接,并显示消息,我该怎么办?
    Nginx 在运行时仅获取所有地址的 IP 一次,由于您的容器已重新创建,其 IP 也随之变更。为避免此类问题,您可使用 NGINX_RESOLVER 选项并将其设置为 127.0.0.11。

可用选项

您可以使用非特权用户 nginx 运行容器,详情请参阅讨论 #224。

部分环境变量选项可用于将此界面仅用于单一服务器(当 SINGLE_REGISTRY=true 时)。

  • REGISTRY_URL: Docker Registry 的默认 URL。您可能需要在 Docker Registry 上配置 CORS(跨源资源共享)。这通常是您的计算机可访问的注册表域名或 IP 地址(例如 http://registry.example.com)。(默认值:从您的 UI 主机名派生)
  • REGISTRY_TITLE:为您的用户界面设置自定义标题。(默认值:源自 REGISTRY_URL 的值)(参见 #28 和 #32)。自 0.3.4 版本起
  • PULL_URL:设置自定义 URL,用于复制 docker pull 命令时使用(参见 #71)。(默认值:从 REGISTRY_URL 派生)。自 1.1.0 版本起
  • DELETE_IMAGES: 设置是否允许通过用户界面删除镜像。(默认值:false)
  • SHOW_CONTENT_DIGEST:在 Docker 标签列表中显示 / 隐藏内容摘要(参见 #126 和 #131)。(默认值:false)。自 1.4.9 版本起
  • CATALOG_ELEMENTS_LIMIT:限制目录页面中的元素数量(参见 #39、#127、#132 和 #306)。(默认值:1000)。自 1.4.9 版本起
  • SINGLE_REGISTRY:移除显示用于添加、删除及更改 Docker 注册表端点对话框的菜单(默认值:false)。自 2.0.0 版本起
  • NGINX_PROXY_PASS_URL:更新默认的 Nginx 配置,将 proxy_pass 设置为您的后端 Docker Registry(这避免了 CORS 配置)。通常,这是您 Registry 容器的名称,格式为 http://registry:5000。自 2.0.0 版本起
  • NGINX_PROXY_HEADER_*:通过环境变量和文件(/etc/nginx/.env)更新默认 Nginx 配置,为后端 Docker 仓库设置自定义头部。仅在启用 NGINX_PROXY_PASS_URL 时生效(参见 #89)。自版本 1.2.3 起支持
  • NGINX_PROXY_PASS_HEADER_*:通过环境变量和文件(/etc/nginx/.env)更新默认 Nginx 配置,并将自定义头部转发至您的后端 Docker 注册表。仅当使用 NGINX_PROXY_PASS_URL 时生效(参见 #206)。自 2.1.0 版本起支持。
  • NGINX_LISTEN_PORT:监听非 80 端口的设置,您还可以更改默认用户并设置为 nginx ——user nginx(参见 #224 和 #234)。(默认值:当用户为 root 时为 80,否则为 8080)。自 2.2.0 版本起
  • NGINX_RESOLVER:在 nginx 配置中添加 resolver 指令以实现动态 DNS 解析。当使用 Docker 网络时,其值为 127.0.0.11,您也可以设置一个带有有效时间的自定义 DNS 服务器。若使用 Kubernetes 则无需此配置(参见 #333 和 #339)。(默认值:“)。自 2.5.5 版本起支持。
  • DEFAULT_REGISTRIES:以逗号分隔的注册表 URL 列表(例如 http://registry.example.com,http://registry:5000),仅在 SINGLE_REGISTRY=false 时可用(参见 #219)。(默认值:)。自 2.1.0 版本起
  • READ_ONLY_REGISTRIES:禁用添加和删除新注册表的对话框,仅在 SINGLE_REGISTRY=false 时可用(参见 #219)。(默认值:false)。自 2.1.0 版本起
  • SHOW_CATALOG_NB_TAGS:在目录页显示每张图片的标签数量,并隐藏无标签的图片。此操作会增加图片请求次数,不建议用于大型注册表(参见 #161 和 #239)。(默认值:false)。自 2.2.0 版本起。
  • HISTORY_CUSTOM_LABELS:在历史页面展示自定义标签,这些标签将按照维护者标签的方式处理(参见 #160 和 #240)。自 2.2.0 版本起生效。
  • USE_CONTROL_CACHE_HEADER:使用 Control-Cache 头并设置为 no-store,no-cache。这将避免多架构镜像的一些问题(参见 #260 和 #265)。此选项需要注册表配置:Access-Control-Allow-Headers 需包含 Cache-Control。(默认值:false)。自 2.3.0 版本起生效。
  • THEME :选择您的默认主题,可以是暗色、亮色或自动(参见 #283)。当选择自动时,您将获得一个手动切换亮暗模式的开关(参见 #291)。(默认值:自动)。自 2.4.0 版本起
  • THEME_*:参见 主题选项 章节中的表格(详见 #283)。自 2.4.0 版本起
  • TAGLIST_ORDER:设置标签列表页的默认排序方式,可选值为 num-asc;alpha-asc、num-desc;alpha-asc、num-asc;alpha-desc、num-desc;alpha-desc、alpha-asc;num-asc、alpha-asc;num-desc、alpha-desc;num-asc 或 alpha-desc;num-desc(参见 #307)。(默认值:alpha-asc;num-desc)。自 2.5.0 版本起
  • CATALOG_DEFAULT_EXPANDED : 默认展开目录中所有仓库(参见 #302)。(默认值:false)。自 2.5.0 版本起
  • CATALOG_MIN_BRANCHES:设置需展开的最小仓库 / 命名空间(例如 joxit/docker-registry-ui 中 joxit / 即为仓库 / 命名空间)。若将最小与最大值均设为 0 可禁用分支功能(参见 #319)。(默认值:1)。自 2.5.0 版本起生效
  • CATALOG_MAX_BRANCHES:设置最大仓库 / 命名空间展开数量(例如 joxit/docker-registry-ui 中 joxit / 即为仓库 / 命名空间)。若将最小值和最大值均设为 0 可禁用分支功能(参见 #319)。(默认值:1)。自 2.5.0 版本起生效
  • TAGLIST_PAGE_SIZE: 设置每页显示的标签数量。(默认值:100)。自 2.5.0 版本起
  • REGISTRY_SECURED:默认情况下,用户界面会在每次请求时检查您的注册表是否安全(您将在控制台中看到 401 响应)。如果您的注册表使用基本身份验证,请将此值设为 true,从而将调用注册表的次数减半。(默认值为 false)。自 2.5.0 版本起生效。
  • SHOW_TAG_HISTORY:是否显示标签历史功能。若设置为 false,可通过在标签列表中隐藏此功能来简化用户界面(默认值:true)。 参考示例:docker-compose 与作为代理的 docker-registry-ui 此处 ,或作为独立应用的 docker-registry-ui 此处 。
  • DOCKER_REGISTRY_UI_TITLE: 设置显示在标题栏中的自定义标题。(默认值:Docker Registry UI)。
  • ENABLE_VERSION_NOTIFICATION:当 Docker Registry UI 有新版本可用时显示通知。此检查每周执行一次。(默认值:true)

主题选项

此功能已添加至版本 2.4.0。

环境变量 浅色主题值 深色主题值
THEME_PRIMARY_TEXT #25313b #98a8bd
THEME_NEUTRAL_TEXT #777777 #6d7fab
THEME_BACKGROUND #ffffff #22272e
THEME_HOVER_BACKGROUND #eeeeee #343a4b
THEME_ACCENT_TEXT #5f7796 #5c88ff
THEME_HEADER_TEXT #ffffff #ffffff
THEME_HEADER_ACCENT_TEXT #7b9ac2 #7ea1ff
THEME_HEADER_BACKGROUND #25313b #333a45
THEME_FOOTER_TEXT #ffffff #ffffff
THEME_FOOTER_NEUTRAL_TEXT #adbacd #98afcf
THEME_FOOTER_BACKGROUND #344251 #344251

Docker 方式部署 Docker Registry UI

1. 部署 Docker Registry【已安装可跳过】

首先,确保你的环境中已经安装了Docker Registry。如果还没有安装,可以通过以下命令安装:

docker pull registry

然后运行 Docker Registry:

docker rm -f registry-srv &>/dev/null;
docker run -d --restart=always -p 5000:5000 --name registry-srv registry:latest
docker logs -f registry-srv ;

2. 部署 Docker Registry UI

Docker Registry UI可以通过Docker镜像直接运行。你可以从Docker Hub上获取这个镜像:

docker pull joxit/docker-registry-ui:latest

运行** Docker Registry UI** 时,你需要指定一些环境变量来连接你的 Docker Registry。例如,如果你的Registry运行在本地并监听5000端口,你可以这样运行 Registry UI:

# registry-ui
docker rm -f registry-ui  &>/dev/null
docker run -d --name registry-ui \
--restart=always \
--memory 128M \
-p 8080:80 \
-v /etc/localtime:/etc/localtime:ro \
-e REGISTRY_URL=https://localhost:5000 \
-e DELETE_IMAGES=true \
-e REGISTRY_TITLE="Docker Registry" \
joxit/docker-registry-ui:latest;
docker logs -f registry-ui;

这里的环境变量解释如下:

  • REGISTRY_URL: Docker Registry的地址。根据你的配置,这可能需要是公网地址或者局域网地址。
  • DELETE_IMAGES: 是否允许删除镜像。设置为false可以禁用删除功能,增加安全性。

3. 访问 Docker Registry UI

打开你的浏览器,访问 http://localhost:8080 来访问 Docker Registry UI。你应该能看到一个列出所有可用镜像的界面。

如果你的 Docker Registry 不是在本地,例如在:192.168.3.123:5000,那你一定会遇到,用户界面提示检查我的 Access-Control-Allow-Origin 问题

我的解决方法是指定,NGINX_PROXY_PASS_URL 参数

# registry-ui
docker rm -f registry-ui  &>/dev/null
docker run -d --name registry-ui \
--restart=always \
--memory 128M \
-p 8080:80 \
-v /etc/localtime:/etc/localtime:ro \
-e PULL_URL=https://registry.baomagangwan.com \
-e NGINX_PROXY_PASS_URL=http://192.168.3.123:5000 \
-e DELETE_IMAGES=true \
-e REGISTRY_TITLE="Docker Registry" \
joxit/docker-registry-ui:latest;
docker logs -f registry-ui;
  • PULL_URL:设置自定义 URL,用于复制 docker pull 命令时使用
  • NGINX_PROXY_PASS_URL:覆盖 Docker Registry UI 默认的 Nginx 配置,将 proxy_pass 设置为 Docker Registry的地址,避免 CORS 配置
  • DELETE_IMAGES: 设置是允许通过用户界面删除镜像。
  • REGISTRY_TITLE:设置用户界面自定义标题。

最后,为了保持在开发环境(私有镜像服务)的镜像地址与生产环境镜像(商业镜像服务)地址一致,我在 192.168.3.123 本地服务器安装了 宝塔Linux面板,并安装 Nginx , 配置Nginx 进行反向代理:

server
{
    listen 80;
    listen 443 ssl;
    listen 443 quic;
    http2 on;
    server_name registry.baomagangwan.com;
    index index.php index.html index.htm default.php default.htm default.html;
    root /www/wwwroot/registry.baomagangwan.com;
    #CERT-APPLY-CHECK--START
    # 用于SSL证书申请时的文件验证相关配置 -- 请勿删除
    include /www/server/panel/vhost/nginx/well-known/registry.baomagangwan.com.conf;
    #CERT-APPLY-CHECK--END
    include /www/server/panel/vhost/nginx/extension/registry.baomagangwan.com/*.conf;

    #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
    #error_page 404/404.html;
    #HTTP_TO_HTTPS_START
    set $isRedcert 1;
    if ($server_port != 443) {
        set $isRedcert 2;
    }
    if ( $uri ~ /\.well-known/ ) {
        set $isRedcert 1;
    }
    if ($isRedcert != 1) {
        rewrite ^(/.*)$ https://$host$1 permanent;
    }
    #HTTP_TO_HTTPS_END
    ssl_certificate    /www/server/panel/vhost/cert/registry.baomagangwan.com/fullchain.pem;
    ssl_certificate_key    /www/server/panel/vhost/cert/registry.baomagangwan.com/privkey.pem;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_tickets on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    add_header Strict-Transport-Security "max-age=31536000";
    add_header Alt-Svc 'quic=":443"; h3=":443"; h3-29=":443"; h3-27=":443";h3-25=":443"; h3-T050=":443"; h3-Q050=":443";h3-Q049=":443";h3-Q048=":443"; h3-Q046=":443"; h3-Q043=":443"';
    error_page 497  https://$host$request_uri;

    #SSL-END

    #ERROR-PAGE-START  错误页配置,可以注释、删除或修改
    error_page 404 /404.html;
    #error_page 502 /502.html;
    #ERROR-PAGE-END

    #PHP-INFO-START  PHP引用配置,可以注释或修改
    include enable-php-00.conf;
    #PHP-INFO-END

    #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
    include /www/server/panel/vhost/rewrite/registry.baomagangwan.com.conf;
    #REWRITE-END

    #禁止访问的文件或目录
    location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md)
    {
        return 404;
    }

    #一键申请SSL证书验证目录相关设置
    location ~ \.well-known{
        allow all;
    }

    #禁止在证书验证目录放入敏感文件
    if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
        return 403;
    }

    location ^~ / {
      proxy_pass http://192.168.3.123:5000;
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Real-Port $remote_port;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Port $server_port;
      proxy_set_header REMOTE-HOST $remote_addr;

      proxy_connect_timeout 60s;
      proxy_send_timeout 600s;
      proxy_read_timeout 600s;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
    }
    access_log  /www/wwwlogs/registry.baomagangwan.com.log;
    error_log  /www/wwwlogs/registry.baomagangwan.com.error.log;
}

Docker-Compose 方式部署 Docker Registry UI

以下是一个使用 docker-compose 简单部署 Docker Registry UIDocker Registry Server 的示例。该方案适用于大多数应用场景,且用户界面将与注册表服务部署在同一域名下。

version: '3.8'
services:
  registry-ui:
    image: joxit/docker-registry-ui:main
    restart: always
    ports:
      - 8080: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
    container_name: registry-ui
  registry-server:
    image: registry:latest
    restart: always
    environment:
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://registry-ui.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]'
      REGISTRY_STORAGE_DELETE_ENABLED: 'true'
    volumes:
      - ./registry/data:/var/lib/registry
    container_name: registry-server

然后运行:

docker-compose up -d

这将在后台启动 RegistryRegistry UI。通过上述步骤,你应该能够成功部署并访问 Docker Registry UI

作者:Jeebiz  创建时间:2025-12-09 17:00
最后编辑:Jeebiz  更新时间:2025-12-10 15:39