<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>rwv's Blog</title><link>https://blog.rwv.dev/en/</link><description>Recent content on rwv's Blog</description><generator>Hugo -- 0.145.0</generator><language>en</language><lastBuildDate>Tue, 18 Mar 2025 10:07:03 +0800</lastBuildDate><atom:link href="https://blog.rwv.dev/en/index.xml" rel="self" type="application/rss+xml"/><item><title>Linux Server Initialization Checklist</title><link>https://blog.rwv.dev/en/posts/linux-server-initialization-checklist/</link><pubDate>Tue, 18 Mar 2025 10:07:03 +0800</pubDate><guid>https://blog.rwv.dev/en/posts/linux-server-initialization-checklist/</guid><description>This memo documents various initialization operations performed on a Linux server, primarily to rapidly configure the server for subsequent development and maintenance. Dotbot could also manage these configurations, but this serves as a personal record.</description><content:encoded><![CDATA[<h2 id="apt-configuration">APT Configuration</h2>
<p>Change sources to HTTPS, upgrade the system, and install commonly used tools:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sed -i <span style="color:#e6db74">&#39;s/http:/https:/g&#39;</span> /etc/apt/sources.list
</span></span><span style="display:flex;"><span>apt update <span style="color:#f92672">&amp;&amp;</span> apt upgrade -y
</span></span><span style="display:flex;"><span>apt install -y curl wget git screen htop zsh sudo rsync nano nload
</span></span></code></pre></div><h2 id="configure-ssh">Configure SSH</h2>
<p>Set up SSH key-based login:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>mkdir -p ~/.ssh
</span></span><span style="display:flex;"><span>nano ~/.ssh/authorized_keys
</span></span></code></pre></div><p>Disable password login and enforce SSH key authentication:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sed -i <span style="color:#e6db74">&#39;s/#PasswordAuthentication yes/PasswordAuthentication no/&#39;</span> /etc/ssh/sshd_config
</span></span><span style="display:flex;"><span>systemctl restart sshd
</span></span></code></pre></div><h2 id="install-oh-my-zsh">Install oh-my-zsh</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sh -c <span style="color:#e6db74">&#34;</span><span style="color:#66d9ef">$(</span>curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh<span style="color:#66d9ef">)</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>nano ~/.zshrc
</span></span><span style="display:flex;"><span>source ~/.zshrc
</span></span></code></pre></div><h2 id="install-docker">Install Docker</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -fsSL https://get.docker.com | sh
</span></span></code></pre></div><h2 id="configure-automatic-updates">Configure Automatic Updates</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>apt-get install -y unattended-upgrades apt-listchanges
</span></span><span style="display:flex;"><span>dpkg-reconfigure unattended-upgrades
</span></span></code></pre></div><h2 id="enable-zram">Enable ZRAM</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>apt install -y zram-tools
</span></span><span style="display:flex;"><span>echo -e <span style="color:#e6db74">&#34;ALGO=zstd\nPERCENT=60&#34;</span> | tee -a /etc/default/zramswap
</span></span><span style="display:flex;"><span>service zramswap reload
</span></span></code></pre></div><h2 id="enable-bbr-network-optimization">Enable BBR Network Optimization</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Check if BBR is enabled</span>
</span></span><span style="display:flex;"><span>sysctl net.ipv4.tcp_congestion_control
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;net.core.default_qdisc=fq&#34;</span> &gt;&gt; /etc/sysctl.conf
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;net.ipv4.tcp_congestion_control=bbr&#34;</span> &gt;&gt; /etc/sysctl.conf
</span></span><span style="display:flex;"><span>sysctl -p
</span></span></code></pre></div><h2 id="configure-time-synchronization-chrony">Configure Time Synchronization (Chrony)</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>apt install -y chrony
</span></span><span style="display:flex;"><span>nano /etc/chrony/sources.d/corps.sources
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Add the following time servers:</span>
</span></span><span style="display:flex;"><span>pool time.apple.com iburst
</span></span><span style="display:flex;"><span>pool time.google.com iburst
</span></span><span style="display:flex;"><span>pool time.cloudflare.com iburst nts
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>chronyc reload sources
</span></span></code></pre></div><h2 id="configure-dns-service-systemd-resolved">Configure DNS Service (systemd-resolved)</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>apt install -y systemd-resolved
</span></span><span style="display:flex;"><span>systemctl enable --now systemd-resolved
</span></span><span style="display:flex;"><span>nano /etc/systemd/resolved.conf
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># TODO: Use sed to configure Cloudflare DNS and fallback DNS</span>
</span></span><span style="display:flex;"><span>DNS<span style="color:#f92672">=</span>1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com
</span></span><span style="display:flex;"><span>FallbackDNS<span style="color:#f92672">=</span>8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google 9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
</span></span><span style="display:flex;"><span>DNSOverTLS<span style="color:#f92672">=</span>yes
</span></span><span style="display:flex;"><span>MulticastDNS<span style="color:#f92672">=</span>no
</span></span><span style="display:flex;"><span>LLMNR<span style="color:#f92672">=</span>no
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>systemctl restart systemd-resolved
</span></span></code></pre></div><p>After completing these steps, the server is ready for use.</p>
]]></content:encoded></item><item><title>Add Giscus Multilingual Support in Hugo PaperMod</title><link>https://blog.rwv.dev/en/posts/add-giscus-multilingual-support-in-hugo-papermod/</link><pubDate>Wed, 22 Jan 2025 13:18:04 +0800</pubDate><guid>https://blog.rwv.dev/en/posts/add-giscus-multilingual-support-in-hugo-papermod/</guid><description>&lt;p>Giscus actually supports multiple languages, as you can see in &lt;a href="https://github.com/giscus/giscus/tree/main/locales">giscus/giscus/locales&lt;/a>. However, it doesn&amp;rsquo;t automatically detect the language, so manual configuration is needed. Hugo PaperMod doesn&amp;rsquo;t have a simple way to set different comment components for different languages, so we need to configure it manually.&lt;/p>
&lt;h2 id="configure-giscus">Configure Giscus&lt;/h2>
&lt;p>First, create a comment component at &lt;a href="https://giscus.app/">giscus.app&lt;/a>, which looks like this:&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-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">script&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">src&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;https://giscus.app/client.js&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-repo&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;[ENTER REPO HERE]&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-repo-id&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;[ENTER REPO ID HERE]&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-category&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;[ENTER CATEGORY NAME HERE]&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-category-id&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;[ENTER CATEGORY ID HERE]&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-mapping&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;pathname&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-strict&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-reactions-enabled&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-emit-metadata&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-input-position&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;bottom&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-theme&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;preferred_color_scheme&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data-lang&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;en&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">crossorigin&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;anonymous&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">async&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt;&amp;lt;/&lt;span style="color:#f92672">script&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Notice the &lt;code>data-lang&lt;/code> attribute - this is what we use to set the language.&lt;/p></description><content:encoded><![CDATA[<p>Giscus actually supports multiple languages, as you can see in <a href="https://github.com/giscus/giscus/tree/main/locales">giscus/giscus/locales</a>. However, it doesn&rsquo;t automatically detect the language, so manual configuration is needed. Hugo PaperMod doesn&rsquo;t have a simple way to set different comment components for different languages, so we need to configure it manually.</p>
<h2 id="configure-giscus">Configure Giscus</h2>
<p>First, create a comment component at <a href="https://giscus.app/">giscus.app</a>, which looks like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#f92672">script</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://giscus.app/client.js&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-repo</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;[ENTER REPO HERE]&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-repo-id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;[ENTER REPO ID HERE]&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-category</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;[ENTER CATEGORY NAME HERE]&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-category-id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;[ENTER CATEGORY ID HERE]&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-mapping</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;pathname&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-strict</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;0&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-reactions-enabled</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;1&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-emit-metadata</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;0&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-input-position</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;bottom&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-theme</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;preferred_color_scheme&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-lang</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;en&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">crossorigin</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;anonymous&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">async</span>
</span></span><span style="display:flex;"><span>&gt;&lt;/<span style="color:#f92672">script</span>&gt;
</span></span></code></pre></div><p>Notice the <code>data-lang</code> attribute - this is what we use to set the language.</p>
<h2 id="configure-hugo-papermod-template-html">Configure Hugo PaperMod Template HTML</h2>
<p>First, set PaperMod&rsquo;s <code>comments</code> to <code>true</code> so that the comment component will be displayed in every article.</p>
<p><a href="https://github.com/adityatelange/hugo-PaperMod/wiki/Features#comments">PaperMod Documentation - Comments</a></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">params</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">comments</span>: <span style="color:#66d9ef">true</span>
</span></span></code></pre></div><p>Then create <code>layouts/partials/comments.html</code> with the following content:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>{{ $giscusLang := &#34;en&#34; }} {{ if eq site.Language.Lang &#34;zh&#34; }} {{ $giscusLang =
</span></span><span style="display:flex;"><span>&#34;zh-CN&#34; }} {{ else if eq site.Language.Lang &#34;zh-tw&#34; }} {{ $giscusLang = &#34;zh-TW&#34;
</span></span><span style="display:flex;"><span>}} {{ else if eq site.Language.Lang &#34;zh-hk&#34; }} {{ $giscusLang = &#34;zh-HK&#34; }} {{
</span></span><span style="display:flex;"><span>else if eq site.Language.Lang &#34;ar&#34; }} {{ $giscusLang = &#34;ar&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;be&#34; }} {{ $giscusLang = &#34;be&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;bg&#34; }} {{ $giscusLang = &#34;bg&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;ca&#34; }} {{ $giscusLang = &#34;ca&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;cs&#34; }} {{ $giscusLang = &#34;cs&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;da&#34; }} {{ $giscusLang = &#34;da&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;de&#34; }} {{ $giscusLang = &#34;de&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;el&#34; }} {{ $giscusLang = &#34;gr&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;eo&#34; }} {{ $giscusLang = &#34;eo&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;es&#34; }} {{ $giscusLang = &#34;es&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;eu&#34; }} {{ $giscusLang = &#34;eu&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;fa&#34; }} {{ $giscusLang = &#34;fa&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;fr&#34; }} {{ $giscusLang = &#34;fr&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;he&#34; }} {{ $giscusLang = &#34;he&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;hu&#34; }} {{ $giscusLang = &#34;hu&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;id&#34; }} {{ $giscusLang = &#34;id&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;it&#34; }} {{ $giscusLang = &#34;it&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;ja&#34; }} {{ $giscusLang = &#34;ja&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;km&#34; }} {{ $giscusLang = &#34;kh&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;ko&#34; }} {{ $giscusLang = &#34;ko&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;nl&#34; }} {{ $giscusLang = &#34;nl&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;pl&#34; }} {{ $giscusLang = &#34;pl&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;pt&#34; }} {{ $giscusLang = &#34;pt&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;ro&#34; }} {{ $giscusLang = &#34;ro&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;ru&#34; }} {{ $giscusLang = &#34;ru&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;th&#34; }} {{ $giscusLang = &#34;th&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;tr&#34; }} {{ $giscusLang = &#34;tr&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;uk&#34; }} {{ $giscusLang = &#34;uk&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;uz&#34; }} {{ $giscusLang = &#34;uz&#34; }} {{ else if eq
</span></span><span style="display:flex;"><span>site.Language.Lang &#34;vi&#34; }} {{ $giscusLang = &#34;vi&#34; }} {{ end }}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">script</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://giscus.app/client.js&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-repo</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;[ENTER REPO HERE]&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-repo-id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;[ENTER REPO ID HERE]&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-category</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;[ENTER CATEGORY NAME HERE]&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-category-id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;[ENTER CATEGORY ID HERE]&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-mapping</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;pathname&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-strict</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;0&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-reactions-enabled</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;1&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-emit-metadata</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;0&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-input-position</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;bottom&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-theme</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;preferred_color_scheme&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-lang</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ $giscusLang }}&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">crossorigin</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;anonymous&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">async</span>
</span></span><span style="display:flex;"><span>&gt;&lt;/<span style="color:#f92672">script</span>&gt;
</span></span></code></pre></div><p>This way, the comment component will be displayed in every article and will automatically set its language based on the article&rsquo;s language.</p>
<p>Note: Prettier will automatically format the code, which is why it might look a bit messy.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://github.com/giscus/giscus/tree/main/locales">giscus/giscus/locales</a></li>
<li><a href="https://github.com/adityatelange/hugo-PaperMod/wiki/Features#comments">PaperMod Documentation - Comments</a></li>
</ul>
]]></content:encoded></item><item><title>Migrating Blog System from Hexo to Hugo</title><link>https://blog.rwv.dev/en/posts/migrate-blog-system-from-hexo-to-hugo/</link><pubDate>Wed, 22 Jan 2025 09:22:52 +0800</pubDate><guid>https://blog.rwv.dev/en/posts/migrate-blog-system-from-hexo-to-hugo/</guid><description>&lt;p>After four years, I&amp;rsquo;m ready to start blogging again. However, I felt the need to tinker with the system as &lt;a href="https://hexo.io/">Hexo&lt;/a> wasn&amp;rsquo;t quite meeting my needs, so I decided to migrate to &lt;a href="https://gohugo.io/">Hugo&lt;/a>. Another important reason was that &lt;a href="https://github.com/litten/hexo-theme-yilia">yilia&lt;/a> hasn&amp;rsquo;t been updated for a very long time and doesn&amp;rsquo;t even support dark mode.&lt;/p>
&lt;h2 id="migration-motivation">Migration Motivation&lt;/h2>
&lt;p>Here are the main advantages of migrating from Hexo to Hugo, along with avoiding some existing technical debt (such as messy git logs and lack of open source):&lt;/p></description><content:encoded><![CDATA[<p>After four years, I&rsquo;m ready to start blogging again. However, I felt the need to tinker with the system as <a href="https://hexo.io/">Hexo</a> wasn&rsquo;t quite meeting my needs, so I decided to migrate to <a href="https://gohugo.io/">Hugo</a>. Another important reason was that <a href="https://github.com/litten/hexo-theme-yilia">yilia</a> hasn&rsquo;t been updated for a very long time and doesn&rsquo;t even support dark mode.</p>
<h2 id="migration-motivation">Migration Motivation</h2>
<p>Here are the main advantages of migrating from Hexo to Hugo, along with avoiding some existing technical debt (such as messy git logs and lack of open source):</p>
<ul>
<li><strong>Faster Build Speed</strong>: Hugo is written in Go, making it faster than Node.js-based solutions</li>
<li><strong>Simpler Deployment</strong>: Single binary file, no complex dependency management needed</li>
<li><strong>Powerful Content Management</strong>: Page Bundles feature makes article and resource management clearer</li>
<li><strong>Active Community</strong>: Rich ecosystem of themes and plugins</li>
<li><strong>Internationalization Support</strong>: Hugo&rsquo;s built-in multilingual support makes internationalization easy</li>
<li><strong>Better Theme Options</strong>: The <a href="https://github.com/adityatelange/hugo-PaperMod">PaperMod</a> theme suits my aesthetic better than <a href="https://github.com/litten/hexo-theme-yilia">yilia</a> and supports dark mode</li>
</ul>
<h2 id="migration-steps">Migration Steps</h2>
<h3 id="creating-a-hugo-site">Creating a Hugo Site</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install Hugo (macOS)</span>
</span></span><span style="display:flex;"><span>brew install hugo
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Create site</span>
</span></span><span style="display:flex;"><span>hugo new site my-blog
</span></span><span style="display:flex;"><span>cd my-blog
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install PaperMod theme</span>
</span></span><span style="display:flex;"><span>git init
</span></span><span style="display:flex;"><span>git submodule add https://github.com/adityatelange/hugo-PaperMod themes/PaperMod
</span></span></code></pre></div><p>Modify the basic configuration file <code>hugo.toml</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span><span style="color:#a6e22e">baseURL</span> = <span style="color:#e6db74">&#34;https://blog.rwv.dev/&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">title</span> = <span style="color:#e6db74">&#34;My Blog&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">theme</span> = <span style="color:#e6db74">&#34;PaperMod&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">languageCode</span> = <span style="color:#e6db74">&#34;en&#34;</span>
</span></span></code></pre></div><p>You can reference my configuration here: <a href="https://github.com/rwv/blog/tree/ace7392bbad25d48d124b779dfe084c4d60ff8f8/config/_default">config/_default</a></p>
<h3 id="content-migration">Content Migration</h3>
<p>Converting article formats:</p>
<ul>
<li>Move articles from <code>source/_posts</code> to <code>content/posts</code></li>
<li>Convert front matter format:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#75715e"># Hexo format</span>
</span></span><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span><span style="color:#f92672">title</span>: <span style="color:#ae81ff">Example Post</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">date</span>: <span style="color:#e6db74">2024-01-22 14:30:00</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">tags</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#ae81ff">hugo</span>
</span></span><span style="display:flex;"><span>  - <span style="color:#ae81ff">blog</span>
</span></span><span style="display:flex;"><span>---
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#75715e"># Hugo format</span>
</span></span><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span><span style="color:#f92672">title</span>: <span style="color:#ae81ff">Example Post</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">date</span>: <span style="color:#e6db74">2024-01-22T14:30:00</span><span style="color:#ae81ff">+08</span>:<span style="color:#ae81ff">00</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">tags</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#ae81ff">hugo</span>
</span></span><span style="display:flex;"><span>  - <span style="color:#ae81ff">blog</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">aliases</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#ae81ff">/2024/01/22/example-post/</span>
</span></span><span style="display:flex;"><span>---
</span></span></code></pre></div><p>The original URL path in Hexo was <code>permalink: :year/:month/:day/:title/</code>. In Hugo, we need to set aliases to prevent old links from breaking.</p>
<h3 id="configuring-comments-system">Configuring Comments System</h3>
<p>I also replaced the original Disqus commenting system with <a href="https://giscus.app/">giscus</a>. Here&rsquo;s the specific configuration:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#75715e"># config/_default/params.yml</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">comments</span>: <span style="color:#66d9ef">true</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span><span style="color:#75715e">&lt;!-- layouts/partials/comments.html --&gt;</span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">script</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://giscus.app/client.js&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-repo</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;your-github-username/your-repo-name&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-repo-id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;xxxx&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-category</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Announcements&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-category-id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;xxxx&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-mapping</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;pathname&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-strict</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;0&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-reactions-enabled</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;1&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-emit-metadata</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;0&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-input-position</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;bottom&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-theme</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;preferred_color_scheme&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">data-lang</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;en&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">crossorigin</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;anonymous&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">async</span>
</span></span><span style="display:flex;"><span>&gt;&lt;/<span style="color:#f92672">script</span>&gt;
</span></span></code></pre></div><h3 id="configuring-github-actions">Configuring GitHub Actions</h3>
<p>I&rsquo;m using GitHub Actions to automatically deploy the blog to both Cloudflare Pages and GitHub Pages for better disaster recovery (although such scenarios are unlikely). In the future, I might deploy to more platforms, possibly even IPFS, though I&rsquo;m skeptical about IPFS&rsquo;s stability.</p>
<p>You can find the specific code in <a href="https://github.com/rwv/blog/blob/92193c6f296febeaa402d69097126b30d61cff7d/.github/workflows/ci.yml">.github/workflows/ci.yml</a></p>
<p>Why not use Cloudflare Pages&rsquo; own build system? Because Cloudflare Pages has concurrent build limitations, and their Hugo version is too old to compile successfully. GitHub Actions&rsquo; build system is more reliable.</p>
<h2 id="open-source">Open Source</h2>
<p>Taking advantage of this migration, I&rsquo;ve made the blog open source. The project is available at <a href="https://github.com/rwv/blog">rwv/blog</a>, and you can find the &lsquo;Edit&rsquo; button at the top of each article to go directly to the source code. Here&rsquo;s the specific configuration:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">editPost</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">URL</span>: <span style="color:#e6db74">&#34;https://github.com/rwv/blog/blob/main/content&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">appendFilePath</span>: <span style="color:#66d9ef">true</span> <span style="color:#75715e"># to append file path to Edit link</span>
</span></span></code></pre></div><p>Code: <a href="https://github.com/rwv/blog/blob/ace7392bbad25d48d124b779dfe084c4d60ff8f8/config/_default/params.yml#L21-L23">config/_default/params.yml#L21-L23</a></p>
<h2 id="conclusion">Conclusion</h2>
<p>Hugo provides a more efficient blogging experience. While migration requires some effort, in the long run, it will enable me to write more blog posts. So the migration was worth it.</p>
]]></content:encoded></item><item><title>Mounting Network UNC Paths to Drive Letters in Windows CMD</title><link>https://blog.rwv.dev/en/posts/mounting-network-unc-paths-to-drive-letters-in-windows-cmd/</link><pubDate>Fri, 26 Apr 2019 13:40:17 +0800</pubDate><guid>https://blog.rwv.dev/en/posts/mounting-network-unc-paths-to-drive-letters-in-windows-cmd/</guid><description>&lt;p>There are two methods to mount a network UNC (Universal Naming Convention) path to a local drive letter in Windows Command Prompt. While &lt;code>pushd&lt;/code> is commonly used, it has a significant limitation that may affect certain scenarios.&lt;/p></description><content:encoded><![CDATA[<p>There are two methods to mount a network UNC (Universal Naming Convention) path to a local drive letter in Windows Command Prompt. While <code>pushd</code> is commonly used, it has a significant limitation that may affect certain scenarios.</p>
<h2 id="common-method-using-pushd">Common Method: Using <code>pushd</code></h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-batch" data-lang="batch"><span style="display:flex;"><span><span style="color:#66d9ef">set</span> unc_path=\\Host\a\b\c
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">pushd</span> %unc_path%
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: Your commands here</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">popd</span>
</span></span></code></pre></div><p>When using <code>pushd</code>, Windows automatically mounts <code>\\Host\a</code> to the first available drive letter (for example, <code>Y:</code>), then changes the working directory to <code>Y:\b\c</code>. However, this approach has a critical limitation: if the user has permissions for <code>\\Host\a\b\c</code> but lacks access to <code>\\Host\a</code>, all commands in this directory will fail with an <code>Access is denied</code> error.</p>
<h2 id="alternative-method-using-net-use">Alternative Method: Using <code>net use</code></h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-batch" data-lang="batch"><span style="display:flex;"><span><span style="color:#66d9ef">set</span> unc_path=\\Host\a\b\c
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: Mount the UNC path to an available drive letter</span>
</span></span><span style="display:flex;"><span>net use * %unc_path%
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: Extract the assigned drive letter</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> <span style="color:#66d9ef">/f</span> <span style="color:#e6db74">&#34;tokens=2,3&#34;</span> <span style="color:#ae81ff">%%</span>i <span style="color:#66d9ef">in</span> (<span style="color:#e6db74">&#39;net use&#39;</span>) <span style="color:#66d9ef">do</span> <span style="color:#66d9ef">if</span> &#39;<span style="color:#ae81ff">%%</span>j<span style="color:#f92672">==</span>&#39;%unc_path% <span style="color:#66d9ef">set</span> drive_letter=<span style="color:#ae81ff">%%</span>i
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: Change to the mounted drive</span>
</span></span><span style="display:flex;"><span>%drive_letter%
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: Your commands here</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: Clean up: unmount the drive</span>
</span></span><span style="display:flex;"><span>net use %drive_letter% /delete /y
</span></span></code></pre></div><p>This alternative approach first assigns an available drive letter to the path using <code>net use</code>, then retrieves the assigned drive letter. The key advantage over <code>pushd</code> is that <code>net use</code> mounts the specific subdirectory rather than the root directory, thereby avoiding the permission issues mentioned above.</p>
<p>Note: When executing these commands directly in the command prompt (rather than in a batch file), replace <code>%%i</code> and <code>%%j</code> with <code>%i</code> and <code>%j</code> respectively.</p>]]></content:encoded></item><item><title>Create a ZeroTier Moon Node with Docker in Two Commands</title><link>https://blog.rwv.dev/en/posts/create-a-zerotier-moon-node-with-docker-in-two-commands/</link><pubDate>Sun, 13 May 2018 19:46:00 +0800</pubDate><guid>https://blog.rwv.dev/en/posts/create-a-zerotier-moon-node-with-docker-in-two-commands/</guid><description>&lt;p>While creating a ZeroTier moon node isn&amp;rsquo;t overly complex, it does involve several steps. To simplify this process, I&amp;rsquo;ve created a Docker image that lets you set up a moon node with just two commands.&lt;/p></description><content:encoded><![CDATA[<p>While creating a ZeroTier moon node isn&rsquo;t overly complex, it does involve several steps. To simplify this process, I&rsquo;ve created a Docker image that lets you set up a moon node with just two commands.</p>
<h2 id="basic-setup">Basic Setup</h2>
<p>First, create the ZeroTier moon node:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run --name zerotier-moon -d -p 9993:9993 -p 9993:9993/udp seedgou/zerotier-moon -4 1.2.3.4
</span></span></code></pre></div><p>(Replace <code>1.2.3.4</code> with your moon node&rsquo;s public IP address)</p>
<p>Then, retrieve your moon ID:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker logs zerotier-moon
</span></span></code></pre></div><p><strong>Note:</strong> Each new container generates a new moon ID. To preserve your moon ID after container restarts, use <code>docker start zerotier-moon</code> instead of creating a new container. For persistent moon ID storage across new container creations, see the <strong>Mounting Configuration Directory</strong> section below.</p>
<h2 id="advanced-usage">Advanced Usage</h2>
<h3 id="zerotier-management">ZeroTier Management</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker exec zerotier-moon /zerotier-cli
</span></span></code></pre></div><h3 id="mounting-configuration-directory">Mounting Configuration Directory</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run --name zerotier-moon -d -p 9993:9993 -p 9993:9993/udp -v ~/somewhere:/var/lib/zerotier-one seedgou/zerotier-moon -4 1.2.3.4
</span></span></code></pre></div><p>This command mounts a local directory (<code>~/somewhere</code>) to the container&rsquo;s <code>/var/lib/zerotier-one</code> directory, enabling configuration persistence. Without this mount, each new container will generate a fresh moon ID.</p>
<h3 id="ipv6-support">IPv6 Support</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run --name zerotier-moon -d -p 9993:9993 -p 9993:9993/udp seedgou/zerotier-moon -4 1.2.3.4 -6 2001:abcd:abcd::1
</span></span></code></pre></div><p>Replace both <code>1.2.3.4</code> and <code>2001:abcd:abcd::1</code> with your moon node&rsquo;s IPv4 and IPv6 addresses respectively. In IPv6-only environments, you can omit the <code>-4</code> option.</p>
<h3 id="custom-port">Custom Port</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run --name zerotier-moon -d -p 9994:9993 -p 9994:9993/udp seedgou/zerotier-moon -4 1.2.3.4 -p <span style="color:#ae81ff">9994</span>
</span></span></code></pre></div><p>Replace <code>9994</code> with your desired port number.</p>
<h2 id="source-code">Source Code</h2>
<p><a href="https://github.com/rwv/docker-zerotier-moon">https://github.com/rwv/docker-zerotier-moon</a></p>]]></content:encoded></item><item><title>Fixing Time Synchronization Issues Between Hackintosh and Windows</title><link>https://blog.rwv.dev/en/posts/fixing-time-synchronization-issues-between-hackintosh-and-windows/</link><pubDate>Sun, 04 Mar 2018 22:51:52 +0800</pubDate><guid>https://blog.rwv.dev/en/posts/fixing-time-synchronization-issues-between-hackintosh-and-windows/</guid><description>&lt;p>By default, macOS and Windows handle the system BIOS clock differently. macOS interprets the BIOS clock as UTC (Coordinated Universal Time), while Windows reads it as local time. For example, if the BIOS clock shows 00:00, Windows will display it as 00:00 local time. However, macOS will interpret this as 00:00 UTC and adjust it to show 08:00 for users in GMT+8 time zones (like Beijing time). This difference in interpretation causes the time to appear inconsistent between the two operating systems.&lt;/p></description><content:encoded><![CDATA[<p>By default, macOS and Windows handle the system BIOS clock differently. macOS interprets the BIOS clock as UTC (Coordinated Universal Time), while Windows reads it as local time. For example, if the BIOS clock shows 00:00, Windows will display it as 00:00 local time. However, macOS will interpret this as 00:00 UTC and adjust it to show 08:00 for users in GMT+8 time zones (like Beijing time). This difference in interpretation causes the time to appear inconsistent between the two operating systems.</p>
<h2 id="solutions">Solutions</h2>
<h3 id="method-1-using-registry-editor">Method 1: Using Registry Editor</h3>
<ol>
<li>Open Registry Editor by pressing <code>Win + R</code> and typing <code>Regedit</code></li>
<li>Navigate to: <code>HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation</code></li>
<li>Create a new DWORD (32-bit) Value named <code>RealTimeIsUniversal</code></li>
<li>Set its value to <code>1</code></li>
</ol>
<p><img alt="Adding RealTimeIsUniversal in Registry Editor" loading="lazy" src="/posts/%E9%BB%91%E8%8B%B9%E6%9E%9C%E5%92%8C-windows-%E6%97%B6%E9%97%B4%E4%B8%8D%E4%B8%80%E8%87%B4%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/Screenshot_1.png"></p>
<h3 id="method-2-using-command-prompt">Method 2: Using Command Prompt</h3>
<p>Run the following command in an Administrator Command Prompt:</p>
<pre tabindex="0"><code>Reg add HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation /v RealTimeIsUniversal /t REG_DWORD /d 1
</code></pre><p>This change will make Windows treat the BIOS clock as UTC time, matching macOS&rsquo;s behavior.</p>
<h2 id="reference">Reference</h2>
<p><a href="http://bbs.pcbeta.com/forum.php?mod=viewthread&amp;tid=1695542">MAC 系统同 WIN10 时间不一致的问题-远景论坛-微软极客社区</a></p>]]></content:encoded></item><item><title>Solution for autojump_chpwd:4: nice(5) failed: operation not permitted Error in WSL</title><link>https://blog.rwv.dev/en/posts/solution-for-autojump-chpwd-4-nice-5-failed-operation-not-permitted-error-in-wsl/</link><pubDate>Thu, 01 Feb 2018 01:26:41 +0800</pubDate><guid>https://blog.rwv.dev/en/posts/solution-for-autojump-chpwd-4-nice-5-failed-operation-not-permitted-error-in-wsl/</guid><description>&lt;p>When using autojump in Windows Subsystem for Linux (WSL), you might see this error message:&lt;/p>
&lt;pre tabindex="0">&lt;code>autojump_chpwd:4: nice(5) failed: operation not permitted
&lt;/code>&lt;/pre>&lt;p>While this error doesn&amp;rsquo;t affect autojump&amp;rsquo;s functionality, it can be annoying to see this message every time you use the command.&lt;/p></description><content:encoded><![CDATA[<p>When using autojump in Windows Subsystem for Linux (WSL), you might see this error message:</p>
<pre tabindex="0"><code>autojump_chpwd:4: nice(5) failed: operation not permitted
</code></pre><p>While this error doesn&rsquo;t affect autojump&rsquo;s functionality, it can be annoying to see this message every time you use the command.</p>
<h2 id="solution">Solution</h2>
<p>Add this line to your <code>~/.zshrc</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>unsetopt BG_NICE
</span></span></code></pre></div><h2 id="example-configuration">Example Configuration</h2>
<p>Here&rsquo;s a complete example of a <code>.zshrc</code> file configured for WSL with autojump. You can find this configuration <a href="https://gist.github.com/rwv/6ee9b987c37585199459ce961401c0a1">on GitHub Gist</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># If you come from bash you might have to change your $PATH.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># export PATH=$HOME/bin:/usr/local/bin:$PATH</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># To Fix the autojump_chpwd:4: nice(5) failed: operation not permitted error.</span>
</span></span><span style="display:flex;"><span>unsetopt BG_NICE
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Path to your oh-my-zsh installation.</span>
</span></span><span style="display:flex;"><span>  export ZSH<span style="color:#f92672">=</span>$HOME/.oh-my-zsh
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Set name of the theme to load. Optionally, if you set this to &#34;random&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># it&#39;ll load a random theme each time that oh-my-zsh is loaded.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes</span>
</span></span><span style="display:flex;"><span>ZSH_THEME<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;ys&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Set list of themes to load</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Setting this variable when ZSH_THEME=random</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># cause zsh load theme from this variable instead of</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># looking in ~/.oh-my-zsh/themes/</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># An empty array have no effect</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ZSH_THEME_RANDOM_CANDIDATES=( &#34;robbyrussell&#34; &#34;agnoster&#34; )</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line to use case-sensitive completion.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># CASE_SENSITIVE=&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line to use hyphen-insensitive completion. Case</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># sensitive completion must be off. _ and - will be interchangeable.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># HYPHEN_INSENSITIVE=&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line to disable bi-weekly auto-update checks.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># DISABLE_AUTO_UPDATE=&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line to change how often to auto-update (in days).</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># export UPDATE_ZSH_DAYS=13</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line to disable colors in ls.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># DISABLE_LS_COLORS=&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line to disable auto-setting terminal title.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># DISABLE_AUTO_TITLE=&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line to enable command auto-correction.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ENABLE_CORRECTION=&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line to display red dots whilst waiting for completion.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># COMPLETION_WAITING_DOTS=&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line if you want to disable marking untracked files</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># under VCS as dirty. This makes repository status check for large repositories</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># much, much faster.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># DISABLE_UNTRACKED_FILES_DIRTY=&#34;true&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Uncomment the following line if you want to change the command execution time</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># stamp shown in the history command output.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># The optional three formats: &#34;mm/dd/yyyy&#34;|&#34;dd.mm.yyyy&#34;|&#34;yyyy-mm-dd&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># HIST_STAMPS=&#34;mm/dd/yyyy&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Would you like to use another custom folder than $ZSH/custom?</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ZSH_CUSTOM=/path/to/new-custom-folder</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Example format: plugins=(rails git textmate ruby lighthouse)</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Add wisely, as too many plugins slow down shell startup.</span>
</span></span><span style="display:flex;"><span>plugins<span style="color:#f92672">=(</span>
</span></span><span style="display:flex;"><span>  git
</span></span><span style="display:flex;"><span>  autojump
</span></span><span style="display:flex;"><span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>source $ZSH/oh-my-zsh.sh
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># User configuration</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># export MANPATH=&#34;/usr/local/man:$MANPATH&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># You may need to manually set your language environment</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># export LANG=en_US.UTF-8</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Preferred editor for local and remote sessions</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># if [[ -n $SSH_CONNECTION ]]; then</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#   export EDITOR=&#39;vim&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># else</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#   export EDITOR=&#39;mvim&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># fi</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Compilation flags</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># export ARCHFLAGS=&#34;-arch x86_64&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ssh</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># export SSH_KEY_PATH=&#34;~/.ssh/rsa_id&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Set personal aliases, overriding those provided by oh-my-zsh libs,</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># plugins, and themes. Aliases can be placed here, though oh-my-zsh</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># users are encouraged to define aliases within the ZSH_CUSTOM folder.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># For a full list of active aliases, run `alias`.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Example aliases</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># alias zshconfig=&#34;mate ~/.zshrc&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># alias ohmyzsh=&#34;mate ~/.oh-my-zsh&#34;</span>
</span></span></code></pre></div><h2 id="reference">Reference</h2>
<p><a href="https://github.com/wting/autojump/issues/474">GitHub Issue #474: autojump_chpwd:4: nice(5) failed: operation not permitted</a></p>]]></content:encoded></item><item><title>Opening UTF-8 CSV Files with Microsoft Excel on macOS</title><link>https://blog.rwv.dev/en/posts/opening-utf8-csv-files-with-microsoft-excel-on-macos/</link><pubDate>Fri, 26 Jan 2018 01:25:40 +0800</pubDate><guid>https://blog.rwv.dev/en/posts/opening-utf8-csv-files-with-microsoft-excel-on-macos/</guid><description>&lt;p>Microsoft Excel on macOS doesn&amp;rsquo;t provide a direct way to set character encoding when opening files. This makes it challenging to properly open UTF-8 encoded CSV files. However, there&amp;rsquo;s a workaround using Excel&amp;rsquo;s &lt;code>Get External Data&lt;/code> feature that allows you to successfully open UTF-8 CSV files.&lt;/p></description><content:encoded><![CDATA[<p>Microsoft Excel on macOS doesn&rsquo;t provide a direct way to set character encoding when opening files. This makes it challenging to properly open UTF-8 encoded CSV files. However, there&rsquo;s a workaround using Excel&rsquo;s <code>Get External Data</code> feature that allows you to successfully open UTF-8 CSV files.</p>
<h2 id="steps">Steps</h2>
<ol>
<li>Create a new blank Excel workbook</li>
<li>Navigate to the <code>Data</code> tab and select <code>Get External Data &gt; Import Text File...</code></li>
</ol>
<p><img alt="import text file" loading="lazy" src="/posts/macos-%E4%B8%8B%E4%BD%BF%E7%94%A8-microsoft-excel-%E6%89%93%E5%BC%80-utf-8-csv-%E6%96%87%E4%BB%B6/Screenshot_1.png"></p>
<ol start="3">
<li>Locate and select your CSV file. In the import wizard, choose <code>Unicode (UTF-8)</code> as the file origin, then click Next.</li>
</ol>
<p><img alt="choose charset" loading="lazy" src="/posts/macos-%E4%B8%8B%E4%BD%BF%E7%94%A8-microsoft-excel-%E6%89%93%E5%BC%80-utf-8-csv-%E6%96%87%E4%BB%B6/Screenshot_2.png"></p>
<ol start="4">
<li>In the next screen, select your desired delimiter options, then click Finish.</li>
</ol>
<p><img alt="choose delimiter" loading="lazy" src="/posts/macos-%E4%B8%8B%E4%BD%BF%E7%94%A8-microsoft-excel-%E6%89%93%E5%BC%80-utf-8-csv-%E6%96%87%E4%BB%B6/Screenshot_3.png"></p>
<p>That&rsquo;s it! Your UTF-8 CSV file should now be properly imported with all characters displaying correctly.</p>]]></content:encoded></item></channel></rss>