<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Registry on HiDa</title><link>https://www.0niu.cn/tags/registry/</link><description>Recent content in Registry on HiDa</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Mon, 09 Jun 2025 22:51:00 +0800</lastBuildDate><atom:link href="https://www.0niu.cn/tags/registry/index.xml" rel="self" type="application/rss+xml"/><item><title>使用官方 Registry v2 搭建 Docker Mirror 私有镜像仓库</title><link>https://www.0niu.cn/posts/docker-registry-mirror/</link><pubDate>Mon, 09 Jun 2025 22:51:00 +0800</pubDate><guid>https://www.0niu.cn/posts/docker-registry-mirror/</guid><description>&lt;p>在国内网络环境下，直接从 Docker Hub 拉取镜像经常遇到超时或被限流的问题。搭建一个本地 Docker Mirror 代理仓库可以有效解决这个痛点。本文介绍如何使用官方 Registry v2 搭建私有镜像代理仓库。&lt;/p>
&lt;h2 id="为什么要搭-docker-mirror">为什么要搭 Docker Mirror&lt;/h2>
&lt;h3 id="1-docker-hub-公网限速">1. Docker Hub 公网限速&lt;/h3>
&lt;p>Docker Hub 对匿名用户的拉取限速为 &lt;strong>100 次/6 小时&lt;/strong>，免费账户为 &lt;strong>200 次/6 小时&lt;/strong>。在 CI/CD 流水线或多人团队环境下，这个限额很容易触达。通过自建 Mirror 代理，所有节点的拉取请求汇聚到 Mirror 节点，Mirror 对上游只产生一次请求，有效规避限额。&lt;/p>
&lt;h3 id="2-缓存加速-build">2. 缓存加速 Build&lt;/h3>
&lt;p>在 CI/CD 构建中，每次 &lt;code>docker build&lt;/code> 都需要拉取基础镜像。即使代码没有变化，基础镜像也会被反复从公网拉取，浪费时间。Mirror 缓存了基础镜像后：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>首次构建&lt;/strong>：从上游拉取并缓存&lt;/li>
&lt;li>&lt;strong>后续构建&lt;/strong>：直接从 Mirror 拉取，速度提升 5-10 倍&lt;/li>
&lt;li>&lt;strong>多节点并行构建&lt;/strong>：共享同一个 Mirror，只消耗一次外网流量&lt;/li>
&lt;/ul></description><content>&lt;p>在国内网络环境下，直接从 Docker Hub 拉取镜像经常遇到超时或被限流的问题。搭建一个本地 Docker Mirror 代理仓库可以有效解决这个痛点。本文介绍如何使用官方 Registry v2 搭建私有镜像代理仓库。&lt;/p>
&lt;h2 id="为什么要搭-docker-mirror">为什么要搭 Docker Mirror&lt;/h2>
&lt;h3 id="1-docker-hub-公网限速">1. Docker Hub 公网限速&lt;/h3>
&lt;p>Docker Hub 对匿名用户的拉取限速为 &lt;strong>100 次/6 小时&lt;/strong>，免费账户为 &lt;strong>200 次/6 小时&lt;/strong>。在 CI/CD 流水线或多人团队环境下，这个限额很容易触达。通过自建 Mirror 代理，所有节点的拉取请求汇聚到 Mirror 节点，Mirror 对上游只产生一次请求，有效规避限额。&lt;/p>
&lt;h3 id="2-缓存加速-build">2. 缓存加速 Build&lt;/h3>
&lt;p>在 CI/CD 构建中，每次 &lt;code>docker build&lt;/code> 都需要拉取基础镜像。即使代码没有变化，基础镜像也会被反复从公网拉取，浪费时间。Mirror 缓存了基础镜像后：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>首次构建&lt;/strong>：从上游拉取并缓存&lt;/li>
&lt;li>&lt;strong>后续构建&lt;/strong>：直接从 Mirror 拉取，速度提升 5-10 倍&lt;/li>
&lt;li>&lt;strong>多节点并行构建&lt;/strong>：共享同一个 Mirror，只消耗一次外网流量&lt;/li>
&lt;/ul>
&lt;h3 id="3-离线可用与稳定性">3. 离线可用与稳定性&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>特性&lt;/th>
&lt;th>说明&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>离线可用&lt;/td>
&lt;td>已缓存的镜像在内网环境下随时可用，不依赖外网连接&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>稳定可控&lt;/td>
&lt;td>不受 Docker Hub 宕机、限速、DNS 污染等公网问题影响&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>节省带宽&lt;/td>
&lt;td>多个节点共享缓存，外网出口带宽消耗大幅降低&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="架构说明">架构说明&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>Docker Client → Caddy (HTTPS) → Registry v2 (Mirror) → DaoCloud 上游 → Docker Hub
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ↓
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 本地缓存（命中则直接返回）
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>整个链路的请求流程：&lt;/p>
&lt;ol>
&lt;li>Docker Client 向 &lt;code>docker pull&lt;/code> 配置的 Mirror 地址发起拉取请求&lt;/li>
&lt;li>请求经 Caddy HTTPS 反向代理转发到 Registry v2&lt;/li>
&lt;li>Registry 检查本地缓存，命中则直接返回&lt;/li>
&lt;li>缓存未命中时，Registry 向 DaoCloud 上游代理转发请求&lt;/li>
&lt;li>DaoCloud 再从 Docker Hub 获取镜像数据并逐层返回&lt;/li>
&lt;li>Registry 将收到的每一层数据写入本地缓存&lt;/li>
&lt;/ol>
&lt;h2 id="环境准备">环境准备&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Docker 20.10+&lt;/strong>：确保 Docker Engine 版本支持 &lt;code>registry-mirrors&lt;/code> 配置&lt;/li>
&lt;li>&lt;strong>域名&lt;/strong>：一个已解析到服务器 IP 的域名，用于 Caddy 自动申请 HTTPS 证书（如 &lt;code>mirror.example.com&lt;/code>）&lt;/li>
&lt;li>&lt;strong>SSD 存储&lt;/strong>：建议至少 100GB 以上，镜像层文件较大且频繁读写，SSD 能显著提升缓存命中后的响应速度&lt;/li>
&lt;li>&lt;strong>开放端口&lt;/strong>：只需开放 443 端口（HTTPS），Registry 本身通过 Docker 内部网络通信，不暴露端口到宿主机&lt;/li>
&lt;/ul>
&lt;h2 id="部署-registry-v2-mirror">部署 Registry v2 Mirror&lt;/h2>
&lt;h3 id="配置文件">配置文件&lt;/h3>
&lt;p>创建 &lt;code>config.yml&lt;/code>：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Registry 配置文件版本，当前为 0.1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">version&lt;/span>: &lt;span style="color:#ae81ff">0.1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 日志配置&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">log&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 日志级别：debug / info / warn / error / fatal，默认 info&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">level&lt;/span>: &lt;span style="color:#ae81ff">info&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 日志格式：json / text / logfmt，默认 logfmt&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">formatter&lt;/span>: &lt;span style="color:#ae81ff">logfmt&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 附加字段，会添加到每条日志中，默认无&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">fields&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">service&lt;/span>: &lt;span style="color:#ae81ff">registry&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">environment&lt;/span>: &lt;span style="color:#ae81ff">production&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 存储配置&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">storage&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 存储驱动类型，默认 filesystem&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">filesystem&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 镜像层数据的存储根目录，默认 /var/lib/registry&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">rootdirectory&lt;/span>: &lt;span style="color:#ae81ff">/var/lib/registry&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 并发文件系统操作的线程数，默认 100&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">maxthreads&lt;/span>: &lt;span style="color:#ae81ff">100&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># Blob 描述符缓存，用于加速 manifest 请求&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">cache&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">blobdescriptor&lt;/span>: &lt;span style="color:#ae81ff">inmemory&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 启用删除 API，允许通过 DELETE 接口删除 blob，默认 false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">delete&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">enabled&lt;/span>: &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 存储维护任务配置&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">maintenance&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 上传清理，自动清理未完成的上传文件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">uploadpurging&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 是否启用上传清理，默认 true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">enabled&lt;/span>: &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 未完成上传文件的保留时间，超过此时间将被清理，默认 168h（7 天）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">age&lt;/span>: &lt;span style="color:#ae81ff">168h&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 清理检查间隔，默认 24h&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">interval&lt;/span>: &lt;span style="color:#ae81ff">24h&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 是否只预览不实际删除，默认 false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">dryrun&lt;/span>: &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 只读模式开关，设为 true 时拒绝所有写入操作（push、delete），拉取正常&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 可用于 GC 时临时开启，防止并发写入，默认 false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">readonly&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">enabled&lt;/span>: &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># HTTP 服务器配置&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">http&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 监听地址和端口，默认 :5000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">addr&lt;/span>: :&lt;span style="color:#ae81ff">5000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 监听的网络接口，默认 localhost（仅本地访问）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">host&lt;/span>: &lt;span style="color:#ae81ff">0.0.0.0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># HTTP 响应头设置&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">headers&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 防止浏览器 MIME 类型嗅探，安全最佳实践&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">X-Content-Type-Options&lt;/span>: [&lt;span style="color:#ae81ff">nosniff]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># CORS 允许的来源，设为 * 允许所有来源&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">Access-Control-Allow-Origin&lt;/span>: [&lt;span style="color:#e6db74">&amp;#39;*&amp;#39;&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># CORS 允许的 HTTP 方法&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">Access-Control-Allow-Methods&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">HEAD&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">GET&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">OPTIONS&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># CORS 允许的请求头&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">Access-Control-Allow-Headers&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">Authorization&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">Accept&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 上游代理配置&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">proxy&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 上游镜像源地址（必填）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">remoteurl&lt;/span>: &lt;span style="color:#ae81ff">https://docker.m.daocloud.io&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 上游认证用户名（可选，公共源不需要）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># username:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 上游认证密码（可选，公共源不需要）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># password:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 健康检查配置&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">health&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">storagedriver&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 是否启用存储健康检查（默认：true）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">enabled&lt;/span>: &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 检查间隔（默认：10s）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">interval&lt;/span>: &lt;span style="color:#ae81ff">10s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 连续失败多少次后标记不健康（默认：3）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">threshold&lt;/span>: &lt;span style="color:#ae81ff">3&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="关键配置项说明">关键配置项说明&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>配置项&lt;/th>
&lt;th>默认值&lt;/th>
&lt;th>说明&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>storage.filesystem.rootdirectory&lt;/code>&lt;/td>
&lt;td>&lt;code>/var/lib/registry&lt;/code>&lt;/td>
&lt;td>镜像存储路径&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>storage.cache.blobdescriptor&lt;/code>&lt;/td>
&lt;td>&lt;code>inmemory&lt;/code>&lt;/td>
&lt;td>Blob 元数据缓存方式，可选 &lt;code>redis&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>storage.delete.enabled&lt;/code>&lt;/td>
&lt;td>&lt;code>false&lt;/code>&lt;/td>
&lt;td>&lt;strong>必须设为 true&lt;/strong>，否则无法执行 GC&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>storage.maintenance.readonly.enabled&lt;/code>&lt;/td>
&lt;td>&lt;code>false&lt;/code>&lt;/td>
&lt;td>只读模式，GC 时临时开启&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>proxy.remoteurl&lt;/code>&lt;/td>
&lt;td>-&lt;/td>
&lt;td>上游镜像源地址&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>health.storagedriver.enabled&lt;/code>&lt;/td>
&lt;td>&lt;code>true&lt;/code>&lt;/td>
&lt;td>存储驱动健康检查&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="上游源选择daocloud">上游源选择：DaoCloud&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>特性&lt;/th>
&lt;th>说明&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>稳定性&lt;/strong>&lt;/td>
&lt;td>DaoCloud 是国内主流容器厂商，镜像站长期维护&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>完整性&lt;/strong>&lt;/td>
&lt;td>同步 Docker Hub 全量镜像&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>速度&lt;/strong>&lt;/td>
&lt;td>国内 CDN 加速&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>免费&lt;/strong>&lt;/td>
&lt;td>公共服务，无需注册&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>其他可选的上游源：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># DaoCloud&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">remoteurl&lt;/span>: &lt;span style="color:#ae81ff">https://docker.m.daocloud.io&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 阿里云&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">remoteurl&lt;/span>: &lt;span style="color:#ae81ff">https://registry.cn-hangzhou.aliyuncs.com&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 腾讯云&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">remoteurl&lt;/span>: &lt;span style="color:#ae81ff">https://mirror.ccs.tencentyun.com&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>可以部署多个 Mirror 实例使用不同的上游源，互为备份。&lt;/p>
&lt;/blockquote>
&lt;h2 id="缓存类型">缓存类型&lt;/h2>
&lt;p>Registry v2 的 proxy 模式使用以下缓存机制：&lt;/p>
&lt;h3 id="1-blob-缓存层缓存">1. Blob 缓存（层缓存）&lt;/h3>
&lt;p>镜像的每一层（layer）都会被缓存到本地存储：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-gdscript3" data-lang="gdscript3">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">/&lt;/span>&lt;span style="color:#66d9ef">var&lt;/span>&lt;span style="color:#f92672">/&lt;/span>lib&lt;span style="color:#f92672">/&lt;/span>registry&lt;span style="color:#f92672">/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">├──&lt;/span> docker&lt;span style="color:#f92672">/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">│&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">└──&lt;/span> registry&lt;span style="color:#f92672">/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">│&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">└──&lt;/span> v2&lt;span style="color:#f92672">/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">│&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">├──&lt;/span> blobs&lt;span style="color:#f92672">/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">│&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">│&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">└──&lt;/span> sha256&lt;span style="color:#f92672">/&lt;/span> &lt;span style="color:#75715e"># 镜像层数据&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">│&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">└──&lt;/span> repositories&lt;span style="color:#f92672">/&lt;/span> &lt;span style="color:#75715e"># 仓库元数据&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-manifest-缓存清单缓存">2. Manifest 缓存（清单缓存）&lt;/h3>
&lt;p>镜像的 manifest（包含层关系、tag 等信息）也会被缓存。&lt;/p>
&lt;h3 id="3-blobdescriptor-缓存元数据缓存">3. BlobDescriptor 缓存（元数据缓存）&lt;/h3>
&lt;p>配置 &lt;code>storage.cache.blobdescriptor&lt;/code>：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 内存缓存（默认，适合中小规模）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">storage&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">cache&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">blobdescriptor&lt;/span>: &lt;span style="color:#ae81ff">inmemory&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Redis 缓存（适合大规模部署）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">storage&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">cache&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">blobdescriptor&lt;/span>: &lt;span style="color:#ae81ff">redis&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">redis&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">addr&lt;/span>: &lt;span style="color:#ae81ff">redis:6379&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">password&lt;/span>: &lt;span style="color:#ae81ff">yourpassword&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">db&lt;/span>: &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">ringlimit&lt;/span>: &lt;span style="color:#ae81ff">100&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="缓存策略">缓存策略&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>缓存类型&lt;/th>
&lt;th>说明&lt;/th>
&lt;th>建议场景&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>inmemory&lt;/code>&lt;/td>
&lt;td>元数据存内存，blob 存磁盘&lt;/td>
&lt;td>镜像数量 &amp;lt; 10000&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>redis&lt;/code>&lt;/td>
&lt;td>元数据存 Redis，blob 存磁盘&lt;/td>
&lt;td>镜像数量 &amp;gt; 10000，多实例&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="缓存未命中">缓存未命中&lt;/h3>
&lt;ol>
&lt;li>Registry 检查本地存储 → 未找到&lt;/li>
&lt;li>转发请求到上游（DaoCloud）&lt;/li>
&lt;li>上游返回数据 → Registry 同时缓存到本地并返回给客户端&lt;/li>
&lt;li>后续请求直接从本地返回&lt;/li>
&lt;/ol>
&lt;h2 id="gc垃圾回收">GC（垃圾回收）&lt;/h2>
&lt;p>随着时间推移，Registry 中会积累大量不再使用的镜像层数据（例如旧版本镜像被更新替换）。GC 用于清理这些无用数据，释放磁盘空间。&lt;/p>
&lt;h3 id="gc-原理">GC 原理&lt;/h3>
&lt;p>Registry 使用 &lt;strong>content-addressable&lt;/strong> 存储，每个 blob 通过 SHA256 哈希标识。GC 的核心逻辑：&lt;/p>
&lt;ol>
&lt;li>标记所有被当前 manifest 引用的 blob&lt;/li>
&lt;li>删除未被引用的 blob（垃圾数据）&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>manifest v2 → 引用 blob A, B, C
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>manifest v1 → 引用 blob A, B, D（旧版本）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>GC 后：blob D 被清除（只被旧 manifest 引用）
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="在线-gcread-only-模式">在线 GC（read-only 模式）&lt;/h3>
&lt;p>Registry v2 支持 &lt;strong>只读模式（read-only mode）&lt;/strong>，GC 前切换为只读，避免并发写入导致数据不一致：&lt;/p>
&lt;ol>
&lt;li>将 Registry 切换为只读模式（拒绝写入，拉取正常）&lt;/li>
&lt;li>执行 GC 清理未引用的 blob&lt;/li>
&lt;li>恢复读写模式&lt;/li>
&lt;/ol>
&lt;h4 id="第一步预览dry-run">第一步：预览（dry-run）&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 安全操作，不影响服务，建议先执行确认&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker exec registry-mirror bin/registry garbage-collect &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> /etc/docker/registry/config.yml &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --dry-run
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>输出示例：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>ubuntu for sha256:abc123...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>nginx for sha256:def456...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="第二步切换只读--执行-gc--恢复">第二步：切换只读 + 执行 GC + 恢复&lt;/h4>
&lt;blockquote>
&lt;p>&lt;strong>注意&lt;/strong>：不能通过环境变量 &lt;code>REGISTRY_STORAGE_MAINTENANCE_READONLY_ENABLED=true&lt;/code> 设置只读模式，会触发 panic（Registry 的已知 bug，环境变量覆盖 maintenance 子配置时 map key 类型不匹配）。
&lt;strong>正确做法是通过 &lt;code>docker exec&lt;/code> 修改容器内的 config.yml，再用 &lt;code>docker restart&lt;/code> 重载配置&lt;/strong>。&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 1. 开启只读模式 + 重启生效&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker exec registry-mirror sed -i &lt;span style="color:#e6db74">&amp;#34;/readonly:/,/enabled:/ s/enabled: false/enabled: true/&amp;#34;&lt;/span> /etc/docker/registry/config.yml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker restart registry-mirror
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 2. 等待容器就绪后执行 GC&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sleep &lt;span style="color:#ae81ff">5&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker exec registry-mirror bin/registry garbage-collect /etc/docker/registry/config.yml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 3. 恢复读写模式 + 重启生效&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker exec registry-mirror sed -i &lt;span style="color:#e6db74">&amp;#34;/readonly:/,/enabled:/ s/enabled: true/enabled: false/&amp;#34;&lt;/span> /etc/docker/registry/config.yml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker restart registry-mirror
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="定期-gc-建议">定期 GC 建议&lt;/h3>
&lt;p>建议通过 cron 定期执行 GC：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 每月 1 号凌晨 3 点执行 GC&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">0&lt;/span> &lt;span style="color:#ae81ff">3&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> * * root docker exec registry-mirror sed -i &lt;span style="color:#e6db74">&amp;#34;/readonly:/,/enabled:/ s/enabled: false/enabled: true/&amp;#34;&lt;/span> /etc/docker/registry/config.yml &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> docker restart registry-mirror &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> sleep &lt;span style="color:#ae81ff">5&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> docker exec registry-mirror bin/registry garbage-collect /etc/docker/registry/config.yml &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> docker exec registry-mirror sed -i &lt;span style="color:#e6db74">&amp;#34;/readonly:/,/enabled:/ s/enabled: true/enabled: false/&amp;#34;&lt;/span> /etc/docker/registry/config.yml &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> docker restart registry-mirror
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="gc-与删除-api-的区别">GC 与删除 API 的区别&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>方式&lt;/th>
&lt;th>作用&lt;/th>
&lt;th>用途&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>DELETE /v2/&amp;lt;name&amp;gt;/manifests/&amp;lt;digest&amp;gt;&lt;/code>&lt;/td>
&lt;td>删除指定 manifest&lt;/td>
&lt;td>删除特定镜像 tag&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>garbage-collect&lt;/code>&lt;/td>
&lt;td>清理未引用的 blob&lt;/td>
&lt;td>回收磁盘空间&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>两者通常配合使用：先通过 DELETE API 删除不需要的 manifest，再执行 GC 释放空间。&lt;/p>
&lt;/blockquote>
&lt;h2 id="caddy-server--https-反向代理">Caddy Server — HTTPS 反向代理&lt;/h2>
&lt;p>Docker 客户端配置 &lt;code>registry-mirrors&lt;/code> 要求使用 HTTPS。使用 &lt;a href="https://caddyserver.com/">Caddy&lt;/a> 的核心优势是 &lt;strong>零配置自动 HTTPS&lt;/strong>，自动申请和续期 Let&amp;rsquo;s Encrypt 证书。&lt;/p>
&lt;h3 id="为什么选-caddy">为什么选 Caddy&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>特性&lt;/th>
&lt;th>Caddy&lt;/th>
&lt;th>Nginx&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>HTTPS 证书&lt;/td>
&lt;td>自动申请续期&lt;/td>
&lt;td>需配合 certbot&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>配置复杂度&lt;/td>
&lt;td>极简&lt;/td>
&lt;td>较复杂&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>HTTP/3&lt;/td>
&lt;td>原生支持&lt;/td>
&lt;td>需额外编译模块&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>适合场景&lt;/td>
&lt;td>中小规模、快速部署&lt;/td>
&lt;td>大规模、复杂路由&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="caddyfile-配置">Caddyfile 配置&lt;/h3>
&lt;p>创建 &lt;code>Caddyfile&lt;/code>：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>mirror.example.com {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> reverse_proxy registry:5000
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 上传大镜像需要放宽限制
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> request_body {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> max_size 10GB
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # Docker 客户端需要的 header
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> header /v2/ Docker-Distribution-Api-Version &amp;#34;registry/2.0&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 访问日志
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> output file /data/caddy/access.log
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> format console
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> # 健康检查端点不记日志
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> @health path /v2/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> log @health {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> output discard
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>确保域名 &lt;code>mirror.example.com&lt;/code> 的 DNS A 记录已指向服务器公网 IP，Caddy 才能自动申请 Let&amp;rsquo;s Encrypt 证书。&lt;/p>
&lt;/blockquote>
&lt;h3 id="完整-docker-composeymlcaddy--registry">完整 docker-compose.yml（Caddy + Registry）&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">version&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;3.8&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">services&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">caddy&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">image&lt;/span>: &lt;span style="color:#ae81ff">caddy:2-alpine&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">container_name&lt;/span>: &lt;span style="color:#ae81ff">registry-caddy&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">restart&lt;/span>: &lt;span style="color:#ae81ff">always&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#e6db74">&amp;#34;80:80&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#e6db74">&amp;#34;443:443&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#e6db74">&amp;#34;443:443/udp&amp;#34;&lt;/span> &lt;span style="color:#75715e"># HTTP/3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">volumes&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">./Caddyfile:/etc/caddy/Caddyfile&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">./caddy_data:/data&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">./caddy_config:/config&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">depends_on&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">registry&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">condition&lt;/span>: &lt;span style="color:#ae81ff">service_healthy&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">registry&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">image&lt;/span>: &lt;span style="color:#ae81ff">registry:2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">container_name&lt;/span>: &lt;span style="color:#ae81ff">registry-mirror&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">restart&lt;/span>: &lt;span style="color:#ae81ff">always&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 不暴露端口，仅通过 Caddy 访问&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">expose&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#e6db74">&amp;#34;5000&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">volumes&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">./data:/var/lib/registry&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">./config.yml:/etc/docker/registry/config.yml&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">REGISTRY_STORAGE_DELETE_ENABLED=true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">REGISTRY_HTTP_ADDR=0.0.0.0:5000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">healthcheck&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">test&lt;/span>: [&lt;span style="color:#e6db74">&amp;#34;CMD&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;wget&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;--spider&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;-q&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;http://localhost:5000/v2/&amp;#34;&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">interval&lt;/span>: &lt;span style="color:#ae81ff">30s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">timeout&lt;/span>: &lt;span style="color:#ae81ff">10s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">retries&lt;/span>: &lt;span style="color:#ae81ff">3&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="启动服务">启动服务&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 启动&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker compose up -d
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 查看 Caddy 日志，确认证书申请成功&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker logs -f registry-caddy
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>看到类似输出表示 HTTPS 证书已自动获取：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;certificate obtained successfully&amp;#34;,&amp;#34;identifier&amp;#34;:&amp;#34;mirror.example.com&amp;#34;}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="验证">验证&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 测试 HTTPS 访问&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>curl https://mirror.example.com/v2/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 应返回空 JSON：{}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="docker-客户端配置">Docker 客户端配置&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;registry-mirrors&amp;#34;&lt;/span>: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;https://mirror.example.com&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;insecure-registries&amp;#34;&lt;/span>: []
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>使用 Caddy 提供 HTTPS 后，&lt;strong>不需要&lt;/strong> 配置 &lt;code>insecure-registries&lt;/code>，安全性更好。&lt;/p>
&lt;/blockquote>
&lt;h3 id="caddy-数据持久化">Caddy 数据持久化&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>./caddy_data/ # TLS 证书（自动申请、自动续期）
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./caddy_config/ # Caddy 配置缓存
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>证书续期由 Caddy 自动处理，无需人工干预。&lt;/p>
&lt;h2 id="日常运维">日常运维&lt;/h2>
&lt;h3 id="查看存储占用">查看存储占用&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 查看缓存目录大小&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>du -sh /data/registry/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 查看各仓库占用&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>du -sh /data/registry/docker/registry/v2/repositories/*
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="查看日志">查看日志&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>docker logs -f --tail &lt;span style="color:#ae81ff">100&lt;/span> registry-mirror
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker logs -f --tail &lt;span style="color:#ae81ff">100&lt;/span> registry-caddy
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="健康检查">健康检查&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 检查服务状态&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>curl https://mirror.example.com/v2/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 检查上游连通性&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>curl https://mirror.example.com/v2/_catalog
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="完整目录结构">完整目录结构&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>docker-mirror/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── docker-compose.yml # Caddy + Registry
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── Caddyfile # Caddy HTTPS 反向代理配置
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── config.yml # Registry 配置
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── data/ # Registry 镜像缓存
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── caddy_data/ # Caddy TLS 证书
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>└── caddy_config/ # Caddy 配置缓存
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="总结">总结&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>要点&lt;/th>
&lt;th>说明&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>核心组件&lt;/td>
&lt;td>官方 Registry v2 + proxy 模式&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>HTTPS 代理&lt;/td>
&lt;td>Caddy（零配置自动 HTTPS、证书自动续期）&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>上游源&lt;/td>
&lt;td>DaoCloud（稳定、完整、免费）&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>缓存加速&lt;/td>
&lt;td>Blob 磁盘缓存 + 元数据内存/Redis 缓存，加速 CI/CD Build&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GC&lt;/td>
&lt;td>read-only 模式 + docker exec，防止并发写入&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>运维要点&lt;/td>
&lt;td>监控磁盘用量、定期 GC、关注上游可用性&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>对于内网 Docker 环境，搭建一个 Mirror 代理仓库是性价比极高的基础设施投入，一次部署长期受益。&lt;/p></content></item><item><title>Outlook提示您的组织策略阻止我们为您完成此操作问题解决</title><link>https://www.0niu.cn/posts/outlook-organization-policy-issue-fix/</link><pubDate>Sat, 25 Mar 2017 15:53:38 +0800</pubDate><guid>https://www.0niu.cn/posts/outlook-organization-policy-issue-fix/</guid><description>&lt;h2 id="问题描述">问题描述&lt;/h2>
&lt;p>在使用 Outlook 打开某些 HTML 邮件或链接时，可能会遇到错误提示：&lt;/p>
&lt;blockquote>
&lt;p>您的组织策略阻止我们为您完成此操作&lt;/p>
&lt;/blockquote>
&lt;p>这个问题通常是由于 Windows 注册表中 &lt;code>.html&lt;/code> 文件关联设置不正确导致的。&lt;/p>
&lt;h2 id="解决方案">解决方案&lt;/h2>
&lt;p>通过修改注册表，将 &lt;code>.html&lt;/code> 文件类型重新关联到 &lt;code>HTMLfile&lt;/code> 即可解决此问题。&lt;/p>
&lt;h3 id="方法一使用注册表命令推荐">方法一：使用注册表命令（推荐）&lt;/h3>
&lt;p>以管理员身份运行命令提示符，执行以下命令：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-batch" data-lang="batch">&lt;span style="display:flex;">&lt;span>Reg.exe add &lt;span style="color:#e6db74">&amp;#34;HKCU\Software\Classes\.html&amp;#34;&lt;/span> /ve /t REG_SZ /d &lt;span style="color:#e6db74">&amp;#34;HTMLfile&amp;#34;&lt;/span> /f
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description><content>&lt;h2 id="问题描述">问题描述&lt;/h2>
&lt;p>在使用 Outlook 打开某些 HTML 邮件或链接时，可能会遇到错误提示：&lt;/p>
&lt;blockquote>
&lt;p>您的组织策略阻止我们为您完成此操作&lt;/p>
&lt;/blockquote>
&lt;p>这个问题通常是由于 Windows 注册表中 &lt;code>.html&lt;/code> 文件关联设置不正确导致的。&lt;/p>
&lt;h2 id="解决方案">解决方案&lt;/h2>
&lt;p>通过修改注册表，将 &lt;code>.html&lt;/code> 文件类型重新关联到 &lt;code>HTMLfile&lt;/code> 即可解决此问题。&lt;/p>
&lt;h3 id="方法一使用注册表命令推荐">方法一：使用注册表命令（推荐）&lt;/h3>
&lt;p>以管理员身份运行命令提示符，执行以下命令：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-batch" data-lang="batch">&lt;span style="display:flex;">&lt;span>Reg.exe add &lt;span style="color:#e6db74">&amp;#34;HKCU\Software\Classes\.html&amp;#34;&lt;/span> /ve /t REG_SZ /d &lt;span style="color:#e6db74">&amp;#34;HTMLfile&amp;#34;&lt;/span> /f
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="方法二手动修改注册表">方法二：手动修改注册表&lt;/h3>
&lt;ol>
&lt;li>按 &lt;code>Win + R&lt;/code>，输入 &lt;code>regedit&lt;/code>，回车打开注册表编辑器&lt;/li>
&lt;li>导航到 &lt;code>HKEY_CURRENT_USER\Software\Classes\.html&lt;/code>&lt;/li>
&lt;li>双击右侧的 &lt;code>(默认)&lt;/code> 值&lt;/li>
&lt;li>将数值数据修改为 &lt;code>HTMLfile&lt;/code>&lt;/li>
&lt;li>点击确定，关闭注册表编辑器&lt;/li>
&lt;/ol>
&lt;h2 id="验证">验证&lt;/h2>
&lt;p>修改完成后，重启 Outlook，再次尝试打开之前报错的邮件或链接，问题应该已解决。&lt;/p>
&lt;h2 id="注意事项">注意事项&lt;/h2>
&lt;ul>
&lt;li>修改注册表前建议先备份&lt;/li>
&lt;li>需要管理员权限才能执行此操作&lt;/li>
&lt;li>如果问题仍然存在，可能需要检查组策略或其他安全软件设置&lt;/li>
&lt;/ul></content></item></channel></rss>