在以前使用docker镜像的构建上传过程中一直都是使用的export DECKSER_HOST的方式,但由于暴露了2375端口之后,任何人无需认证即可上传镜像和运行容器,并且挂载宿主机的文件到容器内部,十分危险,docker官方也不推荐这么做,所以我以前的做法是暴露到非2375端口如10086之类的,虽然减少了黑产扫描到的概率,但依然存在很大的风险,但是docker hub能免费使用的私人仓库限制数量为1个

所以使用docker官方registry镜像搭建了一个私有仓库,并且实现了权限认证,在此记录一下整个过程

docker registry 搭建

根据官方文档,直接使用docker compose拉取最新registry镜像,docker-copose.yml配置如下

version: '3.1'
services:
  registry:
    image: registry
    restart: always
    container_name: registry
    ports:
      - 127.0.0.1:9010:5000
    volumes:
      - /home/docker/registry/registry:/var/lib/registry

将仓库中的镜像文件挂载到宿主机

由于我使用nginx代理,所以SSL配置不需要在registry中配置,通过nginx 反代到127.0.0.1:9010即可

但是需要修改一下nginx的配置

  location / {
    proxy_pass http://127.0.0.1:9010/;
    proxy_set_header   Host $host; 
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 100m;
  } 

主要是设置请求大小限制,默认1m修改到100m,不然镜像push的时候会超粗大小限制失败

此时访问 https://xxx.xxx.xxx/v2/_catalog 可以看到镜像列表

但是此时的仓库是没有用户认证的,所有人知道仓库的host之后都可以push和pull

auth认证

官方提供三种方式用户认证

我们选择htpasswd的方式
htpasswd -Bbn user password > ~/auth/htpasswd

通过htpasswd生成认证文件

修改docker-compose.yml配置

version: '3.1'
services:
  registry:
    image: registry
    restart: always
    container_name: registry
    ports:
      - 127.0.0.1:9010:5000
    volumes:
      - /home/docker/registry/registry:/var/lib/registry
      - /home/docker/registry/config.yml:/etc/docker/registry/config.yml
      - /home/docker/registry/auth:/auth
    environment:
      - REGISTRY_AUTH=htpasswd
      - REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
      - REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm

添加认证方式的环境变量,并且将认证文件挂载进容器内

将仓库的配置文件config.yml文件挂载出来,修改为

version: 0.1
log:
  fields:
    service: registry
storage:
  delete:
    enabled: true
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
    Access-Control-Allow-Origin: ['https://xxx.xxx.xxx']
    Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
    Access-Control-Allow-Headers: ['Authorization', 'Accept']
    Access-Control-Max-Age: [1728000]
    Access-Control-Allow-Credentials: [true]
    Access-Control-Expose-Headers: ['Docker-Content-Digest']

主要是设置一下delete字段打开,允许调用镜像删除的api,如果有cors的问题也可以设置Access-Control-Allow-Origin来实现跨域访问

此时再访问https://xxx.xxx.xxx/v2/_catalog,可以看到已经提示输入密码

同时,现在执行docker push之前也要先docker login,认证成功后才可以执行push pull等操作

web ui管理页面搭建

这个时候的仓库没有可视化界面,管理起来不方便于是搜索到常用的方案

在docker-compose.yml中添加ui服务如下

version: '3.1'
services:
  registry:
    image: registry
    restart: always
    container_name: registry
    ports:
      - 127.0.0.1:9010:5000
    volumes:
      - /home/docker/registry/registry:/var/lib/registry
      - /home/docker/registry/config.yml:/etc/docker/registry/config.yml
      - /home/docker/registry/auth:/auth
    environment:
      - REGISTRY_AUTH=htpasswd
      - REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
      - REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm
    networks:
      - registry-ui-net   

#  现阶段无删除功能,不使用该方案  
#  frontend-registry:
#    image: konradkleine/docker-registry-frontend:v2
#    restart: always
#    container_name: frontend-registry
#    ports:
#      - 127.0.0.1:8010:80
#    environment:
#      - ENV_DOCKER_REGISTRY_HOST=107.172.218.23
#      - ENV_DOCKER_REGISTRY_PORT=9010
#      - ENV_MODE_BROWSE_ONLY=false

  ui:
    image: joxit/docker-registry-ui:latest
    restart: always
    container_name: ui-registry
    ports:
      - 127.0.0.1:8010:80
    environment:
      - REGISTRY_TITLE=1zilc Private Docker Registry
#      - REGISTRY_URL=registry
      - NGINX_PROXY_PASS_URL=http://registry:5000
      - SINGLE_REGISTRY=false
      - DELETE_IMAGES=true
    depends_on:
      - registry
    networks:
      - registry-ui-net

networks:
  registry-ui-net:

如果之前没有在仓库的config文件或者nginx配置文件中配置跨域访问的头部,则这里要使用NGINX_PROXY_PASS_URL来REGISTRY_URL

并且通过docker的内部网络来访问仓库,即容器名+端口http://registry:5000 此处通过域名访问会报403,原因暂时不太明白

此时再配置一下nginx反代到127.0.0.1:8010,再访问页面

已经可以看到镜像 tag等信息,也可以进行删除操作

如果是在github actions中push镜像需要在push前登录到docker hub,添加如下配置

至此私人Docker Registry搭建完成

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注