私有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使用这些证书
 
基本步骤:
- 准备证书文件。
 - 修改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 配置访问认证
添加基本的用户名/密码认证:
- 创建密码文件:
 
mkdir -p /workspace/docker-registry/auth
docker run --rm --entrypoint htpasswd httpd:2 -Bbn username password > /workspace/docker-registry/auth/htpasswd
- 重新启动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镜像存储和分发平台,特别适合内部开发和测试环境。