最后更新:2026-10-17
AI / 自动化
我开始尝试让 Codex 管理自己的服务器
从最早尝试到 DNS 漂移、权限缺口与正式应用部署,补记真实运行后的判断。
这篇最初写于我刚开始让 Codex 管理个人服务器的时候。那时的判断很朴素:不要让长期配置只存在于终端历史里,把能重复的部分留进 Git。后续真实运行和变更,又让我发现“仓库里写了”和“现实中成立”之间,还有不少需要持续核对的地方。
这次更新保留了最初的起点,也补上 DNS 漂移、权限缺口、正式应用部署与密钥配置的后续经验。它们并不是一开始就设计成熟的成果,而是在实际问题出现后逐步补齐的。
从可运行的基线开始
最初,Caddy、Docker、静态页面和基础目录由 Ansible 管理,Git 保存模板、内容和操作说明。我先用临时容器验证经 HTTPS 到本机应用的路径,再清理实验资源。那时没有正式业务应用,更没有完成有状态数据的恢复。
这套起点的价值是能解释服务器:什么由仓库声明,修改前应看到什么差异,部署后怎样验证。它没有把 DNS、外部账号、私钥和应用数据都纳入管理。把仓库称为配置来源,不能顺手把它称为整个现实世界的完整副本。
DNS 漂移让我重看“验证通过”
后来出现过一次很有提醒意义的情况:页面可访问,证书可信,Ansible 重跑也没有变更,但权威 DNS 对一个主机名已经返回记录不存在。部分递归缓存仍保留旧记录,所以从熟悉的客户端打开正常,掩盖了正在出现的访问风险。
当时没有证据确认记录为什么发生变化,我没有把缓存现象写成某个确定的操作失误。域名所有者确认恢复预期记录后,再查权威与递归解析,并重新验证公网 HTTPS。恢复是后来实际观察到的,不能只凭“已经改好了”的回复记成通过。
这让我把验证看成带时间和范围的观察。Ansible 管的文件可以收敛,仓库外的 DNS 仍会变化;同一台客户端成功,也不能代表所有访问路径。详细的部署收敛含义,我留在changed=0 的那篇记录里。
Docker 运行,不代表操作者能使用
另一次问题是服务本身正常,普通登录用户却无法操作 Docker。调查把几件事分开:守护进程是否活着、受限 socket 的权限是什么、当前账户是否属于所需附加组。管理员方式可以访问,普通方式不行,证据指向的是组成员缺口。
我没有为了图省事把 socket 改成所有人可写,而是将预期账户的附加组写回 Ansible,再通过新登录会话验证。旧会话的权限可能还没更新,所以只在当前终端重复尝试并不足够。这个修复也没有扩大给其它账户的权限。
它让我更重视运行身份:进程能跑、工具能调用、预期操作者能完成动作,是三个不同观察。把它们都归进一句“Docker 正常”,会让真正的问题失去位置。
从临时实验到正式应用
后来 JiaJi 的服务正式部署。它沿用原有的 Caddy 入口与 Compose 模式:容器端口留在本机,密钥留在私有配置,镜像身份固定。验证除了容器健康,还包括普通公网客户端的鉴权拒绝,以及授权后的真实模型请求。
微信会话的启用则暴露了另一个区别:同一个服务健康,并不表示可选功能已启用。已有记录中,页面能到服务,会话端点却不可用;在明确授权并备份私有配置后,才补齐所需设置并重建同一镜像,随后在开发者工具观察到真实登录到卡片的路径。
我没有把这次成功写成所有手机端已验收,也没有公开密钥值、部署位置或资源标识。正式应用出现以后,操作约定和只读状态查看才逐步变得更具体;并没有因为多一个应用,就引入新的平台组件。
公开记录,也是运维的一部分
早期公开文章曾带出不必要的生产细节,站点里还发现了能被访问的旧页面备份。后来我把公开源文件扫描和实际页面扫描放进发布过程,旧备份移出可访问目录。内部恢复需要的精确记录,与公开文章的解释目的,需要分别满足。
这不是一劳永逸的脱敏认证。每次内容变化仍要读标题、摘要、正文与示例,再检查真正发布的页面。回滚也使用 Git,而非在公开目录里留一堆历史副本。公开信息检查的文章保留了这段具体经历。
现在我愿意交给 AI 什么
常规、可逆、已经授权的内容与配置工作,可以让 Codex 连续推进到验证和记录。遇到 DNS 的真实变更、密钥来源与授权、数据删除或可能切断访问的动作,则需要具体的人工决定。停止之前,Agent 应尽量完成调查和可审查的准备。
目前 Git 能解释配置,固定镜像和部署约定提供部分回退路径,但独立密钥备份、替代主机完整恢复和有状态数据演练仍缺证据。过去某次容器健康,也不保证此刻或下一次故障仍然正常。
实际运行这段过程以后,我得到的信心来自更清楚的边界:知道什么由工具保证,什么必须从外部观察,什么还需要人承担决定。AI 管服务器的价值,需要体现在少依赖临时记忆、出错后能追查和恢复;我还不能用这些局部成功宣布无人值守运维已经成立。