2026-07-01 17:33:15
我曾经一度对于「平台产品经理」是没感觉的。毕竟大家都是产品经理,做平台有什么了不起的?大家干的不都是产品经理的活么?你有什么差异。
但,后面,发生了一件事,让我记忆犹新,从而对于「平台产品经理」和平台级业务的感知和敬畏加深。
那时我刚加入飞书开放平台,作为飞书开放平台的技术型产品经理,我要去推动一个产品上的 API Breaking Changes。如果在产品发布前就触发了 Breaking Changes,就一定要提前告知客户,不然会直接出现事故,要追责。所以,我就发布了通告,进行客户的告知。
看起来很正常,且做的事情逻辑也对,是么?
但其实那次被定义为事故,事后组织了复盘。
之所以被称为事故,是因为,我的客户告知,进行了一次大面积告知,我的通知告知了所有的开发者客户,但实际上真正可能受影响的客户并没有那么多,我的过度告知反而给平台带来了巨大的解释成本和服务成本。
这个事情很小,但非常明显的体现出了普通产品和平台型产品的很大区别,普通产品大家的影响面可能是非常有限的,但平台型产品,特别是 TO B 的平台型产品,你的影响面可能是数以万计的用户和客户。一个处理不好,可能就是所有人要陪着你一起去跪客户的。
2026-06-24 18:06:29
最新更新于 2026 年 6 月 29 日
这个指南是我自己的 AI Coding 的经验总结,我认为在实际使用 AI Coding 的过程中,应该注意和遵循的规则。
这篇文章是我实践后高度总结出来的结论,如果你想看更细致的内容,可以看 从“代码补全”到“全托管 Agent”:我的 2025 AI Coding 进化论 和 半年过去了,我和 AI Coding 的关系有什么变化?
当你开始使用 AI Agent 来辅助编程后,你很快会发现,最大的瓶颈是你自己的管理范畴和你的精力管理。
AI 时代,信息的生产变得无比简单,这导致我们看到的信息、要处理的信息进一步爆炸。因此,如何更好地利用 AI Agent,降低我们的决策成本、提升我们的信息信噪比,让我们可以少做决策,做正确的决策。
使用你能接触到的最贵的模型来进行开发;能用 Claude Opus ,就不要用 GPT 5.5 XHigh;能用 GPT 5.5 XHigh,就不要使用 GLM 5.2 。
更贵的模型意味着对于你来说,可以更少的干预和决策,降低你对于 Agent 的管理成本。除非,某个任务对你来说,真的就是一句话任务,或者让他执行一个极其简单的任务。
对于格式化、批量替换、简单脚本、低风险机械任务,可以使用更便宜、更快的模型。
你写给 Agent 的 Prompt,本质上就是临时规格说明。模糊的 Prompt 会生产模糊的实现。一个好的任务应该包含:背景、目标、非目标、修改范围、验收标准、验证命令和风险边界。
不要害怕给 Agent 长的 Prompt,相反,你应该尽可能榨干自己的脑子当中的想法,把和你的需求相关的事情全部写下来,即使只是很简单的个人倾向性的描述,也可以有助于帮你更快的完成自己的目标。
所有的工作,除了简单的日常动作(就是那种你觉得丢给随便哪个模型都能干的事情),只要是正常的工程工作(Feat / Bug / CI),都要使用 Plan Mode 先聊一轮。目标是在过程中澄清你的需求,避免似是而非的需求进入到研发队列,浪费你的时间和精力。
把主要精力放在 Review Plan、Review Diff、Review Test Result 和风险项上,而不是逐行 Review Agent 写的每一行代码。你的精力终将不足以支撑传统意义上的全量 Code Review。
对低风险、可逆、影响面小的细节,可以降低审查强度;对数据、权限、计费、迁移、鉴权、删除、生产发布等高风险改动,必须重点审查。
作为 AI Agent 的管理者(Manager),你要做的是抓大放小,何为大?架构设计、方案设计;何为小?具体的细节操作的命令。保持使用 YOLO 模式(Codex 的 dangerously skip permissions 模式),可以帮助你减少微操。
但是,不是无脑 YOLO。你需要确保即使是 Agent 在 YOLO 模式下发挥所造成的最灾难的状态,你是可接受的。
可逆沙盒至少意味着:代码已经进入版本控制;Agent 工作在独立 branch 或 worktree;没有生产密钥;没有生产数据库写权限;危险操作有备份或 dry run;部署、数据迁移、删除类操作需要人工确认。
和 Vibe Coder 不同,作为工程师,我需要交付的是有价值的产品。所以,还是要让工作尽可能的 Under Control,避免 Coding Agent 帮你办离职。
无论你的项目大还是小,都要上一个版本控制工具。可以是 Git ,可以是 SVN,也可以是 hg,但一定要有。你需要让 Agent 始终工作在版本控制工具的范畴内,即使出现了问题,你也能快速回滚。
此外,一定要放在云上,这样即使是最极端的灾难情况 —— AI Agent 删除了你的所有代码,你也可以从云端找回一个历史的版本。
此外,用好 worktree 之类的功能。
让 Agent 以功能 、特性为维度小步快跑,而不是一次性憋个大的。这对于要确认的你不友好;对于 Agent 也不友好。模型的注意力也会涣散,也会出现遗漏重点的问题。
小的步骤配合着版本管理工具,可以帮助你更快的迭代,同时,更稳。
除非你知道你在让 Agent 做什么,不然不要试图让 Agent 直接操作你的生产环境;如果实在不知道怎么操作,最好的办法是让 Agent 给你一个操作手册,你跟着操作手册去执行,并要求 Agent 解释每个行为的意义和价值。
我猜你不会想删库跑路的吧?
尽可能早的报错,不管是代码,还是逻辑;尽早报错可以帮助 AI Agent 更快的发现问题,从而更快的解决问题。而不是到线上才暴露问题。
从这个视角来看,Typed Lang is better than non-typed lang。Golang、Rust、TypeScript 这类有强静态反馈的技术栈,更适合 AI Agent 协作;纯 JavaScript 这种反馈更晚、更依赖运行时和人工约束的方案,会显著增加 Agent 协作成本。
除此之外,为你的 Coding Agent 构建尽可能多的反馈回路,让他除了写代码之外,还可以通过反馈回路来获得反馈,优化自己的代码和实现。这些反馈回路包括:
让你的 Agent 在完成工作后,执行这些工具,尽快获得反馈,并自我修复,避免 Bad code smell 进入你的代码仓库。
git hook 就是一个不错的选择:pre-commit 搞定 type check、lint、format;pre-push 搞定 testing 和 Cyclomatic Complexity。
尽可能构建你自己的项目的 CI/CD流程,除了本地的 hook 和检查,你还需要更加强制的校验,确保符合要求的代码才能进入你的代码仓库主分支。
确保你的 CI/CD 流程包含测试、e2e、复杂度、覆盖率分析、安全扫描,让你的代码尽可能的安全。
CI 负责阻止不合格代码进入主分支;CD 负责让可发布版本以可审计、可回滚的方式进入环境。
由于模型的推理和 Agent 的工作需要时间,所以不要和 Agent 同步工作,而是尽可能的和 Agent 异步工作。通过 Plan 功能,前置让 Agent Review 和设计工作,并在确认后,让确认完的 Agent 工作;
这样你可以有效的让你的 Agent 和模型的工作最大化的利用;这里最重要的是让 Agent 可以在过程中一次性把要确认的快速确认完,然后自己可以兢兢业业干半个小时,甚至更久。你只在他需要你的那一刻投注注意力,剩下的时间,安排好你的注意力。
我最近比较喜欢用的是一个大的屏幕上同时开四个 Codex 干活;如果你是 Windows ,可以使用 wmux, mac 下则可以考虑 cmux 。这些都不错。

对了,一个副作用是,你可能会发现,跑了多个 Agent 之后,你会需要一台更强悍的电脑(所以我买了 2026年的 MBP M5 MAX)
和人类不同,Agent 每一个线程都是完全独立的;只要你的 message 是独立清晰的;Agent 是可以并行工作的。而唯一能限制你并行度的,就是你自己对于工作的拆分和理解。
一个比较合理的方案是使用 git worktree 并行开发;同时尽可能避免让多个 Agent 处理同一个模块的事情,减少最后在合并回主分支时冲突的发生。
但是,需要注意,尽量不要跨项目并发工作,你自己的上下文会不足以支撑切换。
对于人类来说,睡眠是一个很好的休息的时间,但对于 Agent 来说,不是的。 Agent 不需要休息,但很显然,休息状态时,你不太可能去跟进 Agent 的决策,确保他的产出是符合你的预期的,所以,你需要一些能够深夜自动工作的任务,从而帮助你利用好你的睡眠时间。
我一般会在深夜让 Agent 做这些事情:
AI Agent 在写代码时,会很容易出现复杂,你无法理解的写法,导致代码对你而言,彻底无法维护。这个是一定要避免的,你需要学着控制你的项目的复杂度,让 Agent 写完后跑 Cyclomatic Complexity 检查,超标必须重构,避免项目过于复杂,导致你无法维护。
即使你的代码是 Agent 写的,更加简单易于理解的逻辑,也会让你获得更好的结果。毕竟,你可能绝大多数的时候都能借助 AI Agent 搞定工作,但最终还是要确保自己有救济途径;可以接管 Agent 的工作。
无论是 Claude Code 还是 Codex,其实都有 /init 功能,来快速建立 AGENTS.md 和 CLAUDE.md 来帮助你建立一个项目级别的 Profile ,用来引导 Agent 执行;但实际在使用过程中,Agent 生成的文件是无法完整覆盖你对于这个项目的完整定义的。因此,你要学会配合使用不同的层级的 AGENTS.md 来帮助你做好架构。
比如,我会同时使用全局的 AGENTS.md 和 项目级别的 AGENTS.md 来管理我的 AGENT 的行为。我会在全局(~/.codex/AGENTS.md) 中,会加入一些纲领性的指引,比如下面这个例子;
# 基本设定
- 交流使用中文;代码、注释、标识符、提交信息及代码块用 English;技术文档使用 English。
- 处理 Github 相关操作优先使用 `gh` cli。
# 核心原则
- 约束优先级:显式规则 > 正确性/安全性 > 业务边界 > 可维护性 > 性能 > 代码长度 / 局部优雅。
- 在写代码时,你会尽可能多的把可能后续 DEBUG 时所需的日志全部通过日志的方式打印出来,方便后续排查问题;并做好 Level 管理,方便在生产环境时通过 Level 只看最核心的日志。
- 在写代码时,如果你发现单个文件过于复杂或太长,不利于维护,你会适当的拆解合适的模块。
# 表达与风格
- 重点放在设计清晰设计、抽象、正确性、稳定性、性能与可维护性
## 提交与协作
- 提交信息遵循 Conventional Commits:`<type>[optional scope]: <description>`,例如 `feat(repos): add owner filter`。
- 每次执行任务前,都先使用 git pull,确保 main 分支已经是最新。
- 小步提交,完成一个任务后就提交(一个任务的范畴是未来可能一起回滚的),只 stage 自己相关的改动。每次完成任务记得提交;
- 不要提交真实 `.env`、密钥、数据库连接串、OAuth token 或本地私有配置。
- 当前项目会使用 .gitlock 来作为 git 锁;如果你准备 commit ,就要创建一个 .gitlock 文件到项目根目录;如果你 commit 完成,就删除这个文件。如果你准备 commit 时发现有这个文件,就等待 30 秒后再检查直至这个文件删除后再执行 commit
然后,在项目级的 AGENTS.md ,我就不会再使用 commits 的约束,并更多的精力放在项目本身的描述上。
以及如果你的项目最近架构发生了变化,记得重新生成 AGENTS.md 文件,避免旧的架构文件错误引导 Agent 工作。
使用 AI Agent 编程,本质上是一次角色转变:你不再是那个逐行写代码的人,而是那个定义目标、划定边界、审查结果的 Manager。
Agent 的能力上限,取决于你给它的上下文质量;你的精力上限,取决于你把注意力放在哪里。
把决策权留给自己,把执行权交给 Agent,把验证权交给工具链。这三件事做对了,你的生产力才真正被放大——而不是被 Agent 带着跑。
代码是你的,不是 Agent 的。
2026-06-23 23:55:41
在意大利无法像在其他国家那样使用Uber X等网约车服务,需要下载专门的本地应用。appTaxi在佛罗伦萨覆盖率较高,而ItTaxi适用于罗马等地,范围更广。
计费从司机接单驶向乘客时便开始,上车前可能已有费用产生。司机通过专用设备接单,信息有限,需再次确认目的地。可以使用信用卡支付,前往车站则应提前预约车辆。
看到标题,你可能会好奇,诶?为什么是【在意大利打车】?在意大利打车和其他地方有什么不同么?
是的,不同的。在意大利,你并不能像我们在国内这样方便的使用 App 打车!在法国,你可以直接使用 Uber 打车,但在意大利,不行,你没办法打 Uber X(我们一般意义上的网约车)

So,如何打车?
想要在意大利打车,你需要下载当地的 App,比如我下载了 appTaxi 和 ItTaxi 这两个 App 来专门打车;
其中 appTaxi主要是在佛罗伦萨比较强,如果你是在佛罗伦萨,那么可能 appTaxi 能够更快的打到车;
而 iTTaxi 我们则是在罗马使用的,他的覆盖范围也会更广一点。
单纯 App 倒也没啥,我们可以说一些重要的注意事项

就记得意大利和其他地方不一样~得下载专门的 App 就行~
2026-06-23 12:56:00
作者第二次出国旅行时主要入住万豪系酒店,全程使用万豪App预订以便灵活调整行程。巴黎酒店房间和电梯偏小但价格划算,里昂万豪虽大且舒适但位置偏远,尼斯和佛罗伦萨的酒店位置尚可,罗马的AC酒店则过于偏僻,不适合观光。
此次体验让作者更重视酒店与景点的距离,并意识到在高消费城市应控制预算,将资源留给后续行程以获得更高性价比。
由于是我的第二次出国旅行,再加上这次的行程有很多不确定性的,所以这次订酒店和上次美国之旅有所不同,上次我少量入住了万豪/IHG的酒店,这次则是大量入住了万豪系的酒店。
实际上这次只有在巴黎住的酒店是在携程上订的,剩下的全部是用万豪 App 来订的。用万豪 App 的一个好处就是,你可以随时退房,这样如果行程临时发生了变化,就可以非常方便的更换酒店了。
在巴黎时,我们住的是 巴黎蒙帕纳斯阿维雅蓝宝石酒店(Avia Hôtel Saphir Montparnasse) 酒店,这个酒店的房间不是很大,你可以看到,房间放下两个 28 寸的箱子后,其实空间就很少了;左侧窗边也只有一个很小的过道。
整个巴黎的酒店都还挺贵的,所以这个酒店就显得非常划算,我们住了 4 天,花了3400 块钱,日均 800 块钱。

房间小倒是其次,我觉得更加关键的是 —— 电梯小。和国内往往都是一些大电梯不同,我们住的这家酒店的电梯异常的小,我倾向于这是因为这个酒店所使用的房子其实是老房子,所以没办法加装大电梯(毕竟位置倒是还不错)。电梯只能同时站下我们两个人 + 两个箱子(非常拥挤),如果是人比较多的话,可能会比较麻烦。如果你和我一样是个胖子,巴黎的电梯可能不会让你特别舒适。
里昂我们住的是 Lyon Marriott Hotel Cité Internationale。这个酒店就不一样了,又大又新;我们当时还住了一个临街房型,房间里还有阳台,住起来颇为舒适。

不仅如此,这家酒店是给拖鞋的!之前一直觉得美国酒店的是没有拖鞋的,所以觉得欧洲可能也没有,这次就也自己带了拖鞋。结果,这家酒店是赠送拖鞋的,就让我对于万豪的好感 + 1;虽然贵,但最起码还是有点服务的。
不过这家酒店有个问题 —— 太远,你如果是来逛里昂市区的各种风土人文的话,这家酒店还是有点远了。出门都一定要打车。此外,我觉得这家酒店还有点比较坑的是。。。他们楼下还有赌场。。。可能对于有担心的人来说,不一定是个好的选择。
我自己下次去里昂,可能不会选择住这家酒店,而是选择一个更加市区的酒店。
尼斯我们住在 Nice Centre Hotel,这家酒店的位置不错,如果你和我一样,是坐高铁抵达尼斯,从尼斯站出来步行 10 分钟就是这家酒店。不仅如此,这家酒店旁边,就是尼斯圣母殿。不过就是离海边稍微有一点远,走路过去需要 15 ~ 20 分钟才能走到。


不过高楼层带阳台也有坏处,就是你楼顶就是酒店的 Bar


我觉得如果你第一次来,这家酒店还可以,旁边的店铺啥的都比较多,交通也方便,或者是你晚上到。如果第二次,你是来度假,纯看海躺平,那离海边更近的酒店更适合你。
我们在佛罗伦萨住的时佛罗伦萨万豪AC酒店(AC Hotel Firenze)。这家酒店的位置不错,离城区有一定的距离,但也不会特别远,晚上我和太太还走路出去吃晚餐,附近有几家不错的中餐馆,还挺方便的。而且附近走一走,就有洗衣房和缆车站和公交站,很方便。

这家酒店的面积也很大,我们住起来非常的不错;
果然,离开巴黎,你住的酒店都还行。。。
在罗马,我住在AC酒店克洛迪奥罗马(AC Hotel Clodio Roma)。总结来说:后悔,太后悔了,这家酒店的位置有点偏,感觉适合商旅,并不适合来旅游。导致我们在罗马的几天,一出门就要打很久的车,坐很久的车才能到景点,唯一近的是梵蒂冈城。。。

虽然,酒店的房间还是不错的。。。我们的房间还带了个小阳台,晚上出来吹吹风体验不错。

这次欧洲之旅,给我了和美国之旅不同的体感,也有了新的对于酒店的选择思路;
下次可能出国,我依然会考虑住万豪之类的酒店集团的酒店,但我会更加关注从酒店到我要去的景点的位置;同时,也会适当调整预算,比如像巴黎这种明显就是更贵的地方,就别折腾了。。。把预算留给后面的城市吧, ROI 更高!
2026-06-21 06:09:00
尝个鲜系列是我尝试开启的一个新的系列,记录一些我吃的好玩的,不太「日常」的东西。
忘了在哪里刷到了健民辣丝,在淘宝上买了两包健民辣丝。东西倒是不贵,两包 8 块钱(当然,可能作为一个咸菜是有点贵的,但对于我的消费能力能力倒还好)。
这个东西在网络上的风评是【巨辣】,但确实从商品图上看不出来,好奇之下,买了两包健民辣丝,配着面条,试试看。
第一眼看到健民辣丝的时候,确实不觉得这玩意会辣...毕竟,白白净净的,见不到辣椒的红色;说芥末辣的话,也看不到芥末的绿色

而看反面的配料表的话,其实也看不到什么能“辣”的元素。

健民辣丝吃上去的话,其实并不算辣;甚至口味还挺清淡,得益于配料表中的白糖,实际上你吃起来是酸甜口的,虽然芥菜丝是有一点点微辣的口感,但完全可以接受,不会出现太辣的问题。
而真正让我感受到辣的 —— 是吃健民辣丝里面的花生米。这个花生米同样也是白白净净,但当你吃了一颗后,芥末味直冲心灵。
刺激!
我自己吃完健民辣丝,觉得其实还蛮不错的;很适合作为夏天的小凉菜,酸甜口不容易反感,芥菜丝的微微辣可以让你在甜酸口中再补一层独特的口感,非常惊艳。
如果你不喜欢芥末味的话,不要吃里面的花生米,那就问题不大,整体的体验还不错。
我问了问 Grok,为什么健民辣丝里的花生米比芥菜丝更辣,这是Grok 的回答

2026-06-20 20:28:57
近些年来,我的个人项目基本上也是托管在 Github 上的。主要的原因一方面是 Github 身边的 Git Repository 使用起来体感还不错,另一方面,也是很重要的便是 Github 的 Actions。
作为一套开箱即用的 CICD 系统,Github Actions 给所有的 Public repo 提供了免费的运行时长,而对于 Private Repo,则没有那么多;我虽然购买了 Github Pro,每个月有 3000 分钟的额度可以使用,但随着你的项目越来越多,在进行的 CICD 检查越来越多,导致 3000 分钟的额度捉襟见肘,经常月中就没有了。
所以,我就瞄上了 Github Actions 的 self-hosted runners。其实如果你有足够的主机,配置起来挺简单的。打开 Github 仓库页面,找到 设置 - Actions - Runner 页面,就可以新增 self-hosted Runner,在新的引导页面,选择你要使用的操作系统,然后跟随下面的指引安装即可,简单易行。

不过,这个方案也有个问题,一台主机只能安装一个 Runner,而一个 Runner 只能工作于一个仓库,对于项目比较多的人来说,还是不方便,所以就有了我研究使用 Docker 化部署的方案,在研究了前人的工作之后,我对这个方案进行了一定的优化,最终形成了你所看到的这个版本。
如果你不想看下面的细节描述,那比较简单粗暴,直接执行下面这个命令,就可以在你的 Docker 服务上启动一个容器作为 Github Actions 的 Self-hosted Runner。
docker run -d \
--name actions-runner \
--restart unless-stopped \
-e RUNNER_URL=https://github.com/<owner>/<repo> \
-e RUNNER_REGISTRATION_TOKEN=<token-from-config-sh-command> \
-v /var/run/docker.sock:/var/run/docker.sock \
bestony/actions-runner:latest
其中,第四行的 Runner URL 是指你自己的 Github 的仓库地址,直接配置上就行;
而第五行的 Token 则是你在 Runner 指引页面看到的 Config 的 Token

当你执行完成后,2-3 分钟,就可以在 Github Actions 设置页面的 Runner 看到刚刚启动的 Runner 了。

接下来,就是在你所有要使用 self-hosted runner 的 job 上,修改他对应的 run-on 配置即可
# Use this YAML in your workflow file for each job
runs-on: self-hosted
我在代码层面支持了 Linux 和 Windows ,并预打包了对应的 Docker 镜像。Linux 使用的是 Ubuntu 24.04;Windows 使用的是 Windows 2022;此外,支持了 Linux的 x64,arm x64 和 arm v7, 如果你是本地 NAS 使用,应该也可以跑。不过我自己还没测试 ARM 的环境,如果你遇到问题,也可以直接提 issue 来反馈。
打包好的 Docker 镜像放在 https://hub.docker.com/r/bestony/actions-runner ,你可以在 DockerHub 页面上看到。
这个实现的原理本质上就是借助 VM 的 Container 机制,将 Github Actions 的 Runner 二进制文件放在 Docker 镜像中,并通过托管 Docker Socket,来实现让容器内的 Runner 文件可以管理 Docker 容器,从而在后续执行 Job 的时候,创建对应的容器。
代码在 https://github.com/bestony/actions-runner (欢迎来 Star)
Github Actions 提供了缓存能力,从而可以让不同的 job 和 不同的 run 可以使用相同的缓存,减少一部分缓存的时间和成本。 Self Runner 如果想要使用缓存,并让后续的 Runner 都可以使用缓存,你可以这样配置。关于缓存服务的自部署的更多信息,你可以参考 GHA Cache Server 的文档
首先,你需要创建一个 Runner 专属的网络,从而让所有的 Runner 共享一个 Cache Server,方便后续使用。比如我们这里创建一个名为 Runner 的网络
docker network create runner
当你已经有了提前创建好的 Repo 后,就可以根据需要来创建 Runner 了。你可以直接复制我下面的这段配置,存储成为 DockerCompose.yml ,修改环境变量配置,并使用 docker compose up -d 命令来启动,从而创建一个 Runner ,并启动相应的缓存服务器,来实现启动一个带缓存的 Runner。
services:
runner:
image: bestony/actions-runner:latest
restart: unless-stopped
env_file:
- path: .env
required: false
networks:
- runner
environment:
RUNNER_URL: ${RUNNER_URL:-}
RUNNER_REGISTRATION_TOKEN: ${RUNNER_REGISTRATION_TOKEN:-}
REPO: ${REPO:-}
TOKEN: ${TOKEN:-}
ACTIONS_RESULTS_URL: ${ACTIONS_RESULTS_URL:-http://cache:3000/}
RUNNER_NAME: ${RUNNER_NAME:-}
RUNNER_LABELS: ${RUNNER_LABELS:-}
RUNNER_WORKDIR: ${RUNNER_WORKDIR:-_work}
RUNNER_EPHEMERAL: ${RUNNER_EPHEMERAL:-false}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
mode: replicated
replicas: ${RUNNER_REPLICAS:-4}
resources:
reservations:
cpus: "${RUNNER_RESERVED_CPUS:-0.5}"
memory: ${RUNNER_RESERVED_MEMORY:-1024M}
limits:
cpus: "${RUNNER_LIMIT_CPUS:-2.0}"
memory: ${RUNNER_LIMIT_MEMORY:-4096M}
cache:
container_name: cache
image: ghcr.io/falcondev-oss/github-actions-cache-server:latest
restart: unless-stopped
networks:
- runner
ports:
- "3000:3000"
environment:
API_BASE_URL: http://cache:3000
volumes:
- cache:/app/.data
volumes:
cache:
networks:
runner:
external: true
上面这段配置主要有几个核心配置需要关注:
当你完成上述的配置,但发现你需要一个新的 Self-hosted Runner 的时候,就可以复制下面不包含 Cache Server 相关的配置,直接使用了。非常的方便
services:
runner:
image: bestony/actions-runner:latest
restart: unless-stopped
env_file:
- path: .env
required: false
networks:
- runner
environment:
RUNNER_URL: ${RUNNER_URL:-}
RUNNER_REGISTRATION_TOKEN: ${RUNNER_REGISTRATION_TOKEN:-}
REPO: ${REPO:-}
TOKEN: ${TOKEN:-}
ACTIONS_RESULTS_URL: ${ACTIONS_RESULTS_URL:-http://cache:3000/}
RUNNER_NAME: ${RUNNER_NAME:-}
RUNNER_LABELS: ${RUNNER_LABELS:-}
RUNNER_WORKDIR: ${RUNNER_WORKDIR:-_work}
RUNNER_EPHEMERAL: ${RUNNER_EPHEMERAL:-false}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
mode: replicated
replicas: ${RUNNER_REPLICAS:-4}
resources:
reservations:
cpus: "${RUNNER_RESERVED_CPUS:-0.5}"
memory: ${RUNNER_RESERVED_MEMORY:-1024M}
limits:
cpus: "${RUNNER_LIMIT_CPUS:-2.0}"
memory: ${RUNNER_LIMIT_MEMORY:-4096M}
networks:
runner:
external: true
如果你和我一样,喜欢用 Github,但又没有足够多的 Github Actions 运行时长可用,或者你需要依赖一些你自己的内网环境,那么这个 self-hosted runner,就是为你准备的。