在团队开发、离线环境或 CI/CD 流程中,镜像如果全部依赖公共仓库,可能面临访问速度、网络稳定性和内部镜像泄露等问题。Docker Registry 是用于存储和分发容器镜像的服务端应用,通过私有部署可以统一管理业务镜像、缩短拉取链路,并为发布流程提供可控的镜像来源。本文将从基础部署、持久化、访问认证、TLS 配置到日常使用,介绍一套实用的搭建方案。🚀
一、部署前的准备工作
开始前,需要准备一台已安装 Docker Engine 的 Linux 主机,并确保计划使用的端口未被占用。Registry 默认监听 5000 端口,生产环境建议准备独立域名,例如 registry.example.com,同时配置有效的 HTTPS 证书。若服务器启用了防火墙,还应仅向可信网络或指定客户端开放仓库端口。
先创建数据、认证文件和证书目录:
mkdir -p /opt/registry/data
mkdir -p /opt/registry/auth
mkdir -p /opt/registry/certs
其中,data 用于保存镜像数据,auth 用于存放用户凭据,certs 用于保存 TLS 证书。将这些目录挂载到容器后,即使 Registry 容器被删除,镜像与认证文件也不会随之丢失。
二、快速启动私有镜像仓库
如果只想在受控的测试网络中验证功能,可以先启动一个基础 Registry 实例:
docker run -d --name registry \
-p 5000:5000 \
--restart=always \
-v /opt/registry/data:/var/lib/registry \
registry:2
启动后,可执行以下命令检查服务状态:
docker ps
curl 来源链接
接口返回空 JSON 对象通常表示 Registry V2 API 可以访问。但这种方式既没有身份认证,也没有加密传输,不应直接暴露到公网。Registry 的接口和认证流程可参考 Docker Registry API 文档。
三、创建访问认证账户
Registry 支持通过 htpasswd 文件实施基础访问认证。可以借助 httpd 容器生成采用 bcrypt 哈希的用户密码记录,无需在宿主机额外安装工具:
docker run --rm --entrypoint htpasswd httpd:2 \
-Bbn registryadmin '替换为高强度密码' \
> /opt/registry/auth/htpasswd
-B 表示使用 bcrypt,-n 表示将结果输出到标准输出。实际操作时应使用足够复杂且不与其他系统共用的密码,并限制 htpasswd 文件的读取权限。由于命令行参数可能被终端历史记录或进程列表捕获,更稳妥的方式是在受控环境中使用交互式 htpasswd 工具创建凭据。
如需追加账户,可执行:
docker run --rm --entrypoint htpasswd httpd:2 \
-Bbn developer '替换为另一个强密码' \
>> /opt/registry/auth/htpasswd
基础认证只能验证账户是否有效,不适合实现细粒度的仓库级读写权限。如果企业需要区分项目、团队以及只读账户,应考虑接入支持令牌认证和权限控制的仓库平台。Docker Registry 的标准认证机制可查看 官方认证说明。🔐
四、启用认证并重新部署
删除测试容器不会影响已经挂载到宿主机的数据:
docker rm -f registry
随后使用认证参数重新启动服务:
docker run -d --name registry \
-p 5000:5000 \
--restart=always \
-v /opt/registry/data:/var/lib/registry \
-v /opt/registry/auth:/auth:ro \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry:2
这里将认证目录以只读方式挂载,可以降低容器内进程意外修改凭据文件的风险。完成后,未携带有效身份信息的客户端将无法正常推送或拉取受保护的镜像。
五、使用 HTTPS 保护登录凭据
HTTP Basic Authentication 并不等于传输加密,因此生产环境必须配合 HTTPS。将域名证书和私钥分别保存为 /opt/registry/certs/domain.crt 与 /opt/registry/certs/domain.key 后,可加入以下启动参数:
-v /opt/registry/certs:/certs:ro \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key
推荐使用受客户端信任的证书颁发机构签发证书。若采用内部 CA,需要将 CA 根证书分发到每台 Docker 客户端,并放入对应的证书信任目录。自签名证书若未被客户端信任,通常会出现 x509 证书校验错误。
测试环境虽然可以在 Docker daemon 配置中加入 insecure-registries,但这会降低连接安全性,不宜作为生产解决方案。修改 daemon 配置后还需要重启 Docker 服务,因此操作前应检查该主机上运行中的容器和业务影响。⚠️
六、登录、推送与拉取镜像
客户端首先登录私有仓库。建议交互式输入密码,或在自动化任务中通过标准输入传递密码,避免直接使用明文密码参数:
docker login registry.example.com:5000
登录成功后,为本地镜像添加包含仓库地址的完整标签:
docker tag myapp:1.0 registry.example.com:5000/team/myapp:1.0
推送镜像:
docker push registry.example.com:5000/team/myapp:1.0
在其他已登录且信任仓库证书的主机上,可以执行:
docker pull registry.example.com:5000/team/myapp:1.0
使用完毕后,可通过以下命令清除当前仓库的本地登录信息:
docker logout registry.example.com:5000
Docker 登录凭据通常保存在客户端配置中。共享服务器应配置适当的凭据存储工具,避免多个用户共同使用同一份登录信息;CI/CD 环境则应通过密钥管理系统注入短期或专用凭据,不要把账户密码写入镜像、脚本或代码仓库。
七、运维与故障排查建议
- 无法登录:检查容器日志、用户名、htpasswd 文件路径以及文件挂载权限。
- 推送被拒绝:确认已执行 docker login,并检查镜像标签中的域名和端口是否与登录地址完全一致。
- 证书校验失败:核对证书有效期、域名与 SAN 配置,同时确认客户端已信任签发该证书的 CA。
- 重启后镜像消失:检查 /var/lib/registry 是否正确挂载到宿主机持久化目录。
- 磁盘空间不足:定期监控数据目录容量,并在执行镜像清理或垃圾回收前完成备份和维护评估。
- 安全审计:定期轮换密码、删除离职或停用账户,并限制 Registry 仅允许可信网络访问。
总结
一套可用的 Docker Registry 私有仓库,不只是运行 registry 容器,还应同时具备数据持久化、身份认证、HTTPS 加密、凭据保护、容量监控和备份策略。小型团队可以从 htpasswd 认证方案起步;随着项目数量和权限需求增加,再升级到支持细粒度授权、审计、漏洞扫描及镜像生命周期管理的平台。按照“先隔离网络、再启用认证、最后完善 TLS 与运维”的顺序实施,可以更稳妥地建立内部镜像分发能力。✅