<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Caddy on HiDa</title><link>https://www.0niu.cn/tags/caddy/</link><description>Recent content in Caddy on HiDa</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Wed, 25 Mar 2026 14:43:00 +0800</lastBuildDate><atom:link href="https://www.0niu.cn/tags/caddy/index.xml" rel="self" type="application/rss+xml"/><item><title>Alpine Linux 部署 SmokePing 网络监控</title><link>https://www.0niu.cn/posts/alpine-linux-smokeping%E9%83%A8%E7%BD%B2/</link><pubDate>Wed, 25 Mar 2026 14:43:00 +0800</pubDate><guid>https://www.0niu.cn/posts/alpine-linux-smokeping%E9%83%A8%E7%BD%B2/</guid><description>&lt;p>本文介绍如何在 Alpine Linux 系统上部署 SmokePing 网络延迟监控工具，使用 Caddy 作为 Web 服务器，FCGIWrap 处理 CGI 脚本。&lt;/p>
&lt;h2 id="系统要求">系统要求&lt;/h2>
&lt;ul>
&lt;li>Alpine Linux 3.18+&lt;/li>
&lt;li>2GB+ RAM（推荐 4GB+）&lt;/li>
&lt;li>20GB+ 磁盘空间&lt;/li>
&lt;li>网络连接正常&lt;/li>
&lt;/ul>
&lt;h2 id="安装步骤">安装步骤&lt;/h2>
&lt;h3 id="1-安装必要软件包">1. 安装必要软件包&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>apk update
&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"># 安装 SmokePing 及相关组件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apk add fcgiwrap fcgiwrap-openrc caddy smokeping smokeping-openrc
&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"># 创建 fcgiwrap 服务用户&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>useradd -r fcgiwrap-openrc
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-创建数据目录">2. 创建数据目录&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"># 创建 SmokePing 数据目录&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mkdir -p /var/lib/smokeping/Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mkdir -p /var/lib/smokeping/DNS
&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>chown smokeping:smokeping /var/lib/smokeping/Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chown smokeping:smokeping /var/lib/smokeping/DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chmod &lt;span style="color:#ae81ff">777&lt;/span> /var/lib/smokeping/images/Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chmod &lt;span style="color:#ae81ff">777&lt;/span> /var/lib/smokeping/images/DNS
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="3-配置-caddy-web-服务器">3. 配置 Caddy Web 服务器&lt;/h3>
&lt;p>创建 Caddy 配置文件 &lt;code>/etc/caddy/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-caddyfile" data-lang="caddyfile">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">log&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">output&lt;/span> &lt;span style="color:#e6db74">file&lt;/span> &lt;span style="color:#e6db74">/var/log/caddy/access.log&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">roll_size&lt;/span> &lt;span style="color:#e6db74">100MB&lt;/span>&lt;span style="color:#75715e"> # 单个日志文件最大 100MB
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">roll_keep&lt;/span> &lt;span style="color:#ae81ff">10&lt;/span>&lt;span style="color:#75715e"> # 保留最近 10 个日志文件
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">roll_keep_for&lt;/span> &lt;span style="color:#ae81ff">720h&lt;/span>&lt;span style="color:#75715e"> # 保留 30 天（720 小时）
&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:#66d9ef">format&lt;/span> &lt;span style="color:#e6db74">console&lt;/span>&lt;span style="color:#75715e"> # 易读的格式，也可改用 json 格式（format json）
&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>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>http://192.168.1.100 {&lt;span style="color:#75715e">
&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">&lt;/span> &lt;span style="color:#66d9ef">handle&lt;/span> &lt;span style="color:#a6e22e">/js/*&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">file_server&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:#66d9ef">handle&lt;/span> &lt;span style="color:#a6e22e">/css/*&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">file_server&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:#66d9ef">handle&lt;/span> &lt;span style="color:#a6e22e">/imgcache/*&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">file_server&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:#66d9ef">handle_path&lt;/span> &lt;span style="color:#a6e22e">/images/*&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/var/lib/smokeping/images&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">file_server&lt;/span> &lt;span style="color:#e6db74">browse&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">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 处理 CGI 请求
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">handle&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">reverse_proxy&lt;/span> &lt;span style="color:#e6db74">unix//run/fcgiwrap/fcgiwrap.sock&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">transport&lt;/span> &lt;span style="color:#e6db74">fastcgi&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">env&lt;/span> &lt;span style="color:#e6db74">SCRIPT_FILENAME&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/smokeping.cgi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">split&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&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>&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;h3 id="4-配置-smokeping">4. 配置 SmokePing&lt;/h3>
&lt;p>创建配置文件 &lt;code>/etc/smokeping/config&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-gdscript3" data-lang="gdscript3">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">***&lt;/span> General &lt;span style="color:#f92672">***&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>owner &lt;span style="color:#f92672">=&lt;/span> Demo User
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>contact &lt;span style="color:#f92672">=&lt;/span> admin&lt;span style="color:#960050;background-color:#1e0010">@&lt;/span>example&lt;span style="color:#f92672">.&lt;/span>com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mailhost &lt;span style="color:#f92672">=&lt;/span> mail&lt;span style="color:#f92672">.&lt;/span>example&lt;span style="color:#f92672">.&lt;/span>com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sendmail &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>usr&lt;span style="color:#f92672">/&lt;/span>sbin&lt;span style="color:#f92672">/&lt;/span>sendmail
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># NOTE: do not put the Image Cache below cgi-bin&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># since all files under cgi-bin will be executed ... this is not&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># good for images.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>imgcache &lt;span style="color:#f92672">=&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>smokeping&lt;span style="color:#f92672">/&lt;/span>images
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>imgurl &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>images
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>datadir &lt;span style="color:#f92672">=&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>smokeping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>piddir &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>run&lt;span style="color:#f92672">/&lt;/span>smokeping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cgiurl &lt;span style="color:#f92672">=&lt;/span> http:&lt;span style="color:#f92672">//&lt;/span>&lt;span style="color:#ae81ff">192.168&lt;/span>&lt;span style="color:#f92672">.&lt;/span>&lt;span style="color:#ae81ff">1.100&lt;/span>&lt;span style="color:#f92672">/&lt;/span>smokeping&lt;span style="color:#f92672">.&lt;/span>cgi
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>smokemail &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>etc&lt;span style="color:#f92672">/&lt;/span>smokeping&lt;span style="color:#f92672">/&lt;/span>smokemail
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tmail &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>etc&lt;span style="color:#f92672">/&lt;/span>smokeping&lt;span style="color:#f92672">/&lt;/span>tmail
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># specify this to get syslog logging&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>syslogfacility &lt;span style="color:#f92672">=&lt;/span> local0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># each probe is now run in its own process&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># disable this to revert to the old behaviour&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># concurrentprobes = no&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="5-配置告警规则">5. 配置告警规则&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>*** Alerts ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>to = admin@example.com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>from = smokeping@example.com
&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>+hostdown
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in percent
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern ==0%,==0%,==0%, ==U
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 对端无响应
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+bigloss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in percent
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern ==0%,==0%,==0%,==0%,&amp;gt;20%,&amp;gt;20%,&amp;gt;20%
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 连续3次采样-丢包率超过20%
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+lossdetect
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in percent
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern ==0%,==0%,==0%,==0%,&amp;gt;0%,&amp;gt;0%,&amp;gt;0%
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 连续3次采样-存在丢包
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+someloss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in percent
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern &amp;gt;0%,*12*,&amp;gt;0%,*12*,&amp;gt;0%
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 间断性丢包
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+rttdetect
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = rtt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in milli seconds
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern &amp;lt;100,&amp;lt;100,&amp;lt;100,&amp;lt;100,&amp;lt;100,&amp;lt;150,&amp;gt;150,&amp;gt;150,&amp;gt;150
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 连续3次采样延迟增大-超过150ms
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="6-配置数据库设置">6. 配置数据库设置&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>*** Database ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>step = 300
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pings = 20
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># consfn mrhb steps total
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>AVERAGE 0.5 1 28800
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>AVERAGE 0.5 12 9600
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MIN 0.5 12 9600
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MAX 0.5 12 9600
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>AVERAGE 0.5 144 2400
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MAX 0.5 144 2400
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MIN 0.5 144 2400
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="7-配置显示模板">7. 配置显示模板&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>*** Presentation ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>template = /etc/smokeping/basepage.html
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>htmltitle = yes
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>graphborders = no
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># If enabled, treat all filter menu queries as literal strings instead of regex
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>literalsearch = no
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ charts
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Charts
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = The most interesting destinations
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ stddev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sorter = StdDev(entries=&amp;gt;4)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Top Standard Deviation
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Std Deviation
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>format = Standard Deviation %f
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ max
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sorter = Max(entries=&amp;gt;5)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Top Max Roundtrip Time
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = by Max
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>format = Max Roundtrip Time %f seconds
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sorter = Loss(entries=&amp;gt;5)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Top Packet Loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>format = Packets Lost %f
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ median
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sorter = Median(entries=&amp;gt;5)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Top Median Roundtrip Time
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = by Median
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>format = Median RTT %f seconds
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="8-配置探针">8. 配置探针&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>*** Probes ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ FPing
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>binary = /usr/sbin/fping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>binary = /usr/bin/dig
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>lookup = g.cn
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pings = 5
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>step = 180
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="9-配置主从模式可选">9. 配置主从模式（可选）&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>*** Slaves ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>secrets=/etc/smokeping/smokeping_secrets
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+boomer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>display_name=boomer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>color=0000ff
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+slave2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>display_name=another
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>color=00ff00
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="10-配置监控目标">10. 配置监控目标&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>*** Targets ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>alerts = someloss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>probe = FPing
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Top
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Network Latency Grapher
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>remark = Welcome to the SmokePing website of &amp;lt;b&amp;gt;Example Company&amp;lt;/b&amp;gt;. \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Here you will learn all about the latency of our network.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = 10.0.0.14 Pings
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>alerts = hostdown,bigloss,lossdetect,someloss,rttdetect
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ server1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = 192.168.1.50
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>host = 192.168.1.50
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ server2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = 192.168.1.51
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>host = 192.168.1.51
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>probe = DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>alerts = hostdown,bigloss,lossdetect,someloss,rttdetect
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ dns-server
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = 192.168.1.200
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>host = 192.168.1.200
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="启动服务">启动服务&lt;/h2>
&lt;h3 id="1-启动并启用服务">1. 启动并启用服务&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"># 启动 Caddy 服务&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service caddy start
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service caddy add
&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"># 启动 SmokePing 服务&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service smokeping start
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service smokeping add
&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"># 启动 fcgiwrap 服务&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service fcgiwrap start
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service fcgiwrap add
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-检查服务状态">2. 检查服务状态&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"># 检查 Caddy 状态&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service caddy status
&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"># 检查 SmokePing 状态&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service smokeping status
&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"># 检查 fcgiwrap 状态&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service fcgiwrap status
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="验证部署">验证部署&lt;/h2>
&lt;p>访问 &lt;code>http://192.168.1.100/smokeping.cgi&lt;/code> 验证 SmokePing 是否正常工作。&lt;/p></description><content>&lt;p>本文介绍如何在 Alpine Linux 系统上部署 SmokePing 网络延迟监控工具，使用 Caddy 作为 Web 服务器，FCGIWrap 处理 CGI 脚本。&lt;/p>
&lt;h2 id="系统要求">系统要求&lt;/h2>
&lt;ul>
&lt;li>Alpine Linux 3.18+&lt;/li>
&lt;li>2GB+ RAM（推荐 4GB+）&lt;/li>
&lt;li>20GB+ 磁盘空间&lt;/li>
&lt;li>网络连接正常&lt;/li>
&lt;/ul>
&lt;h2 id="安装步骤">安装步骤&lt;/h2>
&lt;h3 id="1-安装必要软件包">1. 安装必要软件包&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>apk update
&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"># 安装 SmokePing 及相关组件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apk add fcgiwrap fcgiwrap-openrc caddy smokeping smokeping-openrc
&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"># 创建 fcgiwrap 服务用户&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>useradd -r fcgiwrap-openrc
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-创建数据目录">2. 创建数据目录&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"># 创建 SmokePing 数据目录&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mkdir -p /var/lib/smokeping/Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mkdir -p /var/lib/smokeping/DNS
&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>chown smokeping:smokeping /var/lib/smokeping/Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chown smokeping:smokeping /var/lib/smokeping/DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chmod &lt;span style="color:#ae81ff">777&lt;/span> /var/lib/smokeping/images/Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chmod &lt;span style="color:#ae81ff">777&lt;/span> /var/lib/smokeping/images/DNS
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="3-配置-caddy-web-服务器">3. 配置 Caddy Web 服务器&lt;/h3>
&lt;p>创建 Caddy 配置文件 &lt;code>/etc/caddy/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-caddyfile" data-lang="caddyfile">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">log&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">output&lt;/span> &lt;span style="color:#e6db74">file&lt;/span> &lt;span style="color:#e6db74">/var/log/caddy/access.log&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">roll_size&lt;/span> &lt;span style="color:#e6db74">100MB&lt;/span>&lt;span style="color:#75715e"> # 单个日志文件最大 100MB
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">roll_keep&lt;/span> &lt;span style="color:#ae81ff">10&lt;/span>&lt;span style="color:#75715e"> # 保留最近 10 个日志文件
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">roll_keep_for&lt;/span> &lt;span style="color:#ae81ff">720h&lt;/span>&lt;span style="color:#75715e"> # 保留 30 天（720 小时）
&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:#66d9ef">format&lt;/span> &lt;span style="color:#e6db74">console&lt;/span>&lt;span style="color:#75715e"> # 易读的格式，也可改用 json 格式（format json）
&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>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>http://192.168.1.100 {&lt;span style="color:#75715e">
&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">&lt;/span> &lt;span style="color:#66d9ef">handle&lt;/span> &lt;span style="color:#a6e22e">/js/*&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">file_server&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:#66d9ef">handle&lt;/span> &lt;span style="color:#a6e22e">/css/*&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">file_server&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:#66d9ef">handle&lt;/span> &lt;span style="color:#a6e22e">/imgcache/*&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">file_server&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:#66d9ef">handle_path&lt;/span> &lt;span style="color:#a6e22e">/images/*&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/var/lib/smokeping/images&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">file_server&lt;/span> &lt;span style="color:#e6db74">browse&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">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> # 处理 CGI 请求
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">handle&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#a6e22e">*&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">reverse_proxy&lt;/span> &lt;span style="color:#e6db74">unix//run/fcgiwrap/fcgiwrap.sock&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">transport&lt;/span> &lt;span style="color:#e6db74">fastcgi&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">env&lt;/span> &lt;span style="color:#e6db74">SCRIPT_FILENAME&lt;/span> &lt;span style="color:#e6db74">/usr/share/webapps/smokeping/smokeping.cgi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">split&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&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>&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;h3 id="4-配置-smokeping">4. 配置 SmokePing&lt;/h3>
&lt;p>创建配置文件 &lt;code>/etc/smokeping/config&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-gdscript3" data-lang="gdscript3">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">***&lt;/span> General &lt;span style="color:#f92672">***&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>owner &lt;span style="color:#f92672">=&lt;/span> Demo User
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>contact &lt;span style="color:#f92672">=&lt;/span> admin&lt;span style="color:#960050;background-color:#1e0010">@&lt;/span>example&lt;span style="color:#f92672">.&lt;/span>com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mailhost &lt;span style="color:#f92672">=&lt;/span> mail&lt;span style="color:#f92672">.&lt;/span>example&lt;span style="color:#f92672">.&lt;/span>com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sendmail &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>usr&lt;span style="color:#f92672">/&lt;/span>sbin&lt;span style="color:#f92672">/&lt;/span>sendmail
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># NOTE: do not put the Image Cache below cgi-bin&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># since all files under cgi-bin will be executed ... this is not&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># good for images.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>imgcache &lt;span style="color:#f92672">=&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>smokeping&lt;span style="color:#f92672">/&lt;/span>images
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>imgurl &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>images
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>datadir &lt;span style="color:#f92672">=&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>smokeping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>piddir &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>run&lt;span style="color:#f92672">/&lt;/span>smokeping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cgiurl &lt;span style="color:#f92672">=&lt;/span> http:&lt;span style="color:#f92672">//&lt;/span>&lt;span style="color:#ae81ff">192.168&lt;/span>&lt;span style="color:#f92672">.&lt;/span>&lt;span style="color:#ae81ff">1.100&lt;/span>&lt;span style="color:#f92672">/&lt;/span>smokeping&lt;span style="color:#f92672">.&lt;/span>cgi
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>smokemail &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>etc&lt;span style="color:#f92672">/&lt;/span>smokeping&lt;span style="color:#f92672">/&lt;/span>smokemail
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tmail &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">/&lt;/span>etc&lt;span style="color:#f92672">/&lt;/span>smokeping&lt;span style="color:#f92672">/&lt;/span>tmail
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># specify this to get syslog logging&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>syslogfacility &lt;span style="color:#f92672">=&lt;/span> local0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># each probe is now run in its own process&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># disable this to revert to the old behaviour&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># concurrentprobes = no&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="5-配置告警规则">5. 配置告警规则&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>*** Alerts ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>to = admin@example.com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>from = smokeping@example.com
&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>+hostdown
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in percent
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern ==0%,==0%,==0%, ==U
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 对端无响应
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+bigloss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in percent
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern ==0%,==0%,==0%,==0%,&amp;gt;20%,&amp;gt;20%,&amp;gt;20%
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 连续3次采样-丢包率超过20%
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+lossdetect
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in percent
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern ==0%,==0%,==0%,==0%,&amp;gt;0%,&amp;gt;0%,&amp;gt;0%
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 连续3次采样-存在丢包
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+someloss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in percent
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern &amp;gt;0%,*12*,&amp;gt;0%,*12*,&amp;gt;0%
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 间断性丢包
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+rttdetect
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = rtt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># in milli seconds
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern &amp;lt;100,&amp;lt;100,&amp;lt;100,&amp;lt;100,&amp;lt;100,&amp;lt;150,&amp;gt;150,&amp;gt;150,&amp;gt;150
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 连续3次采样延迟增大-超过150ms
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="6-配置数据库设置">6. 配置数据库设置&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>*** Database ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>step = 300
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pings = 20
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># consfn mrhb steps total
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>AVERAGE 0.5 1 28800
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>AVERAGE 0.5 12 9600
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MIN 0.5 12 9600
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MAX 0.5 12 9600
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>AVERAGE 0.5 144 2400
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MAX 0.5 144 2400
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MIN 0.5 144 2400
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="7-配置显示模板">7. 配置显示模板&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>*** Presentation ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>template = /etc/smokeping/basepage.html
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>htmltitle = yes
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>graphborders = no
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># If enabled, treat all filter menu queries as literal strings instead of regex
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>literalsearch = no
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ charts
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Charts
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = The most interesting destinations
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ stddev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sorter = StdDev(entries=&amp;gt;4)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Top Standard Deviation
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Std Deviation
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>format = Standard Deviation %f
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ max
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sorter = Max(entries=&amp;gt;5)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Top Max Roundtrip Time
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = by Max
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>format = Max Roundtrip Time %f seconds
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sorter = Loss(entries=&amp;gt;5)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Top Packet Loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Loss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>format = Packets Lost %f
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ median
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sorter = Median(entries=&amp;gt;5)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Top Median Roundtrip Time
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = by Median
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>format = Median RTT %f seconds
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="8-配置探针">8. 配置探针&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>*** Probes ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ FPing
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>binary = /usr/sbin/fping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>binary = /usr/bin/dig
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>lookup = g.cn
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pings = 5
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>step = 180
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="9-配置主从模式可选">9. 配置主从模式（可选）&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>*** Slaves ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>secrets=/etc/smokeping/smokeping_secrets
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+boomer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>display_name=boomer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>color=0000ff
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+slave2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>display_name=another
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>color=00ff00
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="10-配置监控目标">10. 配置监控目标&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>*** Targets ***
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>alerts = someloss
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>probe = FPing
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Top
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = Network Latency Grapher
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>remark = Welcome to the SmokePing website of &amp;lt;b&amp;gt;Example Company&amp;lt;/b&amp;gt;. \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Here you will learn all about the latency of our network.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = Ping
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>title = 10.0.0.14 Pings
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>alerts = hostdown,bigloss,lossdetect,someloss,rttdetect
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ server1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = 192.168.1.50
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>host = 192.168.1.50
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ server2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = 192.168.1.51
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>host = 192.168.1.51
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+ DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>probe = DNS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>alerts = hostdown,bigloss,lossdetect,someloss,rttdetect
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>++ dns-server
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = 192.168.1.200
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>host = 192.168.1.200
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="启动服务">启动服务&lt;/h2>
&lt;h3 id="1-启动并启用服务">1. 启动并启用服务&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"># 启动 Caddy 服务&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service caddy start
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service caddy add
&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"># 启动 SmokePing 服务&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service smokeping start
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service smokeping add
&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"># 启动 fcgiwrap 服务&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service fcgiwrap start
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service fcgiwrap add
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-检查服务状态">2. 检查服务状态&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"># 检查 Caddy 状态&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service caddy status
&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"># 检查 SmokePing 状态&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service smokeping status
&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"># 检查 fcgiwrap 状态&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service fcgiwrap status
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="验证部署">验证部署&lt;/h2>
&lt;p>访问 &lt;code>http://192.168.1.100/smokeping.cgi&lt;/code> 验证 SmokePing 是否正常工作。&lt;/p>
&lt;h2 id="常见问题">常见问题&lt;/h2>
&lt;h3 id="1-caddy-启动失败">1. Caddy 启动失败&lt;/h3>
&lt;p>&lt;strong>症状&lt;/strong>：&lt;code>rc-service caddy start&lt;/code> 失败
&lt;strong>解决&lt;/strong>：&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"># 检查配置文件语法&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>caddy validate --config /etc/caddy/Caddyfile
&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>netstat -tlnp | grep &lt;span style="color:#ae81ff">80&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>netstat -tlnp | grep &lt;span style="color:#ae81ff">443&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-smokeping-无法生成图表">2. SmokePing 无法生成图表&lt;/h3>
&lt;p>&lt;strong>症状&lt;/strong>：访问 CGI 脚本显示空白或错误
&lt;strong>解决&lt;/strong>：&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"># 检查 fcgiwrap 服务&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service fcgiwrap status
&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"># 检查 CGI 脚本权限&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ls -la /usr/share/webapps/smokeping/smokeping.cgi
&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>ls -la /var/lib/smokeping/
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="3-权限问题">3. 权限问题&lt;/h3>
&lt;p>&lt;strong>症状&lt;/strong>：无法创建数据或图片
&lt;strong>解决&lt;/strong>：&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"># 确保所有目录权限正确&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chown -R smokeping:smokeping /var/lib/smokeping/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chmod -R &lt;span style="color:#ae81ff">755&lt;/span> /var/lib/smokeping/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>chmod -R &lt;span style="color:#ae81ff">777&lt;/span> /var/lib/smokeping/images/
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="4-网络连接问题">4. 网络连接问题&lt;/h3>
&lt;p>&lt;strong>症状&lt;/strong>：SmokePing 无法 ping 目标主机
&lt;strong>解决&lt;/strong>：&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"># 测试 fping 命令&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>fping -c &lt;span style="color:#ae81ff">5&lt;/span> 10.0.0.14
&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>iptables -L -n
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="日志管理">日志管理&lt;/h2>
&lt;h3 id="1-caddy-日志">1. 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-bash" data-lang="bash">&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>tail -f /var/log/caddy/access.log
&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>tail -f /var/log/messages | grep caddy
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-smokeping-日志">2. SmokePing 日志&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"># 查看 SmokePing 日志&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tail -f /var/log/messages | grep smokeping
&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>journalctl -u smokeping -f
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="定期维护">定期维护&lt;/h2>
&lt;h3 id="1-数据清理">1. 数据清理&lt;/h3>
&lt;p>SmokePing 会自动管理数据文件，但如果需要手动清理：&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"># 查看磁盘使用情况&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>du -sh /var/lib/smokeping/
&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>find /var/lib/smokeping/images -type f -mtime +90 -delete
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-服务重启">2. 服务重启&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>rc-service caddy restart
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service fcgiwrap restart
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rc-service smokeping restart
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="3-配置备份">3. 配置备份&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>tar -czf /backup/smokeping-config-&lt;span style="color:#66d9ef">$(&lt;/span>date +%Y%m%d&lt;span style="color:#66d9ef">)&lt;/span>.tar.gz &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/caddy/Caddyfile &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/smokeping/smokeping.config
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="扩展功能">扩展功能&lt;/h2>
&lt;h3 id="1-添加更多监控目标">1. 添加更多监控目标&lt;/h3>
&lt;p>在配置文件的 &lt;code>*** Targets ***&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>+ new-host
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>menu = New Host
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>host = 192.168.1.100
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>alerts = hostdown,bigloss
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-配置自定义告警">2. 配置自定义告警&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-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>+ custom-alert
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type = rtt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pattern &amp;gt;1000,&amp;lt;1000,&amp;lt;1000,&amp;lt;1000,&amp;lt;1000,&amp;lt;1000,&amp;gt;2000
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>comment = 延迟异常增高
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="性能优化">性能优化&lt;/h2>
&lt;h3 id="1-调整采样间隔">1. 调整采样间隔&lt;/h3>
&lt;p>根据网络状况调整 &lt;code>step&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>step = 600 # 10 分钟采样一次，减少资源占用
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-限制并发探针">2. 限制并发探针&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-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span># disable concurrent probes
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>concurrentprobes = no
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>通过以上配置，您将在 Alpine Linux 上成功部署一个功能完整的 SmokePing 网络监控系统，提供实时的网络延迟、丢包率和抖动监控。&lt;/p>
&lt;h2 id="参考资料">参考资料&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://www.cnblogs.com/thatsit/p/6395506.html">自定义smokeping告警(邮件+短信)&lt;/a> - 详细的配置参数和优化建议&lt;/li>
&lt;/ul></content></item><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></channel></rss>