局域网 Docker 私有镜像仓库:Registry 3.0.0 + Registry UI 部署

局域网 Docker 私有镜像仓库:Registry 3.0.0 + Registry UI 部署

jupiter
2026-09-13 / 0 评论 / 0 阅读 / 正在检测是否收录...

局域网 Docker 私有镜像仓库:Registry 3.0.0 + Registry UI 部署

内网搭一个团队共用的镜像仓库,带 Web 管理界面,支持镜像浏览、搜索、复制 docker pull 命令和 Web 端删除。

1. 规划

项目
部署目录/data/app/docker-registry
Registryregistry:3.0.0,端口 5000
Registry UIbyrdal/registry-ui:latest,端口 3001(容器内 3000)
数据目录./registry-data./registry-ui-data
示例 IP192.168.101.44(换成你自己的)

2. 部署

mkdir -p /data/app/docker-registry && cd /data/app/docker-registry
vi docker-compose.yml
services:
  registry:
    image: registry:3.0.0
    container_name: docker-registry
    restart: always
    ports:
      - "5000:5000"
    environment:
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
    volumes:
      - ./registry-data:/var/lib/registry
    networks:
      - registry-net

  registry-ui:
    image: byrdal/registry-ui:latest
    container_name: registry-ui
    restart: always
    ports:
      - "3001:3000"
    environment:
      REGISTRY_URL: http://registry:5000
      REGISTRY_PUBLIC_URL: localhost:5000
      REGISTRY_TITLE: "局域网镜像仓库"
    volumes:
      - ./registry-ui-data:/data
    depends_on:
      - registry
    networks:
      - registry-net

networks:
  registry-net:
    driver: bridge

几个要留意的点:

  • REGISTRY_STORAGE_DELETE_ENABLED: "true" —— 不开这个,UI 上删除会返回 405
  • REGISTRY_URL 是 UI 后端访问用的,走容器网络所以写服务名 registryREGISTRY_PUBLIC_URL 是给客户端用的,局域网部署请改成 192.168.101.44:5000,否则 UI 上复制出来的 pull 命令是 localhost,别的机器拉不动。
  • depends_on 只保证启动顺序,UI 默认每 10 分钟同步一次,刚推完镜像没刷新的话 docker restart registry-ui 触发一次。

启动:

docker compose up -d
docker compose ps
docker compose logs -f

防火墙放行:

firewall-cmd --permanent --add-port=5000/tcp
firewall-cmd --permanent --add-port=3001/tcp
firewall-cmd --reload

3. 客户端配置

Registry 默认走 HTTPS,局域网用 HTTP 必须在每台推拉镜像的机器上加 insecure-registries

vi /etc/docker/daemon.json
{
  "insecure-registries": ["192.168.101.44:5000"]
}
systemctl daemon-reload
systemctl restart docker
docker info | grep -A 3 "Insecure Registries"
不配会报 http: server gave HTTP response to HTTPS client。Docker Desktop 在 Settings → Docker Engine 里改。

4. 推送 / 拉取测试

# 打标签,格式必须是 <仓库地址>/<镜像名>:<tag>
docker tag alpine:latest 192.168.101.44:5000/alpine:latest
docker push 192.168.101.44:5000/alpine:latest

# 查看仓库与 tag
curl http://192.168.101.44:5000/v2/_catalog
curl http://192.168.101.44:5000/v2/alpine/tags/list

# 另一台机器拉取
docker pull 192.168.101.44:5000/alpine:latest

浏览器打开 http://192.168.101.44:3001 即可看到镜像列表、大小、推送时间,点进去能一键复制 pull 命令。


5. 删除镜像与回收空间

在 UI 上点删除只删了 manifest,磁盘不会立刻释放,必须再跑一次垃圾回收。

# 1. 先在 compose 的 registry.environment 里临时加上只读维护模式,重建容器
#    REGISTRY_STORAGE_MAINTENANCE_READONLY_ENABLED: "true"
docker compose up -d registry

# 2. 先 dry-run 看看要删多少(3.x 配置路径是 /etc/distribution/config.yml)
docker exec docker-registry registry garbage-collect --dry-run /etc/distribution/config.yml

# 3. 确认无误后执行
docker exec docker-registry registry garbage-collect --delete-untagged /etc/distribution/config.yml

# 4. 去掉只读那行,重建
docker compose up -d registry
⚠️ GC 期间若有 push 上传,可能被误判为垃圾删掉,导致"tag 在但 pull 报 blob 404",所以务必先开只读模式。
2.x 的配置路径是 /etc/docker/registry/config.yml,别照抄老教程。

命令行删除(UI 之外的备选):

DIGEST=$(curl -sSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  http://192.168.101.44:5000/v2/alpine/manifests/latest \
  | awk 'tolower($1) == "docker-content-digest:" {print $2}' | tr -d '\r')
curl -X DELETE http://192.168.101.44:5000/v2/alpine/manifests/$DIGEST
0

评论 (0)

打卡
取消