使用 Docker 拉取镜像时,默认会从 Docker Hub 这个公共仓库拉取。
Docker Hub 也可以上传自己的镜像。不过,上传后会对所有人开放,这对于私有镜像来说显然是不够友好的。
为此,Docker 官方提供了工具 registry
来帮助搭建私有仓库。
首先在你要搭建私有仓库的服务器上,安装好 Docker,并拉取 registry
镜像:
$ docker pull registry
然后,建立要存储私有镜像的目录,如 /data/docker/registry
建好后,创建容器:
$ docker run -d \-p 5000:5000 \--restart=always \--name registry \-v /data/docker/registry:/var/lib/registry \registry
运行成功后,测试连接情况:
$ curl http://localhost:5000/v2/_catalog
如果返回:
{"repositories":[]}
表示仓库创建成功,此时仓库内没有镜像。
最后,再用 nginx 转发 5000 端口即可。
服务端配置好之后,现在来到客户端操作,客户端也需要装好 Docker 环境。
刚才服务端配置简便,没有登录上传的功能,所以客户端要绕过权限验证,直接上传镜像。
绕过权限验证,需要客户端的 Docker 做以下配置:
$ vim /etc/docker/daemon.json
写入你的服务器域名,不加 http 前缀:
{"insecure-registries": ["docker.xxx.com"]}
保存后,重启 docker
systemctl restart docker
上一部分我们搭好私有仓库,但是没有登录验证,所以上传镜像时,要在客户端做绕过授权的配置。
实际在服务器上部署仓库时,必须是有账户密码的用户才能推送镜像。
在数据目录下新建 auth 文件夹,添加一个用户 testuser
,密码是 testpass
$ mkdir auth$ docker run \--entrypoint htpasswd \httpd:2 -Bbn testuser testpass > auth/htpasswd
现在创建好了用户,我们先停止之前运行的容器:
$ docker stop registry
然后重新运行:
$ docker run -d \-p 5000:5000 \--restart=always \--name registry \-v /data/docker/registry:/var/lib/registry \-v /data/docker/registry/auth:/auth \-e "REGISTRY_AUTH=htpasswd" \-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \registry:2
运行成功后,假设你配置的外网域名是 docker.test.com,在浏览器中访问:
docker.test.com/v2/_catalog
如果弹出登录框,让你输入账号密码,就是添加成功了。
Web UI 是提供一个 web 页面更方便的管理私有仓库中的镜像。
使用 docker-registry-ui
这个开源项目来实现页面,demo 在 这里
docker-registry-ui 提供一个 docker 镜像,与 registry 关联在一起。
我们写一个 registry.yml
,作为 docker-compose 的配置:
version: '2.0'services:registry:image: registry:2environment:- REGISTRY_AUTH=htpasswd- REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm- REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswdvolumes:- /data/docker/registry:/var/lib/registry- /data/docker/registry/auth:/authnetworks:- registry-ui-netui:image: joxit/docker-registry-ui:latestports:- 5000:80environment:- REGISTRY_TITLE=My Private Docker Registry- NGINX_PROXY_PASS_URL=http://registry:5000- SINGLE_REGISTRY=truedepends_on:- registrynetworks:- registry-ui-netnetworks:registry-ui-net:
这个配置将 registry 和 UI 两个服务绑成了一个应用容器。
执行启动命令:
$ docker-compose -f registry.yml -d
启动后,通过 5000 端口访问 web 界面,同时 5000 也代理了 registry。也就是说。可以同时使用 5000 端口访问 web 界面和推送/拉取镜像。
注意:如过你的服务器是 swarm 集群,使用 docker-compose 只会在当前节点创建容器,而不会扩展到其他节点。推荐方案是
docker stack deploy
默认 registry 的镜像是不允许删除的,registry-ui 也没有提供删除的按钮。
Registry 的配置是一个 YAML 文件,它提供了非常多的默认配置(文档参考这里),是否允许删除就是一个配置,默认如下:
storage:delete:enabled: false
因为我们是用 compose 运行的,没有 registry 配置文件,只有 compose.yml 文件,所以允许删除的配置要在 compose.yml 里定义。
registry 提供了一个配置规则,可以将配置字段大写并且用_
连接起来,组成一个环境变量,使配置生效。
所以上面的配置转换成环境变量是:
REGISTRY_STORAGE_DELETE_ENABLED=true
将该环境变量写入 compose.yml,即完成了配置。