问题背景

昨天机房服务器意外重启后,发现Docker本地的容器、镜像以及私有仓库中的镜像全部丢失。经过排查,根本原因是Docker配置未做持久化存储,导致数据存储在临时文件系统中,重启后数据自然清空。今天记录完整的恢复和加固过程。

解决方案概览

重建Docker Registry私有仓库

配置持久化存储卷

搭建可视化管理界面

重新构建和上传镜像

详细实施步骤

  1. 创建必要的目录结构
# 创建registry数据存储目录
mkdir -p /data1/docker/registry

# 创建认证文件目录(如果需要认证)
mkdir -p /root/docker-registry/auth

如果需要认证,生成htpasswd文件:

docker run --rm \
  --entrypoint htpasswd \
  httpd:2 -Bbn username password > /root/docker-registry/auth/htpasswd
  1. 创建docker-compose.yml配置文件

在合适位置创建docker-compose.yml文件,内容如下:

version: '3.8'
services:
  registry:
    image: registry:latest
    container_name: registry
    restart: always
    ports:
      - "5000:5000"
    volumes:
      - /data1/docker/registry:/var/lib/registry
      - /root/docker-registry/auth:/auth
    environment:
      REGISTRY_TRACING_ENABLED: "false"
      REGISTRY_STORAGE_DELETE_ENABLED: true
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: 'Registry Realm'
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://192.168.100.104:5001]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'
      REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'

  registry-ui:
    image: joxit/docker-registry-ui:main
    container_name: registry-ui
    restart: always
    ports:
      - 5001:80
    environment:
      - SINGLE_REGISTRY=true
      - REGISTRY_TITLE=Docker Registry UI
      - REGISTRY_URL=http://registry:5000
      - DELETE_IMAGES=true
      - SHOW_CONTENT_DIGEST=true
      - SHOW_CATALOG_NB_TAGS=true
      - TAGLIST_PAGE_SIZE=100
      - CATALOG_ELEMENTS_LIMIT=1000
      - REGISTRY_SECURED=false
  1. 关键配置解析
    持久化存储配置
volumes:
  - /data1/docker/registry:/var/lib/registry

这是防止数据丢失的关键!将容器内的镜像数据挂载到宿主机的持久化目录。

删除功能启用

REGISTRY_STORAGE_DELETE_ENABLED: true

允许通过API删除镜像,便于管理。

跨域配置

CORS相关配置允许UI界面正常访问Registry API。

  1. 启动服务
# 启动服务
docker compose up -d

# 查看启动状态
docker compose ps

# 查看日志
docker compose logs -f
  1. 停止服务
# 正常停止服务
docker compose down

# 停止并删除数据卷(谨慎使用!)
docker compose down -v

Registry UI访问说明
默认登录信息

如果配置了认证:

用户名: 在htpasswd文件中设置的用户名

htpasswd -cB auth/htpasswd admin

访问地址:http://服务器IP:5001

重新构建和上传镜像

  1. 配置Docker客户端信任私有仓库
# 编辑或创建daemon.json
vim /etc/docker/daemon.json

# 添加以下内容(请替换为你的服务器IP)
{
  "insecure-registries": ["192.168.100.104:5000"]
}

# 重启Docker服务
systemctl restart docker
  1. 构建和推送镜像
# 构建镜像
docker build -t 192.168.100.104:5000/myapp:latest .

# 推送镜像到私有仓库
docker push 192.168.100.104:5000/myapp:latest

防止未来数据丢失的关键措施

定期备份持久化目录

tar -czf /backup/registry-$(date +%Y%m%d).tar.gz /data1/docker/registry

监控存储空间

df -h /data1
du -sh /data1/docker/registry

设置Docker数据根目录到持久化存储

# 编辑/etc/docker/daemon.json
{
  "data-root": "/data1/docker"
}

故障排查

如果服务无法正常启动,检查以下方面:

端口是否被占用

netstat -tlnp | grep -E ":5000|:5001"

目录权限

ls -la /data1/docker/registry

查看容器日志

docker logs registry
docker logs registry-ui

总结

通过以上步骤,我们不仅恢复了Docker私有仓库,更重要的是通过配置持久化存储卷,从根本上解决了服务器重启导致数据丢失的问题。现在即使服务器重启,Docker镜像数据也能完整保留。

注意:请根据实际情况修改配置文件中的IP地址、端口和认证信息。生产环境建议配置SSL证书和更严格的访问控制。

更多推荐