使用 Zot 搭建 Docker 镜像按需缓存
Zot 可以作为一个轻量级 OCI Registry 使用,也可以配置成 pull-through cache:第一次拉取镜像时从上游仓库同步,之后由本地缓存直接返回。这个方案适合给 Docker Hub、GHCR 做统一入口,减少重复下载,也方便后续接入反向代理和域名。
本文以 Linux 服务器部署为目标。文中的配置已先在 Windows Docker Desktop 环境验证通过。
目标
最终希望通过类似下面的地址拉取镜像:
docker pull xxx.com/dockerhub/library/nginx:latest
docker pull xxx.com/dockerhub/whyour/qinglong:latest
docker pull xxx.com/ghcr/project-zot/zot-linux-amd64:latest其中:
/dockerhub对应 Docker Hub/ghcr对应 GitHub Container Registry/private建议留给自己推送的私有镜像
保留上游前缀的好处是路径清晰,也能避免不同上游出现同名仓库时发生冲突。
准备目录
在 Linux 服务器上创建数据目录和配置目录:
mkdir -p /zot/data配置文件保存为:
/zot/config.jsonZot 配置
写入 /zot/config.json:
{
"distSpecVersion": "1.0.1",
"storage": {
"rootDirectory": "/var/lib/zot",
"gc": true,
"dedupe": true
},
"http": {
"address": "0.0.0.0",
"port": "5000"
},
"log": {
"level": "info"
},
"extensions": {
"search": {
"enable": true
},
"ui": {
"enable": true
},
"sync": {
"enable": true,
"registries": [
{
"urls": [
"https://index.docker.io"
],
"content": [
{
"prefix": "**",
"destination": "/dockerhub"
}
],
"onDemand": true,
"tlsVerify": true
},
{
"urls": [
"https://ghcr.io"
],
"content": [
{
"prefix": "**",
"destination": "/ghcr"
}
],
"onDemand": true,
"tlsVerify": true
}
]
}
}
}这里有几个关键点:
- Zot 使用
urls数组,不是url或endpoint onDemand: true表示按需同步,不做定时全量同步destination用来把不同上游映射到不同本地路径ui.enable用来开启 Zot Web UIsearch.enable用来开启搜索接口,Web UI 展示仓库列表需要它- Docker Hub 官方镜像需要带
library,例如library/nginx
校验配置
启动前先执行配置校验:
docker run --rm \
-v /zot/config.json:/etc/zot/config.json:ro \
ghcr.io/project-zot/zot-linux-amd64:latest \
verify /etc/zot/config.json看到 config file is valid 即可。使用 latest 镜像时,可能会提示配置里的 dist spec 版本和镜像实际支持版本不同;只要校验通过,不影响当前用法。
启动 Zot
docker rm -f zot 2>/dev/null
docker run -d \
--name zot \
--restart=always \
-p 127.0.0.1:5000:5000 \
-v /zot/data:/var/lib/zot \
-v /zot/config.json:/etc/zot/config.json:ro \
ghcr.io/project-zot/zot-linux-amd64:latest \
serve /etc/zot/config.json注意最后的 serve /etc/zot/config.json 必须保留。-v 只是把配置文件挂载进容器,真正让 Zot 按该配置启动,需要显式传入配置文件路径。
本地验证
检查容器状态:
docker ps --filter name=^/zot$
docker logs --tail 80 zot检查 Registry API:
curl -I http://127.0.0.1:5000/v2/返回 200 OK 表示服务正常。
如果启用了上面的 ui 配置,浏览器访问下面地址会显示 Zot Web UI:
http://127.0.0.1:5000/测试 Docker Hub 缓存:
docker pull 127.0.0.1:5000/dockerhub/library/busybox:latest首次拉取时,Zot 会访问 Docker Hub 并把镜像写入 /zot/data。日志中出现 successfully synced image,说明按需缓存成功。
测试 GHCR 缓存:
docker pull 127.0.0.1:5000/ghcr/project-zot/zot-linux-amd64:latest配置域名
如果使用 1Panel、Nginx 或 Caddy 暴露域名,可以把:
https://xxx.com反向代理到:
http://127.0.0.1:5000之后客户端就可以这样拉取:
docker pull xxx.com/dockerhub/library/nginx:latest
docker pull xxx.com/dockerhub/whyour/qinglong:latest
docker pull xxx.com/ghcr/project-zot/zot-linux-amd64:latest如果公网开放,建议使用 HTTPS,并在 Zot 或前置网关层增加认证和访问控制。当前配置没有启用认证,直接暴露到公网会允许他人拉取甚至推送镜像。
推送私有镜像
自己的镜像建议统一放到 /private 路径下:
docker tag myapp:latest xxx.com/private/myapp:latest
docker push xxx.com/private/myapp:latest
docker pull xxx.com/private/myapp:latest这样可以和 /dockerhub、/ghcr 的缓存镜像分开管理。
Windows 验证记录
本次先在 Windows Docker Desktop 上验证,配置文件和数据目录放在:
C:\Users\Dalton\Documents\Docker\zot\config.json
C:\Users\Dalton\Documents\Docker\zot\data已验证成功:
docker pull 127.0.0.1:5000/dockerhub/library/busybox:latest容器监听:
127.0.0.1:5000->5000/tcp这说明配置本身可用,后续迁移到 Linux 时主要需要替换挂载路径为 /zot/config.json 和 /zot/data。
评论