<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[薄荷の小屋]]></title><description><![CDATA[这是一个没人光顾的小站，隐藏在互联网边缘]]></description><link>https://hoshiroko.com</link><image><url>https://api.hoshiroko.com/favicon.ico</url><title>薄荷の小屋</title><link>https://hoshiroko.com</link></image><generator>Shiro (https://github.com/Innei/Shiro)</generator><lastBuildDate>Sat, 14 Mar 2026 20:49:18 GMT</lastBuildDate><atom:link href="https://hoshiroko.com/feed" rel="self" type="application/rss+xml"/><pubDate>Sat, 14 Mar 2026 20:49:18 GMT</pubDate><language><![CDATA[zh-CN]]></language><item><title><![CDATA[二月碎碎念——真是精彩的一个月]]></title><description><![CDATA[<link rel="preload" as="image" href="https://img.hoshiroko.com/archive/dbc410cdedf70dcc.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/e6ce9538b7747dbe.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/45ea253e3a3fc15e.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/f27755f6a2901f3e.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/fe02546483eb6e86.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/e1870a05874c8630.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/3749f31f0531a0e4.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/0926af99ee33545c.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/112f0f28435f8b97.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/12a007fa4187e50d.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/8f8836f59696429c.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/836bd161517cbe6f.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/ebd9848fcb4b7d01.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/4982c54ec9d87b8f.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/85131f24869908c8.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/41d0e426b2d5d159.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/3f00b7c787adcb8b.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/9aa634b4e2f50d99.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/8dc1ca30f12c9000.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/c8ad58e1e2c251a7.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/380b07ec9f56890c.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/e0e4318dc30c077b.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/a0074a89963a1aa2.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/40690344f33cf4d9.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/bcab514df9359534.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/5efb28f6761c2495.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/e44a704024fcce25.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/8c727aee8e094579.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/bc5a0dde28e0dc9c.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/252dd346ac99adfb.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/4988cf9d2fa984f1.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/8a09b2b156e59191.png"/><div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/notes/18">https://hoshiroko.com/notes/18</a></blockquote><div><h3 id="">在杭州吃喝玩乐</h3><p>这个月1号跟朋友在杭州玩，吃了必胜客，滨寿司，海底捞</p><p>::: grid {cols=3,gap=4}</p><p><img src="https://img.hoshiroko.com/archive/dbc410cdedf70dcc.jpg" height="1280" width="1707"/></p><p><img src="https://img.hoshiroko.com/archive/e6ce9538b7747dbe.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/45ea253e3a3fc15e.jpg"/></p><p>:::</p><p>然后去了工联CC</p><p>::: grid {cols=3,gap=4}</p><p><img src="https://img.hoshiroko.com/archive/f27755f6a2901f3e.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/fe02546483eb6e86.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/e1870a05874c8630.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/3749f31f0531a0e4.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/0926af99ee33545c.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/112f0f28435f8b97.jpg"/></p><p>:::</p><p>还有其他地方就不细说了，主要是去朋友家里，或者就是在酒店玩电脑什么的 <del>(不跟家长出来玩就是松弛)</del></p><p>总结: 非常开心！全程朋友陪同，这也是我这辈子第一次去杭州吧，给了咱非常好的第一印象，还想去 (</p><h3 id="">随朋友家长前往南京</h3><p>一开始咱是想&quot;跟车去南京顺道回家方便&quot;，毕竟从杭州去南京和回安徽比较顺道。然后演变成了想多陪朋友玩 (</p><p>咱也是跟着朋友家长的车去南京了，路上还写了 <a href="https://hoshiroko.com/notes/15">见朋友家长有感</a> ，不过后续也了解到他家里也不太平。唉，家家都有本难念的经啊</p><p>然后跟他家里人去了总统府，秦淮河什么的。其实我不太喜欢去这种景点，我喜欢去打舞萌 <del>(awmc没救)</del> 。或者去体验轨交运转 <del>(hsm没救)</del>，比如我去南京最想体验的就是从金牛湖坐到高淳(坐3小时，150km铁腚)</p><h3 id="">在南京跟朋友家长纠缠</h3><p>次日，朋友被他家长拉去牛首山了。由于门票太贵加上我实在是不想去这些景点，就没跟着一起去，在酒店sleep (逃过一劫</p><p>当晚去了夫子庙，逛完后咱们都受不了了，想去&quot;二次元商场&quot;什么的。然后就已去&quot;打拍拍机(舞萌)&quot;为由让朋友家长先行回酒店了</p><p>然后去逛了水游城</p><p>::: grid {cols=3,gap=4}</p><p><img src="https://img.hoshiroko.com/archive/12a007fa4187e50d.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/8f8836f59696429c.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/836bd161517cbe6f.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/ebd9848fcb4b7d01.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/4982c54ec9d87b8f.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/85131f24869908c8.jpg"/></p><p>:::</p><p>总结：由于是跟朋友一起去的，也还算开心吧。主要是受他家长影响，去了很多我们都不爱去的景点。然后咱的运转体验也没去，ざんねん~</p><h3 id="">月初前往合肥</h3><p>这次去合肥也是去见网友的，没啥好说的，当天去当天回。带网友去吃滨寿司，去hyw出勤。一天下来还是玩的很开心的</p><p>晚上回来的时候特地买了张合肥西站的票，体验一下新开通的合肥西站</p><p>::: grid {cols=3,gap=4}</p><p><img src="https://img.hoshiroko.com/archive/41d0e426b2d5d159.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/3f00b7c787adcb8b.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/9aa634b4e2f50d99.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/8dc1ca30f12c9000.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/c8ad58e1e2c251a7.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/380b07ec9f56890c.jpg"/></p><p>:::</p><p>然后上站台坐车回家！</p><p>::: grid {cols=3,gap=4}</p><p><img src="https://img.hoshiroko.com/archive/e0e4318dc30c077b.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/a0074a89963a1aa2.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/40690344f33cf4d9.jpg"/></p><p>:::</p><h3 id="iphone">换上了iPhone与过年</h3><p>在月中，本地的朋友换了新的iPhone16 Pro，而他的iPhone13 Pro就送我了(没错，你没看错，就这么朴实无华的送我了)。买了新的手机壳，换了新电池，好用！</p><p>然后过年，我觉得跟平常没啥区别，就吃顿饭就结束了。没有了小时候对春节的那种向往，就当普通且平凡的一天就过去了。</p><p>当然体感还是有区别的，比如除夕当晚商场6点就关门了！我刚到机厅就闭店了(悲)</p><p>哦对了，除夕前天晚上我去看了《超时空辉夜姬》，好看啊！！！有点后悔没在除夕当晚看，就当春晚看了 (</p><p><img src="https://img.hoshiroko.com/archive/bcab514df9359534.jpg"/></p><h3 id="">月末杭州朋友来合肥找我玩</h3><p>在月初去杭州和南京的朋友来合肥找我玩，但是这次还是他家里人跟着(他本人快要烦死他家长了)。只不过这次幸好家长不干涉他行程，允许他与我们单走出去。</p><p>然后我把月初去合肥的网友喊上，一起吃滨寿司，去hyw出勤，在酒店一起看《超时空辉夜姬》。真的当天爽麻了，已经好久没这么开心了！</p><p>::: grid {cols=3,gap=4}</p><p><img src="https://img.hoshiroko.com/archive/5efb28f6761c2495.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/e44a704024fcce25.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/8c727aee8e094579.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/bc5a0dde28e0dc9c.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/252dd346ac99adfb.jpg"/></p><p><img src="https://img.hoshiroko.com/archive/4988cf9d2fa984f1.jpg"/></p><p>:::</p><p>最后跟朋友逛逛步行街，吃顿海底捞。咱也就回家了</p><p><strong>出游的真谛，不在于打卡了多少名胜古迹，而是取决于同行的旅伴——薄荷の尾巴</strong></p><p>总结：也是非常开心！真的！非常开心！</p><h3 id="vr">意外邂逅VR设备</h3><p>在酒店看完《超时空辉夜姬》后，咱朋友就想买Quest3S了，说&quot;想登录月读&quot;。然后第二天他就真买了</p><p>咱看完也是馋得不行，外加朋友说&quot;你也买！买来我们一起登录月读&quot;。咱真的非常心动，最后没控制住 -2000￥</p><p><img src="https://img.hoshiroko.com/archive/8a09b2b156e59191.png"/></p><p>目前到手真的每天都玩，不是打游戏也是看视频。咱觉得都不用买电视了 (这篇文章都是咱带着头显，挂着VRChat，SteamVR菜单串流桌面写出来的qwq)</p><p>而且咱真的不晕，坐电脑面前戴着头显开欧卡一点晕的感觉都没有。至少今晚已经一口气戴了6小时了，除了眼睛有点累以外别的都还行 (</p><h3 id="">本月总结</h3><p>我觉得二月碎碎念已经可以当一篇文章来写了，确实非常精彩</p><ul><li><strong>本月减肥</strong>：<strong>-0.7 千克</strong> | 距离目标还剩 <strong>24.2 千克</strong>（体重还重了！出去玩大吃大喝导致的！呜呜呜）</li><li><strong>本月最喜欢歌曲</strong>：<a href="https://music.163.com/song?id=3340112782">星降る海</a></li><li><strong>本月最喜欢游戏</strong>：<a href="https://store.steampowered.com/app/438100">VRChat</a></li></ul></div><p style="text-align:right"><a href="https://hoshiroko.com/notes/18#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/notes/18</link><guid isPermaLink="true">https://hoshiroko.com/notes/18</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Wed, 25 Feb 2026 20:47:23 GMT</pubDate></item><item><title><![CDATA[个人笔记-2]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/posts/notes/2">https://hoshiroko.com/posts/notes/2</a></blockquote><div><p>这是我的第二篇个人笔记，就如标题所示，这是我自己的个人笔记(个人向的)用来记录我平常遇到的一些需要记录的知识点</p><p>所有内容不做讲解，只讲操作，有需要自行阅读。在个人笔记的内容一般毕竟零碎且杂乱，请见谅</p><h2 id="systemd-timesyncd">systemd-timesyncd同步服务器时间</h2><p>安装</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">apt purge ntp chrony
apt update
apt install systemd-timesyncd
</code></pre>
<p>配置</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">nano /etc/systemd/timesyncd.conf
</code></pre>
<pre class=""><code class="">[Time]
NTP=time.cloudflare.com time.apple.com time.windows.com
</code></pre>
<p>(如果你的机器位于中国大陆)</p><pre class=""><code class="">[Time]
NTP=ntp.ntsc.ac.cn ntp.aliyun.com ntp.tencent.com
</code></pre>
<p>重启服务</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">systemctl restart systemd-timesyncd
</code></pre>
<p>设置 RTC 为 UTC</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">timedatectl set-local-rtc 0
</code></pre>
<p>设置服务器为 UTC+8</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">timedatectl set-timezone Asia/Shanghai
</code></pre>
<p>检查运行状态</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">timedatectl
</code></pre>
<h2 id="dockersocks5">docker快速搭建socks5</h2><p>安装docker可跳转:  <a href="https://hoshiroko.com/posts/course/linux-install-docker-guide">Linux安装Docker的详细流程及基础命令</a></p><p>也可:</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">curl -fsSL https://get.docker.com | bash -s docker
</code></pre>
<p>拉取并运行镜像</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">docker run -d --name socks5 --restart=unless-stopped -p &lt;PROXY_PORT&gt;:1080 -e PROXY_USER=&lt;PROXY_USER&gt; -e PROXY_PASSWORD=&lt;PROXY_PASSWORD&gt; serjs/go-socks5-proxy
</code></pre>
<pre class=""><code class="">&lt;PROXY_PORT&gt;是外部访问端口
&lt;PROXY_USER&gt;是连接用户名
&lt;PROXY_PASSWORD&gt;是连接密码 (设置长一点，推荐16位数字+混合大小写起步)
</code></pre>
<h2 id="realm-">Realm 端口转发</h2><p>下载文件</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">wget -O realm.tar.gz https://github.com/zhboner/realm/releases/download/v2.9.3/realm-x86_64-unknown-linux-gnu.tar.gz
</code></pre>
<p>解压并赋予执行权限</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">tar -xvf realm.tar.gz
chmod +x realm
mv realm /usr/local/bin/
</code></pre>
<p>创建配置文件</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">mkdir -p /etc/realm
nano /etc/realm/config.toml
</code></pre>
<p>编写配置文件</p><pre class=""><code class="">[network]
no_tcp = false # 是否关闭 TCP
use_udp = true # 是否开启 UDP

[[endpoints]]
listen = &quot;0.0.0.0:22&quot;      # 中转监听端口
remote = &quot;1.1.1.1:22&quot;      # 目标服务器 IP:端口

[[endpoints]]
listen = &quot;0.0.0.0:3389&quot;      # 中转监听端口
remote = &quot;3.3.3.3:3389&quot;      # 目标服务器 IP:端口

...
</code></pre></div><p style="text-align:right"><a href="https://hoshiroko.com/posts/notes/2#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/posts/notes/2</link><guid isPermaLink="true">https://hoshiroko.com/posts/notes/2</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Sat, 14 Feb 2026 16:06:05 GMT</pubDate></item><item><title><![CDATA[差点把主站玩炸了]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/notes/17">https://hoshiroko.com/notes/17</a></blockquote><div><p>是这样的，今天我无聊就跑去 <a href="https://github.com/mx-space/core">mix-space</a> 看看后端有没有更新，然后看到了有 v10 版本的更新，就直接上控制台更新了</p><p>更新完后觉得还不太成熟想恢复 v9.7 版本，发现恢复后怎么也登不上去了。估计是数据库版本有更新，导致无法降级。</p><p>然后在我的一顿瞎捣鼓下，成功把后端数据库给干废了（上次给别人统一认证数据库干废了，这次给自己主站数据库干废了，也是人才！）。然后就是后端进不去，前端连不上后端就报错。</p><p>这时我突然想起来我 1Panel 有设置每天定时备份整个主站 docker compose 目录（包含前后端）。我火速跑到 nas 里把备份压缩包传到服务器上重建镜像，然后死而复生。差点没给我吓死。</p><p>最后我决定到 1Panel 里面把备份 执行周期 从原来的 &quot;每天备份&quot; 改成 &quot;每八小时备份&quot; ，保留份数也从原来的 3 份改成 30 份，属实是被吓哭了。</p></div><p style="text-align:right"><a href="https://hoshiroko.com/notes/17#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/notes/17</link><guid isPermaLink="true">https://hoshiroko.com/notes/17</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Mon, 09 Feb 2026 16:51:03 GMT</pubDate></item><item><title><![CDATA[一月碎碎念——朋友终于回来了]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/notes/16">https://hoshiroko.com/notes/16</a></blockquote><div><ul><li>我决定从今年开始每月写&quot;个人月报&quot;，主要每月生活记录生活</li></ul><h2 id="">生活记录：</h2><ul><li><strong>久违的重逢</strong>：这个月朋友回来了，生活里总算是有个伴，开心喵。</li><li><strong>关于天气</strong>：下雪了！虽然景色还行，但害得我无法出门运动（借口+1）。</li><li><strong>折腾 NAS</strong>：给 NAS 换了个硬盘，3T 的盘花了 375 大洋，好贵啊！</li><li><strong>舞萌 DX</strong>：遇到了全国大断网事件，被迫使用游客模式。</li></ul><h2 id="">本月总结：</h2><ul><li><strong>本月减肥</strong>：<strong>6斤</strong> | 距离目标还剩 <strong>46.2 斤</strong>（冷死了，根本不想出去qwq）</li><li><strong>本月最喜欢歌曲</strong>：<a href="https://music.163.com/song?id=2669744837">スマイル*シンフォニー</a></li><li><strong>本月最喜欢游戏</strong>：<a href="https://store.steampowered.com/app/1366540">戴森球计划</a></li></ul></div><p style="text-align:right"><a href="https://hoshiroko.com/notes/16#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/notes/16</link><guid isPermaLink="true">https://hoshiroko.com/notes/16</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Fri, 06 Feb 2026 16:20:14 GMT</pubDate></item><item><title><![CDATA[见朋友家长有感]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/notes/15">https://hoshiroko.com/notes/15</a></blockquote><div><p>离开杭州的当天，我坐上了朋友家长开的车准备前往下一目的地，在与朋友母亲沟通中我开始不由自主羡慕对方的家庭。</p><p>原因是，咱看咱朋友和他母亲沟通有说有笑，可以随心所欲在车上连蓝牙播放自己的网易云歌单，畅聊自己的兴趣爱好。</p><p>而咱从小被教育“要大众化”，要求咱的各种爱好都要大众化。咱家长也是比较的“气势凌人”，就别说咱敢不敢在我家里人车上连蓝牙，我这辈子都没坐过几次我爸的车。</p><p>所以种种因素养成了“不敢在外面随便暴露自己兴趣爱好”的性格，其实说白了就是没自信，多年被指责兴趣爱好“不合群”。</p><p>可能我以后买车了第一件事就是自己坐在车上连蓝牙音量拉满爽听。挺荒谬的不是吗（笑</p></div><p style="text-align:right"><a href="https://hoshiroko.com/notes/15#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/notes/15</link><guid isPermaLink="true">https://hoshiroko.com/notes/15</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Tue, 03 Feb 2026 02:41:37 GMT</pubDate></item><item><title><![CDATA[wmc到商场门口一抬头天塌了]]></title><description><![CDATA[<link rel="preload" as="image" href="https://img.hoshiroko.com/archive/3392bb0bfe74318b.jpg"/><div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/notes/14">https://hoshiroko.com/notes/14</a></blockquote><div><p><img src="https://img.hoshiroko.com/archive/3392bb0bfe74318b.jpg" height="1920" width="1440"/></p><p>还有高松灯？还有咕咕嘎嘎？
被吓哭</p></div><p style="text-align:right"><a href="https://hoshiroko.com/notes/14#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/notes/14</link><guid isPermaLink="true">https://hoshiroko.com/notes/14</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Fri, 30 Jan 2026 05:44:23 GMT</pubDate></item><item><title><![CDATA[对于 PaaS 的感想]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/notes/13">https://hoshiroko.com/notes/13</a></blockquote><div><p>我在 <a href="https://hoshiroko.com/posts/course/mix-space">Mix Space + Shiro 全容器化部署指南</a> 这篇文章里提到 &quot;因为我偏好自托管，不太喜欢PaaS&quot; 这句话，那写完后我就在想，我能接受 GitHub Actions 这种 CI 工具，应该不代表说我讨厌这类服务</p><p>然后我转头去问了 Gemini ，聊了一会后我得出结论了。我讨厌的是那种全套网站托管的那种，比如 Vercel ，Cloudflare Workers，GitHub Pages 各种可以&quot;托管网站&quot;的动静函数 PaaS</p><p>Gemini给我举了个例子我觉得很好。各种 PaaS 就像是租房的&quot;房东&quot;，你把代码给它们，它们给你提供房子（服务器），水电（网络），保安（运维）。而自建VPS+CDN就像是自己房子里（虽然服务器也是租赁的，但是毕竟是系统层级的，不是应用层级的）。这时候 GitHub Actions 就像是&quot;装修队&quot;，你把代码给它，它帮你把家具组装好（构建 Docker 镜像）。组装完了它就走了，家具是搬回你自己的房子（VPS）里用的。</p><p>我可能就是没有这种&quot;安全感&quot;，觉得东西得在自己手上才放心，也可能有点病态吧（</p></div><p style="text-align:right"><a href="https://hoshiroko.com/notes/13#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/notes/13</link><guid isPermaLink="true">https://hoshiroko.com/notes/13</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Mon, 26 Jan 2026 13:59:20 GMT</pubDate></item><item><title><![CDATA[Mix Space + Shiro 全容器化部署指南]]></title><description><![CDATA[<link rel="preload" as="image" href="https://img.hoshiroko.com/archive/53e9ddeb691b0a89.png"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/2ae1ad98b438c1c6.png"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/a78e6f6079530c3f.png"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/b1761bda369e0ad3.png"/><div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/posts/course/mix-space">https://hoshiroko.com/posts/course/mix-space</a></blockquote><div><p>Mix Space 是一个采用前后端分离架构的现代化个人空间后端；Shiro 则是其官方配套的高颜值前端主题，基于 Next.js 构建，以极简设计和流畅动画著称。两者搭配使用，能为你提供一个集文章写作、日常动态发布于一体，且兼具极致性能与视觉美感的个人博客系统。——Gemini</p><p>我之前都是用Hexo的，苦于更新困难+功能单一 (因为我偏好自托管，不太喜欢PaaS) 。就算更新一个字，都得打包重新上传服务器，这样使得碎片化写作变得很困难。</p><p>Mix Space和Shiro是相辅相成的，分别是后端 (Core) 和前端 (Theme)，当然也有些别的前端主题 (比如 <a href="https://mx-space.js.org/docs/themes/kami">Kami</a> ，<a href="https://mx-space.js.org/docs/themes/yun">Yun</a>)。本篇只讲解Mix Space (后端) 和Shiro (前端)</p><p>部署后端可以直接使用官方提供的预构建Docker镜像。而Shiro前端可以使用预构建Docker镜像，也可以自构建Docker镜像。自构建可以对前端页面进行深度修改 (如果你需要悬挂两个及以上备案号，那就必须得自构建了)。</p><p>闲话少说，开整！</p><h2 id="mix-space">Mix Space部署</h2><h3 id="">拉取镜像</h3><p>后端部署直接Docker Compose拉取镜像就可以跑</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">cd &amp;&amp; mkdir -p mx-space/core &amp;&amp; cd $_
nano docker-compose.yml
</code></pre>
<p>然后在 <code>docker-compose.yml</code> 写入：</p><pre class="language-yml lang-yml"><code class="language-yml lang-yml">services:
  app:
    container_name: mx-server
    image: innei/mx-server:latest
    environment:
      - TZ=Asia/Shanghai
      - NODE_ENV=production
      - DB_HOST=mongo
      - REDIS_HOST=redis
      - ALLOWED_ORIGINS=localhost
      - JWT_SECRET=YOUR_SUPER_SECURED_JWT_SECRET_STRING
    volumes:
      - ./data/mx-space:/root/.mx-space
    ports:
      - &#x27;2333:2333&#x27;
    depends_on:
      - mongo
      - redis
    networks:
      - mx-space
    restart: unless-stopped
    healthcheck:
      test: [CMD, curl, -f, &#x27;http://127.0.0.1:2333/api/v2/ping&#x27;]
      interval: 1m30s
      timeout: 30s
      retries: 5
      start_period: 30s

  mongo:
    container_name: mongo
    image: mongo:7
    volumes:
      - ./data/db:/data/db
    networks:
      - mx-space
    restart: unless-stopped

  redis:
    image: redis:alpine
    container_name: redis
    volumes:
      - ./data/redis:/data
    healthcheck:
      test: [CMD-SHELL, &#x27;redis-cli ping | grep PONG&#x27;]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 3s
    networks:
      - mx-space
    restart: unless-stopped

networks:
  mx-space:
    driver: bridge
</code></pre>
<ul><li><code>JWT_SECRET</code> 需要填写长度不小于 16 个字符，不大于 32 个字符的字符串</li><li><code>ALLOWED_ORIGINS</code> 需要填写被允许的域名，通常是前端的域名，如果允许多个域名访问，用英文逗号，分隔。</li></ul><p>其他可以根据需要自己修改，比如 <code>&#x27;2333:2333&#x27;</code> 改成 <code>&#x27;127.0.0.1:2333:2333&#x27;</code></p><p>然后就可以启动Core了</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">docker compose up -d
</code></pre>
<h3 id="">反向代理</h3><p>推荐使用 <code>1Panel</code> 或者 <code>宝塔</code> 之类的现代面板操作，非常简单</p><p>新建网站，配置反代，URL地址 <code>http://127.0.0.1:2333</code> 就完事了</p><p>如果要手搓Nginx可以参考 <a href="https://mx-space.js.org/docs/core/extra#%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86">官方Docs</a></p><h3 id="">后端配置</h3><p>去网站设置里把 <code>前端地址</code> <code>管理后台地址</code> <code>API 地址</code> <code>Gateway 地址</code> 分别设置成</p><ul><li>前端地址:  <code>{Shiro地址}</code></li><li>管理后台地址:  <code>{后台地址}/proxy/qaqdmin</code></li><li>API 地址: <code>{后台地址}/api/v2</code></li><li>Gateway 地址: <code>{后台地址}</code></li></ul><p>其他的就自己看着配置就行了</p><h2 id="shiro">Shiro部署</h2><p>进入 Mix Space 后台，进入「配置与云函数」页面，点击右上角的新增按钮，在编辑页面中，填入以下内容:</p><ul><li>名称: <code>shiro</code></li><li>引用: <code>theme</code></li><li>数据类型: <code>JSON</code></li><li>数据:</li></ul><p>以下内容根据自己需要修改</p><pre class="language-json lang-json"><code class="language-json lang-json">{
  &quot;footer&quot;: {
    &quot;otherInfo&quot;: {
      &quot;date&quot;: &quot;202x-{{now}}&quot;,
      &quot;icp&quot;: {
        &quot;text&quot;: &quot;萌 ICP 备 xxxxxxxx 号&quot;,
        &quot;link&quot;: &quot;https://icp.gov.moe/?keyword=xxxxxxxx&quot;
      }
    },
    &quot;linkSections&quot;: [
      {
        &quot;name&quot;: &quot;关于&quot;,
        &quot;links&quot;: [
          {
            &quot;name&quot;: &quot;关于本站&quot;,
            &quot;href&quot;: &quot;/about-site&quot;
          },
          {
            &quot;name&quot;: &quot;关于我&quot;,
            &quot;href&quot;: &quot;/about&quot;
          },
          {
            &quot;name&quot;: &quot;关于此项目&quot;,
            &quot;href&quot;: &quot;https://github.com/innei/Shiro&quot;,
            &quot;external&quot;: true
          }
        ]
      },
      {
        &quot;name&quot;: &quot;更多&quot;,
        &quot;links&quot;: [
          {
            &quot;name&quot;: &quot;时间线&quot;,
            &quot;href&quot;: &quot;/timeline&quot;
          },
          {
            &quot;name&quot;: &quot;友链&quot;,
            &quot;href&quot;: &quot;/friends&quot;
          },
          {
            &quot;name&quot;: &quot;监控&quot;,
            &quot;href&quot;: &quot;https://status.xxxxx.xxx&quot;,
            &quot;external&quot;: true
          }
        ]
      },
      {
        &quot;name&quot;: &quot;联系&quot;,
        &quot;links&quot;: [
          {
            &quot;name&quot;: &quot;写留言&quot;,
            &quot;href&quot;: &quot;/message&quot;
          },
          {
            &quot;name&quot;: &quot;发邮件&quot;,
            &quot;href&quot;: &quot;mailto:xxx@xxx.xxx&quot;,
            &quot;external&quot;: true
          },
          {
            &quot;name&quot;: &quot;GitHub&quot;,
            &quot;href&quot;: &quot;https://github.com/xxx&quot;,
            &quot;external&quot;: true
          }
        ]
      }
    ]
  },
  &quot;config&quot;: {
    &quot;color&quot;: {
      &quot;light&quot;: [
        &quot;#33A6B8&quot;,
        &quot;#FF6666&quot;,
        &quot;#26A69A&quot;,
        &quot;#fb7287&quot;,
        &quot;#69a6cc&quot;,
        &quot;#F11A7B&quot;,
        &quot;#78C1F3&quot;,
        &quot;#FF6666&quot;,
        &quot;#7ACDF6&quot;
      ],
      &quot;dark&quot;: [
        &quot;#F596AA&quot;,
        &quot;#A0A7D4&quot;,
        &quot;#ff7b7b&quot;,
        &quot;#99D8CF&quot;,
        &quot;#838BC6&quot;,
        &quot;#FFE5AD&quot;,
        &quot;#9BE8D8&quot;,
        &quot;#A1CCD1&quot;,
        &quot;#EAAEBA&quot;
      ]
    },
 
    &quot;bg&quot;: [
      &quot;/static/images/xxxxx.jpeg&quot;,
      &quot;/static/images/xxxxx.jpg&quot;
    ],
    &quot;custom&quot;: {
      &quot;css&quot;: [],
      &quot;styles&quot;: [],
      &quot;js&quot;: [],
      &quot;scripts&quot;: []
    },
    &quot;site&quot;: {
      &quot;favicon&quot;: &quot;/xxxxx.svg&quot;,
      &quot;faviconDark&quot;: &quot;/xxxxx-dark.svg&quot;
    },
    &quot;hero&quot;: {
      &quot;title&quot;: {
        &quot;template&quot;: [
          {
            &quot;type&quot;: &quot;h1&quot;,
            &quot;text&quot;: &quot;xxxxxxx&quot;,
            &quot;class&quot;: &quot;font-light text-4xl&quot;
          },
          {
            &quot;type&quot;: &quot;h1&quot;,
            &quot;text&quot;: &quot;xxxxxxx&quot;,
            &quot;class&quot;: &quot;font-medium mx-2 text-4xl&quot;
          },
          {
            &quot;type&quot;: &quot;h1&quot;,
            &quot;text&quot;: &quot;👋。&quot;,
            &quot;class&quot;: &quot;font-light text-4xl&quot;
          },
          {
            &quot;type&quot;: &quot;br&quot;
          },
          {
            &quot;type&quot;: &quot;h1&quot;,
            &quot;text&quot;: &quot;xxxxxxx&quot;,
            &quot;class&quot;: &quot;font-light text-4xl&quot;
          },
          {
            &quot;type&quot;: &quot;code&quot;,
            &quot;text&quot;: &quot;&lt;Developer /&gt;&quot;,
            &quot;class&quot;: &quot;font-medium mx-2 text-3xl rounded p-1 bg-gray-200 dark:bg-gray-800/0 hover:dark:bg-gray-800/100 bg-opacity-0 hover:bg-opacity-100 transition-background duration-200&quot;
          },
          {
            &quot;type&quot;: &quot;span&quot;,
            &quot;class&quot;: &quot;inline-block w-[1px] h-8 -bottom-2 relative bg-gray-800/80 dark:bg-gray-200/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 group-hover:animation-blink&quot;
          }
        ]
      },
      &quot;description&quot;: &quot;xxxxxxxxxxxxxxxxxxxx&quot;
    },
    &quot;module&quot;: {
      &quot;activity&quot;: {
        &quot;enable&quot;: true,
        &quot;endpoint&quot;: &quot;/fn/ps/update&quot;
      },
      &quot;donate&quot;: {
        &quot;enable&quot;: true,
        &quot;link&quot;: &quot;https://afdian.net/xxxxx&quot;,
        &quot;qrcode&quot;: [
          &quot;/static/images/xxxxxx.png&quot;,
          &quot;/static/images/xxxxxx.png&quot;
        ]
      },
      &quot;bilibili&quot;: {
        &quot;liveId&quot;: 1
      }
    }
  }
}
</code></pre>
<p>Shiro前端部署可以分为官方提供的预构建和自构建版本，按需选择</p><p>预构建适合打算快速建站使用，但是不能深度修改。还是那句话：按需选择</p><p>再提一嘴，如果你赞助的闭源版本Shiroi，那就只能选择自构建，因为官方没有提供预构建镜像</p><h3 id="">预构建</h3><p>预构建就很快速了，直接拉取官方镜像配置好环境变量就可以上线了</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">mkdir shiro &amp;&amp; cd shiro
nano docker-compose.yml
</code></pre>
<pre class="language-yml lang-yml"><code class="language-yml lang-yml">services:
  shiro:
    container_name: shiro
    image: innei/shiro:latest
    volumes:
      - ./.env:/app/.env
      - ./public:/app/public
    restart: always
    environment:
      - NEXT_SHARP_PATH=/usr/local/lib/node_modules/sharp
    ports:
      - 2323:2323
</code></pre>
<p>配置环境变量</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">nano .env
</code></pre>
<p>然后填入</p><pre class=""><code class="">NEXT_PUBLIC_API_URL=https://{后端地址}/api/v2
NEXT_PUBLIC_GATEWAY_URL=https://{后端地址}
</code></pre>
<p>填完就可以 <code>docker compose up -d</code> 了</p><h3 id="">自构建</h3><p>自构建稍微麻烦点，但是如果想深度定制，那这是你唯一的选择</p><p>这里我们使用 GitHub Actions 来构建 Docker 镜像，方便快捷</p><p>前往自己的 GitHub 建一个仓库，推荐私密仓库，待会要用</p><p>确保你电脑安装了 <a href="https://git-scm.com/">Git</a></p><p>找个目录打开终端，执行以下命令。注意：不要删除 <code>.git</code> 文件夹，我们采用“重命名远程仓库”的方式，这样以后原作者更新了，也能同步合并</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell"># 克隆原作者的代码
git clone https://github.com/Innei/Shiro.git
cd Shiro

# 重命名原作者的仓库为 &quot;upstream&quot;
git remote rename origin upstream

# 替换下面的 URL 为你自己刚创建的 GitHub 仓库地址
git remote add origin https://github.com/xxxxxx/xxxxx.git
</code></pre>
<p>重点来了！前往并清空 <code>.github</code> / <code>workflows</code> 文件夹后新建 <code>docker-main.yml</code></p><p>并在里面填写:</p><pre class="language-yml lang-yml"><code class="language-yml lang-yml">name: Docker (Main Branch)

on:
  workflow_dispatch:
  push:
    branches:
      - main
  repository_dispatch:
    types: [trigger-workflow]

permissions: write-all
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  PNPM_VERSION: 9.x.x
  HASH_FILE: path/to/hash/file.txt
  TZ: Asia/Shanghai

jobs:
  prepare:
    name: Prepare
    runs-on: ubuntu-latest
    if: ${{ github.event.head_commit.message != &#x27;Update hash file&#x27; }}
    outputs:
      hash_content: ${{ steps.read_hash.outputs.hash_content }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Read HASH_FILE content
        id: read_hash
        run: |
          content=$(cat ${{ env.HASH_FILE }}) || true
          echo &quot;hash_content=$content&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;

  check:
    name: Check Should Rebuild
    runs-on: ubuntu-latest
    needs: prepare
    outputs:
      canceled: ${{ steps.use_content.outputs.canceled }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          lfs: true

      - name: Use content from prev job and compare
        id: use_content
        env:
          FILE_HASH: ${{ needs.prepare.outputs.hash_content }}
        run: |
          file_hash=$FILE_HASH
          current_hash=$(git rev-parse --short HEAD)
          echo &quot;File Hash: $file_hash&quot;
          echo &quot;Current Git Hash: $current_hash&quot;
          if [ &quot;$file_hash&quot; == &quot;$current_hash&quot; ]; then
            echo &quot;Hashes match. Stopping workflow.&quot;
            echo &quot;canceled=true&quot; &gt;&gt; $GITHUB_OUTPUT
          else
            echo &quot;Hashes do not match. Continuing workflow.&quot;
          fi

  build:
    name: Build artifact
    runs-on: ubuntu-latest
    needs: check
    if: ${{ needs.check.outputs.canceled != &#x27;true&#x27; }}
    outputs:
      sha_short: ${{ steps.store.outputs.sha_short }}
      branch: ${{ steps.store.outputs.branch }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          lfs: true

      - name: Set up Image Name
        run: |
          IMAGE_ID=ghcr.io/${{ github.repository }}
          IMAGE_ID=$(echo $IMAGE_ID | tr &#x27;[A-Z]&#x27; &#x27;[a-z]&#x27;)
          echo &quot;IMAGE_ID=$IMAGE_ID&quot; &gt;&gt; $GITHUB_ENV

      - name: Login to Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Store artifact commit version
        shell: bash
        id: store
        run: |
          sha_short=$(git rev-parse --short HEAD)
          branch_name=$(git rev-parse --abbrev-ref HEAD)
          echo &quot;sha_short=$sha_short&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;
          echo &quot;branch=$branch_name&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;

      - name: Build Docker Image
        run: |
          docker build --build-arg TZ=Asia/Shanghai -t ${{ env.IMAGE_ID }}:${{ steps.store.outputs.sha_short }} .
  
      - name: Push Docker Image to Github
        run: |
          docker push ${{ env.IMAGE_ID }}:${{ steps.store.outputs.sha_short }}

      - name: Tag Docker Image as latest
        run: |
          docker tag ${{ env.IMAGE_ID }}:${{ steps.store.outputs.sha_short }} ${{ env.IMAGE_ID }}:latest
  
      - name: Push Docker Image as latest
        run: |
          docker push ${{ env.IMAGE_ID }}:latest
</code></pre>
<p>保存并退出</p><p>然后返回CMD窗口</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell"># 确保分支名为 main
git branch -M main

# 提交第一次修改(可以自定义)
git add .
git commit -m &quot;Hello World&quot;

# 推送到你的仓库
git push -u origin main
</code></pre>
<p>推送完成后返回 GitHub 仓库查看</p><p><img src="https://img.hoshiroko.com/archive/53e9ddeb691b0a89.png" height="304" width="563"/></p><p>可以点击旁边的小黄点查看进程</p><p><img src="https://img.hoshiroko.com/archive/2ae1ad98b438c1c6.png" height="247" width="806"/></p><p><img src="https://img.hoshiroko.com/archive/a78e6f6079530c3f.png" height="837" width="877"/></p><p><img src="https://img.hoshiroko.com/archive/b1761bda369e0ad3.png" height="908" width="866"/></p><p>构建完成后还需在服务器上配置 GitHub Token 才能拉取</p><ul><li>前往 GitHub → 点击头像 → Settings → Developer Settings → Personal access tokens (classic) 里创建一个 Token</li><li>时间可以永久，权限只设置 <code>read:packages</code> 即可</li><li>前往服务器输入 <code>echo &quot;{你的Token}&quot; | docker login ghcr.io -u {你的GitHub ID} --password-stdin</code></li></ul><p>然后按照流程来就可以了</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">mkdir shiro &amp;&amp; cd shiro
nano docker-compose.yml
</code></pre>
<pre class="language-yml lang-yml"><code class="language-yml lang-yml">services:
  shiro:
    container_name: shiro
    image: ghcr.io/{你的GitHub ID}/{你的仓库名}:latest
    volumes:
      - ./.env:/app/.env
      - ./public:/app/public
    restart: always
    environment:
      - NEXT_SHARP_PATH=/usr/local/lib/node_modules/sharp
    ports:
      - 2323:2323
</code></pre>
<p>配置环境变量</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">nano .env
</code></pre>
<p>然后填入</p><pre class=""><code class="">NEXT_PUBLIC_API_URL=https://{后端地址}/api/v2
NEXT_PUBLIC_GATEWAY_URL=https://{后端地址}
</code></pre>
<p>填完就可以 <code>docker compose up -d</code> 了</p><p>好了，现在一套流程已经走完了，具体要怎么折腾，就看各位了</p><h4 id="">更新代码</h4><p>随着原作者的不断更新，你可能想要同步最新的功能。不过得益于我们刚才保留了 Git 历史并配置了 upstream，更新就变得非常简单</p><p>如果在不冲突的情况下只需要三行命令就可以完成更新</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell"># 拉取原作者的最新代码
git fetch upstream

# 合并到本地
git merge upstream/main

# 推送到你自己的仓库
git push origin main
</code></pre>
<p>如果冲突，那就到 VS Code 里&quot;调停&quot;一下吧（</p><h3 id="">尾巴</h3><p>如果你的服务器位于中国大陆，拉取 ghcr.io 镜像可能会非常缓慢甚至失败。为了解决这个问题，可以在构建完成后将镜像同步推送到阿里云 ACR</p><p>在 <code>docker-main.yml</code> 的 <code>env</code> 区域添加</p><pre class="language-yml lang-yml"><code class="language-yml lang-yml"># 你的阿里云镜像仓库地址
ALIYUN_REGISTRY:  crpi-xxxxxxxxx.cn-shanghai.personal.cr.aliyuncs.com

# 你的命名空间
ALIYUN_NAMESPACE: xxxxx

# 你的仓库名
ALIYUN_REPO: xxxxx
</code></pre>
<p>然后在文件最后加上</p><pre class="language-yml lang-yml"><code class="language-yml lang-yml">- name: Login to Aliyun ACR
  uses: docker/login-action@v3
  with:
    registry: ${{ env.ALIYUN_REGISTRY }}
    username: ${{ secrets.ALIYUN_USERNAME }}
    password: ${{ secrets.ALIYUN_PASSWORD }}

- name: Tag &amp; Push Image to Aliyun (Hash)
  run: |
    ALIYUN_IMAGE=&quot;${{ env.ALIYUN_REGISTRY }}/${{ env.ALIYUN_NAMESPACE }}/${{ env.ALIYUN_REPO }}:${{ steps.store.outputs.sha_short }}&quot;
    docker tag ${{ env.IMAGE_ID }}:${{ steps.store.outputs.sha_short }} $ALIYUN_IMAGE
    docker push $ALIYUN_IMAGE

- name: Tag &amp; Push Image to Aliyun (Latest)
  run: |
    ALIYUN_IMAGE_LATEST=&quot;${{ env.ALIYUN_REGISTRY }}/${{ env.ALIYUN_NAMESPACE }}/${{ env.ALIYUN_REPO }}:latest&quot;
    docker tag ${{ env.IMAGE_ID }}:latest $ALIYUN_IMAGE_LATEST
    docker push $ALIYUN_IMAGE_LATEST
</code></pre>
<p>接着，请将阿里云账户全名和 ACR 实例的独立登录密码，分别配置到仓库 Actions Secrets 的 <code>ALIYUN_USERNAME</code> 和 <code>ALIYUN_PASSWORD</code> 变量中</p><p>配置完成后，下一次推送代码时，GitHub Actions 就会自动将镜像同步到阿里云。这样一来，国内服务器就再也不会拉镜像拉半小时了</p></div><p style="text-align:right"><a href="https://hoshiroko.com/posts/course/mix-space#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/posts/course/mix-space</link><guid isPermaLink="true">https://hoshiroko.com/posts/course/mix-space</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Sun, 25 Jan 2026 12:41:27 GMT</pubDate></item><item><title><![CDATA[冬天的第一场雪]]></title><description><![CDATA[<link rel="preload" as="image" href="https://img.hoshiroko.com/archive/c735500365ce225b.jpg"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/beb67e19c3d09246.jpg"/><div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/notes/12">https://hoshiroko.com/notes/12</a></blockquote><div><p>已经好久没见过下雪长什么样的了，但是我现在对下雪已经祛魅了</p><p>现在我只觉得下雪路上好滑影响我走路（</p><p>图片已经是雪停了两天后拍的了（下着大雪出门分分钟冻死你XD，冻不死也摔死XD）</p><p>::: grid {cols=2,gap=1}</p><p><img src="https://img.hoshiroko.com/archive/c735500365ce225b.jpg" height="1920" width="1440"/></p><p><img src="https://img.hoshiroko.com/archive/beb67e19c3d09246.jpg"/></p><p>:::</p></div><p style="text-align:right"><a href="https://hoshiroko.com/notes/12#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/notes/12</link><guid isPermaLink="true">https://hoshiroko.com/notes/12</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Wed, 21 Jan 2026 14:49:43 GMT</pubDate></item><item><title><![CDATA[RustDesk 自建指南：基于 Docker 部署官方与第三方开源全功能服务端]]></title><description><![CDATA[<link rel="preload" as="image" href="https://img.hoshiroko.com/archive/d97476212552e7bc.png"/><link rel="preload" as="image" href="https://img.hoshiroko.com/archive/e917b51548ef9a59.png"/><div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://hoshiroko.com/posts/course/rustdesk">https://hoshiroko.com/posts/course/rustdesk</a></blockquote><div><p>RustDesk是一款开源远程桌面软件。与传统商业软件不同，RustDesk最大的优势在于支持自建服务器。这意味着可以完全掌控数据，不再受限于公共服务器的带宽瓶颈和次数限制，实现低延迟、高画质的私有远程连接体验。——Gemini</p><p>之所以会用RustDesk其实是因为受不了国内的有些远程桌面软件了。限制免费次数和免费时长，黑箱限制你根本不知道你还剩多少次数和时长，听天由命，基本上月底就甭想用了（我说的是谁大家心里都有数）。还有就是你无法知道他们是否真的安全，真的会守护你的个人隐私。毕竟屏幕画面、键鼠操作、剪贴板同步，这些可都是实打实的隐私数据。</p><p>RustDesk实际上是解决上述问题的理想方案——它兼顾了部署的便利性（提供便携客户端）、连接的流畅性（支持自建中继）以及数据的安全性。</p><p>闲话少叙，直接进入搭建实操。在服务器的选择上，建议优先考虑<strong>物理距离较近</strong>的节点以降低延迟，带宽推荐<strong>5Mbps</strong>起步，有条件上三网BGP线路效果最佳。</p><p>顺便提一句：如果双方网络环境好（能打通P2P直连），其实是不走服务器流量的；只有P2P失败走中继的时候，服务器带宽才是瓶颈。</p><p>下面分为两部分，第一部分是官方服务端，第二部分是开源服务端</p><h2 id="">官方服务端</h2><h3 id="">服务端搭建</h3><h4 id="">开放端口</h4><p>在安装之前要放通以下端口</p><ul><li><code>21115</code> (TCP)</li><li><code>21116</code> (TCP&amp;UDP)</li><li><code>21117</code> (TCP)</li><li><code>21118</code> (TCP)</li><li><code>21119</code> (TCP)</li></ul><p><code>21118/tcp</code> 和 <code>21119/tcp</code> 为Web客户端端口，如果不需要，也可以不开放</p><h4 id="docker">Docker安装</h4><p>选一个合适的地方放置，我这边就拿 /opt/rustdesk 打比方</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">mkdir -p /opt/rustdesk &amp;&amp; cd /opt/rustdesk
nano docker-compose.yml
</code></pre>
<p>然后填入</p><pre class="language-yml lang-yml"><code class="language-yml lang-yml">services:
  hbbs:
    container_name: rustdesk-hbbs
    image: rustdesk/rustdesk-server:latest
    command: hbbs
    volumes:
      - ./data:/root
    network_mode: &quot;host&quot;
    depends_on:
      - hbbr
    restart: unless-stopped

  hbbr:
    container_name: rustdesk-hbbr
    image: rustdesk/rustdesk-server:latest
    command: hbbr
    volumes:
      - ./data:/root
    network_mode: &quot;host&quot;
    restart: unless-stopped
</code></pre>
<p>最后运行并查看 <strong>Key 密钥</strong> 就算是搭建完成了</p><pre class=""><code class="">docker compose up -d
docker logs rustdesk-hbbs
</code></pre>
<p>查看容器日志，你会看到一串长<strong>密钥</strong>，请将其复制备用，这是后续配置客户端时的<strong>必填项</strong>。</p><h4 id="">客户端配置</h4><p>下载客户端 <a href="https://github.com/rustdesk/rustdesk/releases/">GitHub</a> (下载速度慢可以使用本站提供的网盘镜像: <a href="https://www.123865.com/s/gAEZVv-yrteh">123Pan</a>）</p><p>前往 <strong>设置</strong> &gt; <strong>网络</strong> &gt; <strong>ID/中继服务器</strong> 菜单。 在弹出的窗口中，只需填写 <strong>ID 服务器 (你的IP/域名)</strong> 与 <strong>Key (密钥)</strong> 这两栏即可。</p><p><img src="https://img.hoshiroko.com/archive/d97476212552e7bc.png" height="811" width="1155"/></p><p>这时候多配置几个设备，之间的互通就完全走中转服务器了，如果NAT类型宽松还可以P2P连接</p><h2 id="">开源服务端</h2><p>在自建过程中，咱们已经发现免费的官方服务端缺失了“账号系统”这一核心功能，意味着没有地址簿管理，多设备管理变得困难。</p><p>为了解决这个痛点，社区涌现了许多优秀的第三方开源服务端。</p><p>我发现了 <a href="https://github.com/lejianwen/rustdesk-server">lejianwen/rustdesk-server</a> 这个项目。该项目通过兼容 RustDesk 通信协议，补全了Web管理面板和账号系统功能。</p><p>对于想拥有完整自建体验，但预算有限的个人用户来说，这是一个绝佳的开源替代方案。</p><p>::: warning
本教程仅供<strong>个人技术研究</strong>使用。如果您是企业用户或需要稳定的商业支持，强烈建议购买RustDesk官方Pro版本，以获得更完善的功能保障和官方技术支持
:::</p><h3 id="">服务端搭建</h3><h4 id="">开放端口</h4><p>在安装之前要放通以下端口</p><ul><li><code>21114</code> (TCP)</li><li><code>21115</code> (TCP)</li><li><code>21116</code> (TCP&amp;UDP)</li><li><code>21117</code> (TCP)</li><li><code>21118</code> (TCP)</li><li><code>21119</code> (TCP)</li></ul><p><code>21118/tcp</code> 和 <code>21119/tcp</code> 为Web客户端端口，如果不需要，也可以不开放</p><h4 id="docker">Docker安装</h4><p>选一个合适的地方放置，我这边就拿 /opt/rustdesk 打比方</p><pre class="language-shell lang-shell"><code class="language-shell lang-shell">mkdir -p /opt/rustdesk &amp;&amp; cd /opt/rustdesk
nano docker-compose.yml
</code></pre>
<p>然后填入</p><pre class="language-yml lang-yml"><code class="language-yml lang-yml"> networks:
   rustdesk-net:
     external: false
 services:
   rustdesk:
     ports:
       - 21114:21114
       - 21115:21115
       - 21116:21116
       - 21116:21116/udp
       - 21117:21117
       - 21118:21118
       - 21119:21119
     image: lejianwen/rustdesk-server-s6:latest
     environment:
       - RELAY=&lt;relay_server[:port]&gt;
       - ENCRYPTED_ONLY=1
       - MUST_LOGIN=N
       - TZ=Asia/Shanghai
       - RUSTDESK_API_RUSTDESK_ID_SERVER=&lt;id_server[:21116]&gt;
       - RUSTDESK_API_RUSTDESK_RELAY_SERVER=&lt;relay_server[:21117]&gt;
       - RUSTDESK_API_RUSTDESK_API_SERVER=http://&lt;api_server[:21114]&gt;
       - RUSTDESK_API_KEY_FILE=/data/id_ed25519.pub
       - RUSTDESK_API_JWT_KEY=xxxxxx # Key密钥 可以自定义
     volumes:
       - ./data/server:/data
       - ./data/api:/app/data
     networks:
       - rustdesk-net
     restart: unless-stopped
</code></pre>
<p>最后运行并查看 <strong>Key 密钥</strong>  和 <strong>Web控制台admin初始密码</strong> 就算是完成了</p><pre class=""><code class="">docker compose up -d
docker logs rustdesk-rustdesk-1
</code></pre>
<p>查看容器日志，你会看到一串长<strong>密钥</strong> 以及 <strong>Web控制台admin初始密码</strong> ，请将其复制备用，这是后续配置客户端和Web控制台时的<strong>必填项</strong>。</p><h4 id="">客户端配置</h4><p>下载客户端 <a href="https://github.com/rustdesk/rustdesk/releases/">GitHub</a> (下载速度慢可以使用本站提供的网盘镜像: <a href="https://www.123865.com/s/gAEZVv-yrteh">123Pan</a>）</p><p>前往 <strong>设置</strong> &gt; <strong>网络</strong> &gt; <strong>ID/中继服务器</strong> 菜单。 在弹出的窗口中，只需填写 <strong>ID 服务器 (你的IP/域名)</strong> 与 <strong>Key (密钥)</strong> 这两栏即可。</p><p><img src="https://img.hoshiroko.com/archive/d97476212552e7bc.png" height="811" width="1155"/></p><p>这时候多配置几个设备，之间的互通就完全走中转服务器了，如果NAT类型宽松还可以P2P连接</p><p><strong>默认配置下，必须登录才能发起远程连接！</strong> 请前往 <strong>设置</strong> &gt; <strong>账户</strong>，使用默认用户名 <code>admin</code> 和刚才在 docker logs 里看到的初始密码进行登录。</p><p><img src="https://img.hoshiroko.com/archive/e917b51548ef9a59.png" height="811" width="1155"/></p>
<h4 id="">管理端配置</h4><p>浏览器访问 <code>http://{服务器IP/域名}:21114</code> 进入 Web 管理面板，默认账户为 <code>admin</code> ，密码即为刚才在 Docker 日志中获取的初始密码。</p><p>这里面可以配置的门道很多，自己研究研究，就不挨个深入细说了（</p><p>可玩性还是很丰富的，从<strong>设备</strong>与<strong>标签管理</strong>，到<strong>用户</strong>、<strong>群组</strong>和<strong>权限</strong>，甚至还支持<strong>OAuth第三方登录</strong></p><h2 id="">尾巴</h2><p>这里有一个很少人知道的一个小诀窍，平时用便携版最烦的就是每次都要重新填ID服务器和Key。其实你完全可以通过重命名文件名来<strong>&quot;固化&quot;</strong>配置</p><pre class=""><code class="">rustdesk-host={服务器IP/域名},key={Key}.exe
</code></pre>
<p>改成这个名字，双击打开就会默认连接自建节点。不管带到哪台电脑上，都是点开即连，再也不会连到缓慢的官方服务器了。</p></div><p style="text-align:right"><a href="https://hoshiroko.com/posts/course/rustdesk#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://hoshiroko.com/posts/course/rustdesk</link><guid isPermaLink="true">https://hoshiroko.com/posts/course/rustdesk</guid><dc:creator><![CDATA[薄荷の尾巴]]></dc:creator><pubDate>Sun, 18 Jan 2026 18:53:52 GMT</pubDate></item></channel></rss>