Skip to content
VDS · Docker 与容器

自建镜像仓库

什么时候需要自建镜像仓库、如何用密码和证书配置它、它占用多少磁盘,以及如何避免它变成旧镜像的垃圾堆。

更新于 2026年8月23日

镜像仓库是存放镜像的存储库。以下三种情况下您需要自建:镜像属于私有、不能离开您的基础设施;构建频繁,外部下载限制造成妨碍;或者您要在多台机器上部署同样的东西。

简单方案:registry:2

services:
  registry:
    image: registry:2
    restart: unless-stopped
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
    volumes:
      - ./data:/var/lib/registry
      - ./auth:/auth:ro
    ports:
      - "127.0.0.1:5000:5000"

这样创建密码:

mkdir -p auth
docker run --rm --entrypoint htpasswd httpd:2 -Bbn deploy 'long-password' > auth/htpasswd
docker compose up -d

不要把端口暴露到外部:镜像仓库前面要放一台带证书的 Web 服务器。Docker 拒绝通过 HTTP 与第三方镜像仓库通信——这是对的,因为可执行代码正是通过它进入您的机器。

使用它

docker login registry.example.com
docker tag myapp:1.5.0 registry.example.com/myapp:1.5.0
docker push registry.example.com/myapp:1.5.0
docker pull registry.example.com/myapp:1.5.0

curl -u deploy https://registry.example.com/v2/_catalog
curl -u deploy https://registry.example.com/v2/myapp/tags/list

执行 docker login 后,凭据以明文存放在 ~/.docker/config.json 中(base64 不是加密)。在构建机器上,请创建一个只有只读权限的单独账户。

没有大小限制、没有清理的镜像仓库,是填满磁盘最快的方式。每次构建都会增加层,而删除标签并不会释放空间:需要垃圾回收。在 40 GB 的 VDS-1 上,活跃项目的镜像仓库会在几周内填满磁盘。

清理

删除标签以及随后的垃圾回收:

docker compose exec registry registry garbage-collect \
  --delete-untagged /etc/docker/registry/config.yml

垃圾回收运行期间必须停止镜像仓库——否则并发的推送可能丢失层:

docker compose stop registry
docker compose run --rm registry registry garbage-collect --delete-untagged /etc/docker/registry/config.yml
docker compose start registry

把它设置为每周执行一次的计划任务,并留意磁盘空间。

替代方案:与 Git 服务器捆绑的镜像仓库

如果您已经配置了 Forgejo 或 Gitea,它们内置了软件包存储,包括 Docker 镜像。您不需要单独的服务:访问走同一套账户,镜像就显示在代码旁边。对于小型项目,这比独立的 registry:2 更方便。

常见错误

  • 镜像仓库未授权即可访问。 通过它,别人可以植入一个会在您自己的生产机器上部署的镜像。
  • 用 latest 标签代替版本号。 镜像仓库不再是可复现性的来源:无法确定究竟部署了什么。参见更新容器。
  • 存储与数据库放在同一块磁盘上。 推送量激增会占满磁盘带宽,拖慢生产服务——参见磁盘速度。
  • ./data 目录不在您的备份中。 您会丢失所有手头没有源码的镜像。参见需要备份什么。