2026年成功构建自托管软件工厂:指令驱动全流程开发,隔离性与自主性待平衡

构建一个(几乎)完全自托管、沙盒化、自主运行的软件工厂

2026年8月21日,阅读时长10分钟。简而言之,我构建的这个(几乎)完全自托管、沙盒化、自主运行的软件工厂成功了!只需一个指令,它就能创建一个代码仓库,编写应用程序和测试代码,让持续集成(CI)流程通过,配置好Postgres数据库,并将完成的应用部署到HTTPS环境中,全程无需我再下达其他指令。若你只想看结果,可在文章底部找到演示视频。

大语言模型(LLMs)又变得有趣起来了!或许它们一直如此,只是我之前陷入了失望的低谷。最近,每当我需要一个小工具时,就自己动手构建。前几天在健身房,我想要一个记录举重数据的应用。理想中的应用很简单,就是基本的增删改查(CRUD)功能,但应用商店里的相关应用每月收费12英镑,于是我用Claude一次性搞定了一个。这很有趣,但让大语言模型在自动模式下获得我机器的root权限,我还是不太放心。

因此,挑战来了:如何创建一个完全远程的自主开发环境,从架构上对大语言模型进行约束,而非仅仅依赖信任?我希望给它一个指令,它就能自主完成整个软件开发生命周期(SDLC)的工作:研究合适的技术栈和软件包;规划并编写代码和测试;将代码提交到Git仓库,构建并运行CI管道;将项目部署到“生产”服务器,配置好数据库、可观测性工具(o11y),并使用带有SSL的域名。所有这些都在我的家庭服务器上完成,无需额外支付云基础设施费用。这次实验唯一的持续成本是每月20英镑的Codex订阅费用。

服务器

服务器这些就是我的服务器,尽显风采。下面那台是2014年的双核i3服务器,我把它当作家庭实验室用了五年。它顽强地托管着这个博客和大约45个Docker容器,从Pi - hole到完整的Prometheus / Loki / Grafana监控栈都有。它还将路由器的443端口进行了转发。如果大语言模型把它搞坏了,我会很恼火,所以今天不用它。上面那台是2021年的第十代i7服务器,有32GB内存,我从eBay上全新买来的,里面什么都没装,正合适。

技术栈

核心开发栈通过Coolify进行自托管。推理和集成(如Tailscale、Telegram、DNS和ACME)仍需连接外部网络。你也可以自托管推理服务,但我没有相应的硬件,而且我更希望OpenAI为我的实验提供补贴。

组件说明
Pi - hole本地DNS规则管理,还能让你少看到一些垃圾广告。
Tailscale让我的家庭网络如影随形。
Coolify基于Docker构建的自托管、类Heroku的平台即服务(PaaS)。
Forgejo(带运行器)自托管的Git和CI服务。
Hermes(带Web UI)类似OpenClaw的虚拟助手,使用Codex进行推理。
Telegram可以在厕所或其他任何地方与代理进行交流。
Firecrawl(自托管)代理与网络之间的抓取/翻译层。
Porkbun(域名注册商) & Let's Encrypt提供域名和即时SSL证书。
其他Postgres、Redis等,你的应用需要什么就用什么。反正底层都是Docker,对吧?

参考资料

这不是一篇完整的操作指南。我或许可以写一个Ansible一次性脚本把所有东西都设置好;如果你需要,可以在下面的GitHub仓库里提个issue。不过,如果你都读到这里了,应该自己也能搞定。

参考资料说明
Coolify安装博客我在Hetzner上安装Coolify的指南。
Coolify Dockerfiles能在Coolify上正常运行的生产环境Dockerfile,只需添加环境变量即可。
Forgejo Hermes技能用于Forgejo CLI的Hermes技能,只需提供一个密钥。

网络配置

第一个安全保障很明显:它有自己独立的硬件。即使Hermes执行 `rm -rf /` 命令,最坏的情况也只是我花几个小时重新搭建一下,损失不大。

下一层安全防护是网络方面的。我那台旧服务器将路由器的443端口进行了转发,而这台新服务器没有。这样就没有外部网络入口,大大减少了攻击面,也避免了来自互联网上那些对我设置的每个DNS A记录都进行试探性探测 `/wp - admin` 的干扰。

但是,如果没有网络入口,我该如何:在手机上访问所有这些酷炫的新应用呢?为自定义域名生成SSL证书,以便访问 `https://cool - new - app.internal.jakeshomelab.me` 呢?我把Tailscale配置好了,将旧服务器设为出口节点。当我不在家时,选择这个出口节点就能让我的网络流量通过那台旧服务器和Pi - hole,我用Pi - hole进行自定义DNS设置。Pi - hole允许你添加类似这样的dnsmasq规则:address=/internal.jakeshomelab.me/192.168.1.201这样,任何请求 `*.internal.jakeshomelab.me` 的域名都会解析到我的新服务器,然后Coolify的反向代理会接管并提供我那些闪亮的新服务。

SSL证书

使用Caddy或Traefik以及Docker标签,你可以将容器X的3000端口映射到 `https://my - service.internal.jakeshomelab.me`。将A记录指向服务器后,它会联系Let's Encrypt,完成ACME挑战并获取SSL证书。我三年前就学会了这个方法,现在看来还是很神奇。

问题在于A记录。无论别人能否访问,我都不想将 `my - service.internal.jakeshomelab.me` 与我的IP地址公开关联起来。我想要为一个虚拟服务获取SSL证书。

为了解决这个问题,我采用了DNS - 01方法。说实话,我对这个方法也是刚接触,但它的工作原理如下:购买一个域名(在这个例子中是从Porkbun购买的);生成Porkbun API密钥,并将其添加到Coolify的环境变量中,赋予对该域名的写入权限;修改Coolify的Docker Compose文件,使用 `lego` 和Porkbun API: - '--certificatesresolvers.letsencrypt.acme.dnschallenge=true'
- '--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=porkbun'
- '--log.level=INFO'
然后,当我注册一个新的URL时,Traefik / Coolify会:使用Porkbun API在 `_acme - challenge.my - service.internal.jakeshomelab.me` 创建一个新的TXT记录;Let's Encrypt验证挑战并颁发有效的SSL证书;Traefik删除该TXT记录。

搞定!现在你有了一个有效的HTTPS URL,只能在你的Tailscale网络内访问,而且没有指向该服务的公共A或AAAA记录。虽然主机名可能仍会出现在公共证书透明度日志中,但该服务只能从Tailscale网络访问。最棒的是,Coolify可以即时完成这些操作。我们的代理可以在任何子域名下创建服务,它会“神奇地”自动处理好一切。把这些都整合起来,你就会得到下面这样的结果:网络配置图(有点像AI生成的,抱歉!)同样的配置也适用于工具,所以Coolify、Hermes、Forgejo和Firecrawl都运行在各自的本地子域名下。

开发栈与多组件项目(MCPs)

现在我们有了一个(差不多)隔离的环境,接下来看看工具。这些工具大家都很熟悉,有趣的是如何把它们整合在一起。

Forgejo

我们需要一个可靠的地方来存储代码并运行CI。我决定不使用GitHub,原因如下:把我的GitHub令牌给这个环境会破坏隔离性,而且它也不是自托管的;它的API和CI时长限制无法满足我们新软件工厂的规模需求;最近它经常出问题。

Forgejo是一个很棒的自托管替代方案。上面链接的Docker Compose文件可以设置好Forgejo及其运行器;注册你自己和运行器需要多花点功夫,但文档很详细。我还提供了一个Compose文件,用于将项目同步回GitHub。这样会把你的GitHub令牌放在环境变量中,不过这得你自己权衡利弊。上面链接的Forgejo Hermes技能可以让代理完全控制这个实例。

Hermes

Hermes是一个类似OpenClaw的个人助理,具备自主能力。我没赶上OpenClaw的热潮,所以没法比较两者,但Hermes有一些我觉得很实用的功能:Web UI:一个类似ChatGPT的标准界面,方便我在笔记本电脑上操作和管理技能;共享文件系统:我把它的工作空间从Docker主机挂载出来,并通过Samba共享。这样代理和我可以使用相同的文件,而不用复制粘贴Markdown和代码;Telegram集成:我可以在手机上和代理聊天。设置只花了两分钟,而且不需要登录信息,很符合沙盒化的要求;自我构建技能:Hermes可以创建并注册自己的技能。我没找到合适的Coolify技能,于是它就阅读文档、查看多组件项目(MCP),然后自己构建了一个;Firecrawl:自托管的Firecrawl让代理能更好地访问搜索引擎结果页面(SERP)数据,并进行大规模的网页抓取。

把Hermes和Firecrawl配置好,把密钥放在正确的位置,真是件让人头疼的事。我已经把适合Coolify的Docker Compose文件添加到上面链接的仓库里了。Hermes为这篇博客文章构建演示网页应用的过程

Coolify

Coolify是整个系统的粘合剂:它是一个基于Docker和Compose的自托管PaaS,每次更新都有很大的进步。如果你想在自己的硬件上拥有Heroku或DigitalOcean App Platform的便利功能,我强烈推荐它。

我最喜欢的一些功能包括:底层就是Docker。现有的部署大多能正常工作,如果Coolify处理不了一些奇怪的情况,你还可以在笔记本电脑上使用 `docker exec ` 命令。只有在你需要的时候,它才会进行抽象封装;上面详细介绍过的SSL / 路由栈;Coolify自带了很多常见应用的预制模板。Postgres、Redis、Hermes、Forgejo等几乎所有应用都可以一键部署;Postgres备份到S3只需三步操作,而且内置了环境变量和用户管理功能;GitHub网络钩子(webhook)可以让你在推送到主分支时自动部署。

Coolify工具界面Firecrawl服务和Docker Compose

实际成果

下面的演示能很好地展示这一点,但最初的指令如下:请为我构建一个记录卡路里摄入的应用。它应该类似于MyFitnessPal,但要有一个表单,方便添加特定的食物和餐食,以便日后快速选择。你的任务是构建这个应用,将其提交到一个新的代码仓库并编写测试,使用CI进行测试,然后将其部署到http://calories.internal.jakeshomelab.me。我希望它是一个全栈的SvelteKit应用,数据库层使用Drizzle和Postgres。我希望使用Tailwind进行CSS样式设计,并且要以移动设备优先。部署时,请使用Docker和Docker Compose,并部署你自己的Postgres实例。从那之后,它就自动开始工作了:创建了一个新的Git仓库,并初始化了SvelteKit、Drizzle、Postgres和Tailwind;编写了应用程序和测试代码,并分阶段合理地提交了代码;创建了CI管道;解决了测试中的失败问题,直到CI通过;使用Docker Compose将应用程序和它自己的Postgres实例容器化;将整个项目部署到Coolify的指定URL。

全程无需我再给出任何指令。不用在测试失败时催促它,也不用把错误信息复制回聊天框。它一直运行,直到应用程序成功运行。那时我试用了一下,提交数据时遇到了一个跨站请求伪造(CSRF)问题。我又给了它一个指令,它诊断出问题,修复了它,添加了回归测试,并重新部署。成功了!

这就是我想要的流程:指令、仓库、代码、测试、CI、部署、修复bug。显然,这不是一个复杂的应用,但它从一段文字描述变成了经过测试、部署好的软件,并处理了中间所有繁琐的工作。这感觉还是有点像魔法。

别啰嗦了,快让我看看成果!

我不是YouTube博主,但还是给你看看吧。

关于隔离性的思考与下一步计划

在完全自主开发和安全性之间总是需要权衡。这是一个比较特殊的例子:这个应用完全在隔离环境中运行。大多数有用的软件都需要与其他软件交互,这意味着要交出API密钥,而每一个密钥都会在沙盒上开一个小孔。

即使在这个设置中,Hermes仍然可以:摧毁新服务器以及上面运行的所有东西;删除代码仓库、数据库和部署;泄露或滥用我给它的任何凭证;像为了年终考核一样疯狂消耗推理令牌;发起随机的出站请求,下载互联网上的任何垃圾内容;访问防火墙允许它访问的我网络中的其他任何东西。

所以,它并非无害。我所做的是让这台机器成为“牺牲品”,并严格限制它能触及到我在乎的东西。现在的故障模式是“重新搭建eBay上买来的这台服务器,轮换几个密钥”,而不是“发现大语言模型把我的笔记本电脑搞得一团糟”。我觉得这样好多了,但这也并非万无一失。

明显的下一步计划是:将这台服务器放在单独的VLAN中,明确禁止它访问我家庭网络的其他部分;按照服务提供商允许的最小范围设置每个凭证的权限,并定期轮换;自动化备份,让重新搭建整个服务器成为一键式操作,Coolify的数据库备份和我共享的Docker compose挂载应该能让这相对容易实现;在它进行任何真正公开或难以撤销的操作之前,要求获得批准。

不过,审批环节太多的话,这个神奇的自主软件工厂就会变成一堆你必须填写的表单。找到“每五分钟就需要我干预一次”和“拥有最高权限”之间的平衡点,将是下一个实验的内容。

人工智能 自托管 家庭实验室 Codex Coolify(C) 2020 - 2026未完成的副业项目 基于 Hugo 构建;主题 StackJimmy 设计

内容概要:本文围绕“基于需求侧响应的配电网供电能力综合评估”展开研究,重点探讨了价格型需求响应机制对配电网供电能力的影响,并提出了一套科学的综合评估方法。研究构建了一个涵盖一次设备安全、负荷平稳、电能质量和系统效率等多个维度的评价指标体系,采用熵权法客观确定各指标权重,并结合模糊综合评价模型实现双层评分机制,从而定量评估不同运行场景下配电网的承载能力。通过Python编程实现算法仿真,利用算例分析验证了所提模型在不同分布式能源渗透率及多种需求响应策略下的有效灵敏度,揭示了价格激励措施在提升电网承载力方面的积极作用,为现代配电网的规划、调度运行优化提供了理论依据和技术支撑。; 适合人群:具备一定电力系统基础知识和Python编程能力,从事电力系统规划、运行优化、需求响应等相关领域的科研人员及研究生。; 使用场景及目标:①评估高比例电动汽车、分布式电源接入背景下配电网的实际供电能力;②分析价格型需求响应策略对提升电网承载力的作用效果;③为配电网扩容改造、运行调度和需求管理政策制定提供决策支持; 阅读建议:建议读者结合文中提供的Python代码进行实证复现,重点关注熵权法模糊综合评价的实现逻辑,并尝试修改参数设置以观察评估结果的变化趋势,加深对模型机理的理解。
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 在Qt应用程序开发过程中,有时我们可能需要构建一个具备特殊视觉效果的窗口,例如设计成没有边框但带有阴影,并且依然允许用户拖动窗口。此类需求通常出现在构建简洁用户界面或定制化窗口外观的场景中。标题“Qt(部分)无边框窗口 边框阴影,可以拖动边框,移动窗口”所涵盖的技术要点主要集中于如何在Qt框架内达成这样的功能,尤其是借助winEvent函数的重写来应对特定的Windows平台事件。 让我们深入理解无边框窗口的概念。在Qt环境中,可以通过调整窗口的边框样式来构建无边框窗口。这通常是通过`setWindowFlags()`函数完成的,将`Qt::FramelessWindowHint`标志整合到窗口的标志参数里。例如: ```cpp setWindowFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint); ``` 这样一来,窗口将丧失标准的边框和标题栏,但依然维持着窗口管理的基本功能,例如最大化、最小化和关闭操作,前提是你也没有移除这些相关标志。 接下来,为了给无边框窗口增添阴影效果,可以利用Qt的QGraphicsDropShadowEffect类。首先创建一个QGraphicsView对象作为窗口的底层容器,然后在其上放置一个QGraphicsProxyWidget用以展示实际的窗口内容。接着,为QGraphicsView施加阴影效果: ```cpp QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffe...
内容概要:本文系统研究了同步电机构网型变流器在电力系统中的频率稳定特及其多时间尺度交互机理,基于Simulink搭建高保真仿真模型,深入分析两类电源在动态响应、惯量支撑、频率调节能力等方面的差异耦合关系。研究涵盖不同运行工况下的频率波动响应特,重点揭示控制延迟、电气机械动态过程之间的时间尺度耦合机制,探讨构网型变流器在高比例新能源接入背景下对传统同步机主导系统的频率稳定的影响,评估其替代或协同传统同步机的潜力挑战,为未来电力系统的稳定运行控制策略设计提供理论依据和技术支撑。; 适合人群:具备电力系统分析、自动控制理论及新能源并网技术背景的科研人员、高校研究生及电力工程技术人员;熟悉Simulink仿真环境者更佳; 使用场景及目标:①深入理解同步电机构网型变流器在频率响应特上的本质差异及其相互作用机理;②支撑高电力电子化电网的频率稳定分析新型控制器设计;③为多类型电源协同控制策略的研发仿真验证提供模型基础分析平台; 阅读建议:建议结合Simulink仿真模型进行同步操作,重点关注不同时间尺度动态过程的建模方法参数敏感分析,深入探究频率稳定的内在机理,全面把握构网型控制在提升系统稳定方面的优势潜在局限。
代码转载自:https://pan.quark.cn/s/db56051ee6da 依据所提供的文档资料,能够归纳出以下“寻求一个字符串中连续出现频率最高的子串”相关的基础知识: ### 一、问题的阐述剖析 #### 1.1 问题背景 在计算机科学领域中,字符串操作是一项普遍且关键的工作。本议题聚焦于给定字符串,识别其中连续出现频率最高的子串。 #### 1.2 问题陈述 假定存在一个输入字符串 `str`,目标在于找出该字符串中出现频率最高的一个或多个连续子串,并统计它们的出现频次。 #### 1.3 输入输出格式 - **输入**:一个字符串 `str`。 - **输出**:连续出现频率最高的子串及其对应的出现次数。 ### 二、算法的构思执行 #### 2.1 基本理念 遍历字符串的所有可能子串,并借助某种数据结构来追踪每个子串的出现频次。通过对比所有子串的出现频次,从而识别出出现频次最高的子串。 #### 2.2 具体执行步骤 1. **初始化**:设定一个字符串 `str` 来存储输入的字符串,以及一个辅助变量 `tep` 来暂存当前子串。 2. **外层循环**:从字符串长度减去1至1的逆向遍历,每次循环的 `i` 代表子串的长度。 3. **内层循环**:从0至字符串长度减去当前子串长度的遍历,每次循环的 `j` 指示子串的起始位置。 4. **子串提取**:运用 `substr` 方法从位置 `j` 开始截取长度为 `i` 的子串并存储至 `tep` 中。 5. **子串检测**:借助 `find` 和 `rfind` 方法分别确定子串在字符串中的初始出现位置 `t` 最终出现位置 `num`。 6. **判定条件**:若 `t` ...
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 在Linux操作系统平台上进行C++语言开发,达成串行通信功能是一项核心且关键的技能,特别是在嵌入式系统设计、设备管理或物联网解决方案中。此"Linux下C++实现简易串口交互"范例展示了一个基础的架构,旨在协助程序员了解怎样运用C++计算机的串行端口(COM端口)进行互动,完成数据的发送及接收任务。接下来将详尽阐述相关技术要点。 1. **串行通信原理**: 串行通信是一种历史悠久的通信机制,借助串行接口来传输信息。在Linux环境中,串行端口通常被映射为/dev/ttySx的路径,其中x代表端口的编号,例如/dev/ttyS0或/dev/ttyUSB0等。串行通信所涉及的重要参数包含波特率、数据位数、停止位数及校验类型等。 2. **C++系统接口调用**: 若要在C++中操作串口,必须借助系统级调用或第三方库。本范例可能直接运用了包含在<termios.h>头文件中的函数,比如使用tcgetattr()和tcsetattr()来配置串口特,open()和close()用于串口的开启关闭,以及write()和read()负责数据的发送接收。 3. **<termios.h>中的结构体**: struct termios结构体是控制串口行为的决定组件,它包含了串口的多种配置选项,如波特率(Baud Rate)、数据位(Data Bits)、停止位(Stop Bits)和校验位(Parity Bit)等。程序员需要通过cfsetispeed()和cfsetospeed()来设定输入和输出的波特率,而c_cflag字段则用于设定其他串口配置。 4. **串口初始化...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值