<?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>Codeberg on Tony Bai</title><link>https://tonybai.com/tags/codeberg/</link><description>Recent content in Codeberg on Tony Bai</description><generator>Hugo</generator><language>zh-cn</language><copyright>2004-2026 Tony Bai. 版权所有.</copyright><lastBuildDate>Mon, 06 Jul 2026 06:00:00 +0800</lastBuildDate><atom:link href="https://tonybai.com/tags/codeberg/index.xml" rel="self" type="application/rss+xml"/><item><title>5 分钟上手 gvu：把 vanity import path 这件事，从“半天运维”变成一条命令</title><link>https://tonybai.com/2026/07/06/get-started-with-gvu-in-5-minutes/</link><pubDate>Mon, 06 Jul 2026 06:00:00 +0800</pubDate><guid>https://tonybai.com/2026/07/06/get-started-with-gvu-in-5-minutes/</guid><description>上一篇文章的结尾我留了个坑——“这篇不是产品说明书，后面会单独写如何上手的文章”。今天这篇就是还债：gvu 正式开放公测，这是一个专门解决 Go 私有 module vanity import path 分发和拉取问题的命令行工具。这篇文章带你 5 分钟走完从安装到跑通拉取第一个私有 module 的全过程。</description><content:encoded><![CDATA[<p><img alt="题图" loading="lazy" src="/images/wp-content/uploads/2026/get-started-with-gvu-in-5-minutes-1.png"></p>
<p><a href="https://tonybai.com/2026/07/06/get-started-with-gvu-in-5-minutes">本文永久链接</a> – <a href="https://tonybai.com/2026/07/06/get-started-with-gvu-in-5-minutes">https://tonybai.com/2026/07/06/get-started-with-gvu-in-5-minutes</a></p>
<p>大家好，我是Tony Bai。</p>
<p>上一篇《<a href="https://tonybai.com/2026/07/05/go-private-modules-lessons-learned">五年，三篇文章，一个我一直没真正解决的问题</a>》里，我记录了这五年折腾私有 Go module 拉取方案的几段经历，也提到今年白盒交付给客户时踩的新坑。文章结尾我说会把这个工具单独写篇上手文章——今天这篇就是它。</p>
<p><strong>gvu（GomodVanityUrls 的缩写）现在正式开放公测</strong>，官网在 <a href="https://gomodvanityurls.com">gomodvanityurls.com</a>。这篇文章不谈太多背景，直接上手，5 分钟带你走完从安装到拉取用上第一个私有 module 的完整流程。</p>
<p><img loading="lazy" src="/images/wp-content/uploads/2025/paid/the-ultimate-guide-to-go-module-qr.png"></p>
<h2 id="gvu-是什么">gvu 是什么</h2>
<p>一句话概括：<strong>gvu 是一个命令行工具，用来把 Go module 的 vanity import path（比如 <code>mycompany.com/go/common</code>）映射到你真实的代码仓库地址（GitHub / GitLab / Bitbucket / Codeberg / 自建仓库都支持），全程一行命令搞定，不需要你再手写 <code>govanityurls</code> 的 YAML 配置，也不需要自己维护 Nginx。</strong></p>
<p>如果你看过我五年前那几篇搭建私有 Go module 拉取方案的文章，就知道这背后原本要做的事：起一个 <code>govanityurls</code> 服务、写映射配置、配 Nginx 反代、（如果要自定义域名）自己签 TLS 证书。gvu 把这一整套操作压缩成了一行 <code>gvu add</code>。</p>
<h2 id="安装">安装</h2>
<h3 id="linux--macos">Linux / macOS</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -fsSL gomodvanityurls.com/install.sh | bash
</span></span></code></pre></div><h3 id="windows">Windows</h3>
<p>如果你用 Git Bash / MSYS2 / Cygwin/ WSL/ WSL2，直接执行和上面一样的命令即可，脚本会自动识别 Windows 环境并下载对应的 <code>.exe</code>。</p>
<p>如果你在Windows上使用 Scoop 的话，可以在Powershell命令行里执行下面：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-powershell" data-lang="powershell"><span style="display:flex;"><span>scoop bucket add gomodvanityurls https<span style="color:#960050;background-color:#1e0010">:</span>//github.com/gomodvanityurls/scoop-bucket
</span></span><span style="display:flex;"><span>scoop install gvu
</span></span></code></pre></div><p>装完之后，跑一下 <code>gvu --version</code> 确认安装成功。</p>
<h2 id="添加你的第一个-vanity-url">添加你的第一个 vanity URL</h2>
<p>最简单的方式是直接用 gvu 提供的默认域名 <code>gomod.io</code>，<strong>不需要注册、不需要配 Domain解析</strong>，一行命令（以你的私有仓库在github.com上为例）：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ gvu add gomod.io/private-module https://github.com/yourorg/private-module.git
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>✔ Route created successfully!
</span></span><span style="display:flex;"><span>═══════════════════════════════════════════════════════════
</span></span><span style="display:flex;"><span>┃ Route ID:     m_abc123
</span></span><span style="display:flex;"><span>┃ Vanity Path:  gomod.io/private-module
</span></span><span style="display:flex;"><span>┃ Target Repo:  https://github.com/yourorg/private-module.git
</span></span><span style="display:flex;"><span>┃ Quota:        <span style="color:#ae81ff">1</span> / <span style="color:#ae81ff">5</span> used
</span></span><span style="display:flex;"><span>═══════════════════════════════════════════════════════════
</span></span></code></pre></div><p>这条命令执行时，gvu 会自动帮你创建一个匿名账号（免签名、免邮箱），并且自动识别出这是个 GitHub 仓库。GitLab、Bitbucket、Codeberg 或者你自己内网的 GitLab 也都是同样的用法，把仓库地址换掉即可，gvu 会自动识别托管平台。</p>
<p>如果你的仓库需要用 SSH 方式拉取，也可以直接传 SSH 地址：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>gvu add gomod.io/private-module ssh://git@github.com:yourorg/private-module.git
</span></span></code></pre></div><h2 id="告诉-go-工具链去哪里解析这个路径">告诉 Go 工具链去哪里解析这个路径</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>export GOPRIVATE<span style="color:#f92672">=</span>gomod.io
</span></span></code></pre></div><p>建议把这行加到你的 <code>~/.bashrc</code> 或 <code>~/.zshrc</code> 里，一劳永逸。</p>
<h2 id="在代码里用起来">在代码里用起来</h2>
<p>在你的 <code>go.mod</code> 里，module path 要直接用 vanity path，而不是原始的 Git 托管地址：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#75715e">// go.mod —— 正确</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">module</span> <span style="color:#a6e22e">gomod</span>.<span style="color:#a6e22e">io</span><span style="color:#f92672">/</span><span style="color:#a6e22e">private</span><span style="color:#f92672">-</span><span style="color:#a6e22e">module</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// go.mod —— 错误，会直接去github上拉去私有仓库</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">module</span> <span style="color:#a6e22e">github</span>.<span style="color:#a6e22e">com</span><span style="color:#f92672">/</span><span style="color:#a6e22e">yourorg</span><span style="color:#f92672">/</span><span style="color:#a6e22e">private</span><span style="color:#f92672">-</span><span style="color:#a6e22e">module</span>
</span></span></code></pre></div><p>如果你的模块之前用的是 <code>github.com/...</code> 这样的 module path，迁移时记得把它改成 vanity path 再发布。</p>
<p>改好之后，同组织内有github.com私有仓库访问权限的人 <code>import &quot;gomod.io/private-module&quot;</code> 就能正常拉取了。</p>
<p>Go 工具链会自动把这个 vanity path 解析到你背后真实的仓库地址——以后即便你把代码从 GitHub 挪到自建 GitLab，只要在 gvu 里改一下映射，所有使用方的 import path 完全不用变。这也是五年前我们折腾 <code>govanityurls</code> 时最看重的那个特性，gvu 把它继承了下来，而且不需要你自己运维那套基础设施。</p>
<h2 id="管理你的路由">管理你的路由</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># 查看所有已注册的路由</span>
</span></span><span style="display:flex;"><span>gvu list
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 删除一个路由</span>
</span></span><span style="display:flex;"><span>gvu remove m_abc123
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 批量删除</span>
</span></span><span style="display:flex;"><span>gvu remove m_abc123 m_def456 -y
</span></span></code></pre></div><h2 id="如果你的仓库结构更复杂一点">如果你的仓库结构更复杂一点</h2>
<p><strong>Monorepo 场景</strong>：如果一个仓库里有多个 Go module（比如 <code>go/module-a/go.mod</code>），用 <code>--subdir</code> 指定子目录（需要 Go 1.25+）：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>gvu add gomod.io/module-a https://github.com/yourorg/monorepo.git --subdir go/module-a
</span></span></code></pre></div><p><strong>自定义域名场景</strong>：如果你不想用 <code>gomod.io</code> 这个默认域名，想用自己或公司的域名（比如 <code>go.mycompany.com</code>）做 vanity path 前缀，需要先升级到 Verified 账号（免费，只需绑定邮箱）并配置好 DNS CNAME。这部分内容稍微多一点，我会放在下一篇有关gvu使用的文章中详细讲，因为这正好对应我们当年真实的迁移场景。</p>
<h2 id="账号与配额">账号与配额</h2>
<p>匿名账号（也就是你什么都不注册、直接 <code>gvu add</code> 或<code>gvu auth signup</code>时自动创建的那种）免费可以用 5 个路由，够个人项目和小范围试用。用 <code>gvu auth bind your@email.com</code> 免费升级成 Verified 账号可以拿到 10 个，并解锁自定义域名。如果你需要更大的配额或者短路径这类进阶能力，可以看一眼 <a href="https://gomodvanityurls.com/pricing/">pricing 页面</a>，这篇就不展开了。</p>
<p>大家随时可以用下面这条命令看自己账号的状态：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>gvu auth whoami
</span></span></code></pre></div><h2 id="小结">小结</h2>
<p>到这里，你应该已经跑通了从安装到用上第一个私有 module 的完整流程——中间没有 Nginx，没有 YAML，也没有证书要自己签。</p>
<p>这就是 gvu 现在的公测版本。如果你在使用中遇到问题，或者有功能上的想法，欢迎去 <a href="https://gomodvanityurls.com/community/">Community 页面</a> ，或使用<code>gvu issue</code> 反馈，我会认真看每一条。</p>
<p>下一篇我会把五年前那套&quot;手动 govanityurls + Nginx&quot;的方案，原样迁移到 gvu 上，一步步对比迁移前后到底省了多少事——这也是很多老读者最关心的问题：如果我已经有一套手搭的方案，值不值得换。</p>
<hr>
<p>还在为写 Agent 框架频频死循环、上下文爆炸而束手无策？我的新专栏 <strong>《<a href="http://gk.link/a/12IzL">从0 开始构建 Agent Harness</a>》</strong> 将带你：</p>
<ul>
<li>抛弃臃肿框架，回归“驾驭工程 (Harness Engineering)”的第一性原理</li>
<li>用 Go 语言手写 ReAct 循环、并发拦截与上下文压缩引擎等，复刻极简OpenClaw</li>
<li>构建坚不可摧的 Safety Middleware 与飞书人工审批防线</li>
<li>在底层实现 Token 成本审计、链路追踪与自动化跑分评估</li>
<li>从“调包侠”进化为掌控大模型边界的“AI 操作系统架构师”</li>
</ul>
<p>扫描下方二维码，开启从 0 开始构建Agent Harness 的实战之旅。</p>
<p><img loading="lazy" src="/images/wp-content/uploads/2026/build-agent-harness-from-scratch-qr.png"></p>
<hr>
<p>你的Go技能，是否也卡在了“熟练”到“精通”的瓶颈期？</p>
<ul>
<li>想写出更地道、更健壮的Go代码，却总在细节上踩坑？</li>
<li>渴望提升软件设计能力，驾驭复杂Go项目却缺乏章法？</li>
<li>想打造生产级的Go服务，却在工程化实践中屡屡受挫？</li>
</ul>
<p>继《<a href="http://gk.link/a/10AVZ">Go语言第一课</a>》后，我的《<a href="http://gk.link/a/12yGY">Go语言进阶课</a>》终于在极客时间与大家见面了！</p>
<p>我的全新极客时间专栏 《<a href="http://gk.link/a/12yGY">Tony Bai·Go语言进阶课</a>》就是为这样的你量身打造！30+讲硬核内容，带你夯实语法认知，提升设计思维，锻造工程实践能力，更有实战项目串讲。</p>
<p>目标只有一个：助你完成从“Go熟练工”到“Go专家”的蜕变！ 现在就加入，让你的Go技能再上一个新台阶！</p>
<p><img loading="lazy" src="/images/wp-content/uploads/course-card/iamtonybai-banner-2.gif"></p>
<hr>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求，请扫描下方公众号二维码，与我私信联系。</p>
<p><img loading="lazy" src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png"></p>
<!-- 
公众号地址：https://mp.weixin.qq.com/s/wjmBZHxOnDy2Ws4a9mcY8A
-->
]]></content:encoded></item></channel></rss>