跳到主要内容

私有Docker Registry设置指南

简介

本文档详细记录了如何设置和配置私有Docker Registry的过程。私有Docker Registry允许你在本地网络中存储和管理Docker镜像,无需依赖公共Docker Hub,适用于内部开发、测试环境或对安全性有较高要求的场景。

目标

  • 设置一个基本的私有Docker Registry
  • 配置持久化存储
  • 验证Registry的功能
  • 了解进阶配置选项

前提条件

  • 已安装Docker
  • 具有root或sudo权限
  • 基本的命令行操作知识

1. 创建持久化存储目录

首先,我们需要创建一个目录来持久化存储Registry的数据:

mkdir -p /workspace/docker-registry/data

2. 启动Docker Registry容器

使用官方的Registry镜像启动一个容器,并将其配置为使用我们创建的持久化存储目录:

docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /workspace/docker-registry/data:/var/lib/registry \
registry:2

这个命令的参数说明:

  • -d: 在后台运行容器。
  • -p 5000:5000: 将容器的5000端口映射到主机的5000端口,这样外部可以通过访问主机的5000端口来使用Registry。
  • --restart=always: 设置容器在Docker重启时自动重启。
  • --name registry: 为容器指定一个名称,方便后续管理。
  • -v /workspace/docker-registry/data:/var/lib/registry: 将主机上的目录挂载到容器中,用于持久化存储镜像数据。
  • registry:2: 使用官方Registry镜像的版本2。

3. 验证Registry是否正常运行

检查容器是否正在运行:

docker ps | grep registry

如果一切正常,你应该能看到类似以下输出:

CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS         PORTS                    NAMES
abcdef123456 registry:2 "/entrypoint.sh /etc…" 1 minute ago Up 1 minute 0.0.0.0:5000->5000/tcp registry

4. 推送镜像到私有Registry

4.1 拉取一个测试镜像

我们使用Alpine Linux镜像作为测试:

docker pull alpine:latest

4.2 为镜像添加私有Registry的标签

docker tag alpine:latest localhost:5000/my-alpine:latest

4.3 推送镜像到私有Registry

docker push localhost:5000/my-alpine:latest

成功推送后,你应该能看到类似以下输出:

The push refers to repository [localhost:5000/my-alpine]
24302eb7d908: Pushed
latest: digest: sha256:e9e9d51e25e4343f56b64d5ef1717234ec62241d93bf59734c53b4108b5c19ca size: 528

5. 验证镜像是否成功存储

5.1 删除本地镜像

为了验证我们可以从私有Registry拉取镜像,先删除本地的镜像:

docker image remove alpine:latest
docker image remove localhost:5000/my-alpine:latest

5.2 从私有Registry拉取镜像

docker pull localhost:5000/my-alpine:latest

如果一切正常,你应该能成功拉取镜像:

latest: Pulling from my-alpine
Digest: sha256:e9e9d51e25e4343f56b64d5ef1717234ec62241d93bf59734c53b4108b5c19ca
Status: Downloaded newer image for localhost:5000/my-alpine:latest
localhost:5000/my-alpine:latest

5.3 验证持久化存储

检查Registry的数据目录,确认镜像数据已经正确存储:

ls -la /workspace/docker-registry/data/docker/registry/v2/repositories

你应该能看到my-alpine目录,表示镜像已经成功存储。进一步查看标签信息:

ls -la /workspace/docker-registry/data/docker/registry/v2/repositories/my-alpine/_manifests/tags

你应该能看到latest标签。

6. 进阶配置选项

6.1 启用HTTPS

在生产环境中,强烈建议为Registry配置HTTPS。这需要:

  • 获取SSL证书(可以使用Let's Encrypt等服务)
  • 配置Registry使用这些证书

基本步骤:

  1. 准备证书文件。
  2. 修改Registry启动命令,添加证书挂载:
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /workspace/docker-registry/data:/var/lib/registry \
-v /path/to/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2

6.2 配置访问认证

添加基本的用户名/密码认证:

  1. 创建密码文件:
mkdir -p /workspace/docker-registry/auth
docker run --rm --entrypoint htpasswd httpd:2 -Bbn username password > /workspace/docker-registry/auth/htpasswd
  1. 重新启动Registry,启用认证:
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /workspace/docker-registry/data:/var/lib/registry \
-v /workspace/docker-registry/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
registry:2

6.3 配置存储限额

可以通过环境变量配置存储限额:

docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /workspace/docker-registry/data:/var/lib/registry \
-e REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry \
-e REGISTRY_STORAGE_DELETE_ENABLED=true \
-e REGISTRY_STORAGE_MAINTENANCE_READONLY_ENABLED=false \
registry:2

7. 故障排除

7.1 无法推送或拉取镜像

  • 检查Registry容器是否正在运行。
  • 确认端口映射是否正确。
  • 如果使用HTTPS,确保证书配置正确。
  • 检查防火墙设置。

7.2 查看Registry日志

docker logs registry

7.3 常见错误

  • 无法连接到Registry: 检查网络配置和防火墙设置。
  • 认证失败: 检查用户名和密码是否正确。
  • 存储空间不足: 检查磁盘空间。

8. 使用 docker-compose 部署私有 Docker Registry

8.1 创建 docker-compose.yml 文件

/workspace/docker-registry 目录下创建一个名为 docker-compose.yml 的文件,并添加以下内容:

version: '3'

services:
registry:
image: registry:2
ports:
- "5000:5000"
volumes:
- /workspace/docker-registry/data:/var/lib/registry
restart: always

auth:
image: jwilder/nginx-proxy
ports:
- "80:80"
volumes:
- /etc/nginx/conf.d:/etc/nginx/conf.d
- /etc/nginx/vhost.d:/etc/nginx/vhost.d
- /var/run/docker.sock:/tmp/docker.sock:ro

htpasswd:
image: registry:2
command: htpasswd -Bbn username password > /auth/htpasswd
volumes:
- /workspace/docker-registry/auth:/auth

8.2 启动服务

/workspace/docker-registry 目录下运行以下命令启动服务:

docker-compose up -d

这将启动 Registry、Nginx 和 Htpasswd 容器。

9. 验证部署

9.1 检查容器是否正在运行

docker-compose ps

你应该能看到类似以下输出:

Name                    Command                  State           Ports
--------------------------------------------------------------------------------
docker-registry_auth_1 /app/docker-entrypoint.sh ... Up 0.0.0.0:80->80/tcp
docker-registry_htpasswd_1 registry:2 htpasswd -Bbn username password > /auth/htpasswd Up
docker-registry_registry_1 /entrypoint.sh /etc/docker/... Up 0.0.0.0:5000->5000/tcp

9.2 验证 Registry 是否正常运行

curl -I http://localhost:5000/v2/

你应该能看到类似以下输出:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Registry Realm"
Content-Length: 19
Content-Type: application/json; charset=utf-8
Date: Mon, 04 Jul 2025 00:00:00 GMT

10. 客户端配置

10.1 配置 Docker 客户端

编辑 ~/.docker/config.json 文件,添加以下内容:

{
"auths": {
"http://localhost:5000": {
"username": "username",
"password": "password"
}
}
}

10.2 测试推送和拉取镜像

推送镜像
docker pull alpine:latest
docker tag alpine:latest localhost:5000/my-alpine:latest
docker push localhost:5000/my-alpine:latest
拉取镜像
docker image remove alpine:latest
docker image remove localhost:5000/my-alpine:latest
docker pull localhost:5000/my-alpine:latest

如果一切正常,你应该能看到类似以下输出:

latest: Pulling from my-alpine
Digest: sha256:e9e9d51e25e4343f56b64d5ef1717234ec62241d93bf59734c53b4108b5c19ca
Status: Downloaded newer image for localhost:5000/my-alpine:latest
localhost:5000/my-alpine:latest

11. 总结

通过使用 docker-compose,我们成功部署了一个私有 Docker Registry,并配置了客户端。这种方式简化了服务的管理和部署过程。

私有Docker Registry为团队提供了一个安全、可控的Docker镜像存储和分发平台,特别适合内部开发和测试环境。

12. 参考资源