惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Know Your Adversary
Know Your Adversary
G
GRAHAM CLULEY
V
Vulnerabilities – Threatpost
P
Palo Alto Networks Blog
Security Latest
Security Latest
P
Privacy & Cybersecurity Law Blog
Simon Willison's Weblog
Simon Willison's Weblog
A
Arctic Wolf
T
Tor Project blog
T
Threatpost
NISL@THU
NISL@THU
I
InfoQ
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Apple Machine Learning Research
Apple Machine Learning Research
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
aimingoo的专栏
aimingoo的专栏
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
K
Kaspersky official blog
W
WeLiveSecurity
L
LINUX DO - 热门话题
小众软件
小众软件
Recorded Future
Recorded Future
B
Blog RSS Feed
H
Help Net Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
L
Lohrmann on Cybersecurity
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
Blog — PlanetScale
Blog — PlanetScale
雷峰网
雷峰网
爱范儿
爱范儿
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threat Research - Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
H
Hacker News: Front Page
博客园 - 三生石上(FineUI控件)
N
Netflix TechBlog - Medium
P
Proofpoint News Feed
有赞技术团队
有赞技术团队
N
News and Events Feed by Topic
云风的 BLOG
云风的 BLOG
Scott Helme
Scott Helme
V2EX - 技术
V2EX - 技术

Tony Bai

重磅!Tokio官方发布全栈框架Topcoat:不用WASM,AI时代Rust也能“糊”网页了 软件工厂的明与暗:当代码可以自动生产,人类为何必须留下一盏灯? Twitter之父再出手:Block开源Buzz,要让人类和AI Agent「同工同权」 Go 密码学维护者放大招:把 Passkey 存成一行字符串,还顺手为 Go 1.28 写好了 API Loop Engineering才火两个月,硅谷已经卷出“Graph Engineering”了 我开源了 cc-session-migrate :让 Claude Code 会话在多台机器之间自由迁移 从掌上设备的失败到AI时代的基石:Java官方纪录片,揭开一门语言30年的生死赌局 “皇帝的新衣”一年后:对话Thorsten Ball谈Agentic编程 告别标签页焦虑:我让 AI 帮我做了个浏览器插件 TabQueue Bun刚把Zig重写成Rust,这个团队却用487天反向重写 为了一个函数名,Go官方吵了两个月:maps.Same提案近日正式通过 Go 1.28 路线图首度曝光:Cgo 告别C工具链?泛型容器将入标准库? 掌控外环:为什么“循环工程”的边界必须由人类死守? 171个“已批准”却迟迟未实现的提案:Go语言的十年“欠账清单” 别再往 Go 里塞 Java 了:拆解 spf13 的 Idiomatic Go 信仰 AI 不在乎代码烂不烂,但你的Token账单在乎:一项660次实验揭示的编程新常识 10倍速 TypeScript 7.0 正式发布,前Go产品经理:Go才是AI智能体时代的“天选语言” Bun 重写为 Rust 后,Zig 之父罕见开炮:“我们早就等着看你重写” 全新 AI 技术栈:模型、Harness、Loop 与自我进化的智能体 AI 重写 Bun 为Rust全过程揭秘:101万行代码、11天、64个Claude并行开工 MCP Server 架构模式全解析:5 种模式、4 个反模式,与那条不能越过的“工具数量红线” 从手动 govanityurls + Nginx 迁移到 gvu:一次真实迁移记录 从“切歌小工具”到“零人工代码”:Claude Code 的诞生史,比科幻还科幻 如何使用 Claude Code 构建 AI 循环系统(Loops) 5 分钟上手 gvu:把 vanity import path 这件事,从“半天运维”变成一条命令 Go 对语言演化的保守态度,在未来 5 年是否仍然正确呢? 五年,三篇文章,一个我一直没真正解决的问题 别把“容易”当“简单”:Gin 框架作者撰文揭秘 88k Star 背后的架构哲学 每个 AI 工程师都应该知道的 20 个循环设计模式 cc-switch-cli:专为终端控与远程开发打造的 Claude Code 多模型切换工具! Andrej Karpathy 解析 Loop Engineering:构建“数日级”长程 Agent 的 9 条黄金法则 HashiCorp 创始人:AI 时代,我们为什么越来越需要有“品味”的程序员? HashiCorp 创始人:AI 时代,我们为什么越来越需要有“品味”的程序员? 一个 Rust 项目吃掉 75GB 硬盘?聊聊 Go 与 Rust 的“缓存焦虑”与拯救指南 折腾过各种语言后,我为什么总是回到 Go 语言? YC 揭秘 AI 原生组织:打造一家在睡梦中自我进化的公司 从 WordPress 到 Hugo:一个 20 年技术博客的迁移实录 偿还十年技术债:深度拆解 Go 1.27 的 GODEBUG 强力清理计划 浏览器里的“安全阴谋”:为什么 Go 1.27 的 UUIDv7 会离奇丧失随机性? Go 1.27新特性前瞻:泛型方法落地,标准库内建 UUID - Tony Bai AI 正在撕裂研发团队:狂欢的“托管派”与心碎的“守夜人” - Tony Bai 屠榜 CNCF!为什么在云原生时代,Go 语言能把 Java、C++ 和 Rust 堵在门外? 上千程序员自爆 AI 的“卧槽时刻”:是推开神界大门,还是跌入黑盒地狱? - Tony Bai 大模型正在见顶!传奇架构师:欢迎来到“平坦曲线时代” - Tony Bai Anthropic 40万大样本揭秘:AI 时代为什么“专家”身价暴涨? - Tony Bai 在 AI 编码时代,为什么我们依然选择 Go 而不是 Rust? DeepMind 亮出王炸:别再手写 Agent Harness 了,AI 已经学会自己写了! 为什么说“编译通过,就能运行”?Google 专家 Alice 揭秘 Rust 的工程美学与底层逻辑 谷歌 SRE 重磅白皮书:当 AI 自动写出 10 倍代码,谁来阻止系统崩溃? 别再省 Token 了!硅谷新共识:浪费算力才是唯一捷径 - Tony Bai Linux 内核顶级维护者:写了 35 年 C,是 Rust 让我重新找回了编程的乐趣 拒领上亿、封杀 AI:Zig 之父为什么 10 年不发 1.0? 写地道的 Go 语言,是否能让你成为了一个更好的开发者? - Tony Bai RSA 将死?Let’s Encrypt 押注 MTCs 迎战后量子时代 C++ 的权力游戏:一部关于妥协、背叛与重生的“史诗神剧” - Tony Bai 终结十年纠结:Go 新提案允许 Example 支持任意函数签名 - Tony Bai 2026年,大厂重构核心系统为何集体投向 Go? - Tony Bai “辛辛苦苦考上985,却发现AI能替代我90%的工作”:今天的高考,我们还在为什么而战? - Tony Bai 传奇黑客 Geohot 炮轰 AI Agent:这是软件工程史上代价最昂贵的灾难! 别把 Go 写成 Java:毁掉项目从过度架构开始 - Tony Bai 开源维护者的困境 - Tony Bai AI 时代如何真正掌握一门新技术?这份非主流学习指南建议永久收藏 - Tony Bai Go 生态17年大浪淘沙:2026年最值得引入的10个“神仙级”QoL工具包 - Tony Bai 再见样板代码!Go 官方新提案:函数一键转接口 - Tony Bai 写代码快 10 倍,不等于研发快 10 倍!Google 揭秘 AI 系统级瓶颈 Google I/O 2026:Jeff Dean 携 DeepMind 众神宣告,AI Agent 正在终结“标准化软件”时代 AI 优化 1.5ms,手写 0.02ms!Ghostty 作者痛批 AI 编程“平庸陷阱” Redis 之父吐槽现代前端的复杂性:我们到底是在解决问题,还是在制造问题? - Tony Bai 无痛消灭技术债:Google I/O 2026 开启 Go 自动重构时代 省下 10% CPU!Uber 揭秘 Go 栈扩容的隐秘代价 从 Go 迁移到 Rust - Tony Bai 悄悄用 Go 重写 AI 基础设施:NVIDIA 的 GPU 云平台为何选择 Go? Shopify 23,000 名工程师背后的 Claude Code 配置方案(你可以直接复刻的完整配置) Google 开源 AX 与 Agent Substrate:构建以 Agent 为核心的云原生计算底座 十年难题终获突破:揭秘 Go 1.27 接口逃逸分析优化 - Tony Bai
Go 私有模块拉取全解:凭据配置 + Vanity URL,个人与组织全覆盖
Tony Bai · 2026-07-08 · via Tony Bai

题图

本文永久链接https://tonybai.com/2026/07/08/go-private-modules-comprehensive-guide

大家好,我是Tony Bai。

Go 语言的依赖管理从 GOPATH 时代走到 Go Modules,公共依赖的拉取体验已经足够顺滑,但只要涉及“私有模块”,绝大多数团队和个人开发者都会在某个时刻撞上同一堵墙。

具体来说,大概率是下面这几个痛点里的一个或几个:

  • 凭据配置散落各处:.netrcgit config、CI 环境变量里都可能藏着一份 token,换一台机器、换一个 CI 平台,就要重新配一遍,稍不注意还容易把明文 token 提交进仓库;
  • import path 和代码托管平台强绑定:go.mod 里写死了 github.com/yourname/xxx,哪天想把仓库从 GitHub 挪到自建 GitLab 或者 Codeberg,所有依赖这个模块的代码都要跟着改 import path;
  • 想要有自己域名语义的 import path,又不想为此单独运维一套服务:自己写静态页面维护成本高,自建 govanityurls + Nginx 又要操心证书续期、单点故障;
  • 组织规模变大之后,新增一个私有模块的映射变成一件琐事:改配置、重载服务,团队人数越多,这类重复劳动的隐性成本越明显;
  • 代码需要跨组织边界分发时(比如交付给客户),原有的私有拉取方案在对方网络环境里直接失效,需要临时重新搭一遍。

这篇文章尝试把这件事一次性讲透,分三部分:

  • 第一部分是不分场景都要搞清楚的凭据配置底层机制;
  • 第二部分是个人开发者的几种典型场景;
  • 第三部分是组织 / 团队场景。

每种场景我都会给出对应的落地方案,上面这几个痛点,也会在对应的小节里逐一给出解法,供你按需查阅、按需收藏。

统一的凭据配置方案

在讨论任何具体场景之前,有必要先把几个容易混淆的环境变量和凭据配置方式讲清楚,因为后面所有场景本质上都是在这个底层机制上做排列组合。

两种主流的凭据配置方式

方式一:~/.netrc

这是最传统的方式,gitgo 命令本身都会读取这个文件:

machine github.com
login your-username
password ghp_your_personal_access_token

以github.com为例,其中的password你可以在“Developer Settings”的“Personal access tokens”中申请,推荐使用“Fine-grained personal access tokens”,你可以更好地控制token的权限粒度。

方式二:git configinsteadOf 重写

更推荐这种方式,因为它可以精确控制到某个域名 / 某个协议,而不是一个笼统的凭据文件:

git config --global url."https://oauth2:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"

如果你更习惯 SSH 方式(配好 deploy key 之后),可以让 HTTPS 的拉取请求自动重写成 SSH:

git config --global url."ssh://git@github.com/".insteadOf "https://github.com/"

CI 环境里,建议把 token 放进 CI 平台自带的 secret 变量,而不是明文写进仓库里的脚本文件,这是最基本的安全底线。

四个环境变量,职责边界要分清楚

这是整篇文章最重要的一个知识点,后面所有场景都建立在这个区分之上:

  • GOPRIVATE:告诉 Go 工具链,哪些 module 路径前缀属于私有模块,遇到这些路径时跳过公共 GOPROXYGOSUMDB,直接走版本控制工具(git)直连拉取。例如:
export GOPRIVATE=github.com/yourname/*,go.mycompany.com/*
  • GOPROXY:控制 module 内容本身怎么拉取、怎么缓存,默认是 https://proxy.golang.org,direct。如果你在公司内部有自己的私有代理(Athens、goproxy/goproxy.cn等),一般会配成类似 https://your-internal-proxy,direct 这样的组合。

  • GOSUMDB:控制是否要向 sum.golang.org 做校验和验证,私有模块通常需要连同 GOPRIVATE 一起把这一层也关掉,否则公共校验服务器根本没有你私有模块的记录,会导致拉取失败。

  • GOVCS:Go 1.16 引入的安全限制,控制哪些路径允许用哪种版本控制工具拉取,默认只允许公共托管平台走 git/hg 等,私有域名如果不在白名单里,可能需要显式配置,例如:

export GOVCS=go.mycompany.com:git

简单总结一下这四者的关系:GOPRIVATE 划定“哪些是私有的”,GOPROXY/GOSUMDB 决定“公共部分怎么拉、怎么校验”,GOVCS 决定“私有部分允许用什么工具拉”。

理解了这一层,后面无论是个人场景还是组织场景,本质上都只是在“私有仓库放在哪里”和“import path 要不要自定义”这两个维度上做选择,凭据配置这一层的原理是完全一致的。

个人开发者的私有模块拉取

直接使用 GitHub / GitLab 等平台的私有仓库

这是最简单、成本最低的场景。假设你在 GitHub 上有一个私有仓库 github.com/tonybai/privatemodule,配置如下:

export GOPRIVATE=github.com/tonybai/*
git config --global url."https://oauth2:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"

go get github.com/tonybai/privatemodule 即可正常工作,go.mod 里的 module path 直接就是 github.com/tonybai/privatemodule,不需要任何额外的“翻译层”。

想用个人域名做 import path,代码仍托管在 GitHub / GitLab / Codeberg 等平台

如果你不满足于 github.com/tonybai/privatemodule 这种带着托管平台印记的 import path,希望换成 example.me/go/privatemodule,或者希望以后即便把仓库从 GitHub 挪到 GitLab、Codeberg,import path 也保持不变,这就需要引入 vanity import URL 机制。

原理很简单:Go 工具链请求 https://example.me/go/privatemodule?go-get=1 时,期望拿到一个包含 go-import meta 标签的 HTML 页面,告诉它真实仓库地址在哪里:

<meta name="go-import" content="example.me/go/privatemodule git https://github.com/tonybai/privatemodule">

按运维成本从低到高,有几种落地方式:

方案一:手写静态 HTML,挂到 GitHub Pages / Cloudflare Pages 上

几乎零成本,只要给每个 module 路径建一个静态页面即可,缺点是每新增一个 module 都要手动加一个页面,仓库多了之后维护起来比较琐碎。

方案二:自己部署 govanityurls

govanityurls 是官方 golang.org/x 下的一个开源工具,读取一份 YAML 映射配置,自动生成对应的 go-import 页面。需要自己找一台机器(哪怕是最便宜的 VPS)跑这个服务,前面配一层 Nginx 做 TLS 终止。可控性最高,但要自己维护这套服务的可用性和证书续期。

方案三:用 gvu 这类托管服务

如果不想自己运维一套 govanityurls + Nginx,也可以用 gvu(gomodvanityurls.com)这类托管化的 vanity URL 服务,一条命令创建映射:

gvu add example.me/go/privatemodule https://github.com/tonybai/privatemodule.git

不需要自己起服务、配证书,适合不想为了一个 vanity 层单独维护基础设施的个人开发者。这只是三种方案里的一种,具体选哪种,取决于你是否愿意为了完全的可控性,多维护一套自己的服务。

自己在 VPS 上搭 Git Server,同时想用个人域名做 import path

如果你更进一步,连代码托管也不想依赖第三方平台,自己在 VPS 上跑了 Gitea、GitLab CE 或者 Codeberg 式的自建 Git Server,这里有个关键认知:vanity 解析层和实际代码托管,完全可以是两个互相独立的服务,用的甚至可以是不同的域名、不同的机器。

这种场景下,前面三种方案依然都成立,只是 go-import 里指向的真实仓库地址,从 github.com/... 换成了你自己 VPS 上的 Git Server 地址,例如:

<meta name="go-import" content="example.me/go/privatemodule git https://git.example.me/tonybai/privatemodule">

对应到 gvu 的用法上,就是把目标仓库地址换成你自建 Git Server 的地址:

gvu add example.me/go/privatemodule https://git.example.me/tonybai/privatemodule.git

同样,手写静态页面或者自建 govanityurls 这两种方式在这个场景下也完全适用,选择哪种取决于你愿意为“完全自主可控”付出多少运维成本。

组织 / 团队的私有模块拉取

组织场景相比个人场景,多出的核心考量是:仓库数量更多、参与人员更多、可用性要求更高——vanity 解析服务一旦故障,可能意味着全公司的 CI 流水线都构建失败,这是个人场景基本不需要考虑的风险等级。

组织统一使用 GitHub / GitLab 等平台的私有仓库

这是最常见的组织场景,凭据管理上比个人场景多几个需要注意的点:

  • 建议用机器账号(bot account)而不是某个具体成员的个人账号去生成访问令牌,避免因为人员变动导致 CI 突然失效;
  • 令牌尽量按仓库或按项目限权,而不是签发一个能访问组织下所有仓库的超级令牌;
  • 令牌统一放在 CI 平台的 secret 管理里,避免散落在各个项目的配置文件中。

其余配置和个人场景完全一致,GOPRIVATE 换成组织域名前缀即可:

export GOPRIVATE=github.com/mycorp/*

组织想用组织域名做 vanity import path

这是很多团队迟早会遇到的需求:不希望 go.mod 里到处是 github.com/mycorp/xxx,而是想统一成 go.mycompany.com/xxx,一方面是品牌语义,另一方面是为未来可能的仓库迁移(比如从 GitHub 换到自建 GitLab)留出余地——只要 vanity 层的映射改一下,所有下游使用方的 import path 完全不用变。

五年前我在公司内部第一次搭建这类方案时,写过几篇实践记录(《小厂内部私有Go module拉取方案》、《小厂内部私有Go module拉取方案(续)》和《小厂内部私有Go module拉取方案3》),走的就是自建 govanityurls + Nginx 这条路。这套方案跑了五年,整体稳定,最大的优势是完全自主可控,不依赖任何第三方服务;代价是每新增一个仓库都要手动改一次映射配置、重载一次 Nginx,团队规模大了之后,这个日常维护成本会逐渐显现出来。

如果团队不想自己承担这部分运维成本,用 gvu 这类托管方案可以把“新增映射”这个动作压缩成一条命令,而且天然具备高可用(不用担心自己那台跑 govanityurls 的机器挂了导致全公司构建失败):

gvu add go.mycompany.com/privatemodule https://github.com/mycorp/privatemodule.git

两种路线各有取舍:

  • 自建方案胜在完全自主、不依赖外部服务的可用性;
  • 托管方案胜在免运维、天然高可用。

具体选哪个,取决于团队愿意在这件事上投入多少运维精力。

组织在内部数据中心 / VPS 自建 Git Server,同时要 vanity import path

这是组织场景里最复杂、也最容易被低估的一种情况:私有代码托管在内部数据中心自建的 GitLab / Gitea 上,同时又希望有一层语义化的 vanity import path。原理和 前面个人场景自建git server完全一致,只是仓库地址换成了内部数据中心的地址(通常是内网 IP 或内网域名)。

这里额外提一句:如果你的团队还涉及把这类私有代码以“白盒交付”的方式给到外部客户,会遇到一个更棘手的问题——客户的网络环境访问不到你内部的 vanity 服务和内部仓库,这又是另一套需要专门讨论的方案了,我在上一篇《五年,三篇文章,一个我一直没真正解决的问题》里记录过我的具体做法,这里不展开。

小结:怎么选

把上面讨论的几个维度整理成一份简单的参考:

  • 只是想让私有依赖能被 go get 拉到,不在乎 import path 好不好看:直接用托管平台的私有仓库 + 对应凭据配置即可,不需要引入 vanity 层。
  • 想要自定义 import path,且不介意自己运维一套服务:手写静态页面(仓库少)或自建 govanityurls(仓库多、要求可控)都是合理选择。
  • 想要自定义 import path,但不想自己运维 vanity 服务:可以看看 gvu gomodvanityurls.com这类托管方案,一条命令搞定映射。
  • 组织规模较大、涉及高可用要求,或者需要频繁给不同客户 / 项目分配独立的 import path:优先考虑免运维的托管方案,或者在自建方案上补齐高可用保障,两者都是可行路径,关键是提前想清楚团队愿意为“完全自主可控”付出多少运维成本。

无论最终选哪条路,先把第一部分那几个环境变量的职责边界搞清楚,后面遇到的大多数报错,基本都能顺着这条线索排查出来。


还在为写 Agent 框架频频死循环、上下文爆炸而束手无策?我的新专栏 从0 开始构建 Agent Harness 将带你:

  • 抛弃臃肿框架,回归“驾驭工程 (Harness Engineering)”的第一性原理
  • 用 Go 语言手写 ReAct 循环、并发拦截与上下文压缩引擎等,复刻极简OpenClaw
  • 构建坚不可摧的 Safety Middleware 与飞书人工审批防线
  • 在底层实现 Token 成本审计、链路追踪与自动化跑分评估
  • 从“调包侠”进化为掌控大模型边界的“AI 操作系统架构师”

扫描下方二维码,开启从 0 开始构建Agent Harness 的实战之旅。


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。