运维手记

自托管、部署与网络踩坑。一台机器怎么稳稳地跑起来。

3 threads

PinnedPinnedPrivate

给服务器配备份,但不要往机器里塞云密钥

给自托管的服务配自动备份,最容易犯、也最危险的错,是把云账号的访问密钥(AccessKey)直接写进服务器——一旦机器被入侵,攻击者拿到的就是整个云账号的钥匙。

更稳的做法是零静态密钥:给云主机挂一个实例角色(阿里云叫 ECS RAM 角色),只授权它读写某一个备份桶。服务器上不存任何 key,备份脚本靠实例元数据(metadata)动态取一份临时凭证。就算机器被拿下,攻击者的爆炸半径也只有「这一个备份桶」,碰不到云账号本身。

tt.hn 的备份就是这套:每天用 SQLite 的在线备份(.backup,能正确处理 WAL,不用停服)做一致性快照,连媒体一起打包上传对象存储(OSS);走内网 endpoint 上传,同区不产生流量费;对象存储上挂一条生命周期规则,备份保留 30 天后自动删。

这样备份既是可靠的,也没有在服务器上多留一把能捅穿整个云账号的钥匙。

给服务器配备份,但不要往机器里塞云密钥

PinnedPinnedPrivate

把这个博客部署上线,踩的三个坑

tt.hn 从零部署到阿里云的过程里,有三个坑值得记下来,都不是文档会告诉你的。

1. 运维通道:SSH 出站被挡,改走云厂商的远程命令。 从本机 SSH 到新机器一直超时,排查发现是网络出口对裸 TCP 22 端口的分流问题。绕开的办法是干脆不用 SSH——改用云厂商的远程命令能力(阿里云叫 Cloud Assistant),通过云 API 直接在实例上执行脚本,不依赖 SSH、不受源 IP 限制,反而更稳。

2. SQLite 打不开:容器里的写权限。 容器起来后数据库迁移报 SQLITE_CANTOPEN。原因是绑定挂载(bind mount)的数据目录在宿主机上是 root 属主,而容器内进程是非 root 用户(uid 1000),没有写权限。本地 Docker Desktop 不暴露这个问题,Linux 上才会。修复就一句:把数据目录 chown 给容器用户。

3. 网站打不开,但加 www 就行。 上线后裸域名访问不了,加 www 却正常。查下来真凶是本机的代理软件(Clash)按域名分流——裸域名被路由到一个不通的节点,www 走了另一条线。直连、绕过代理时两个都正常。

Continue →
把这个博客部署上线,踩的三个坑

PinnedPinnedPrivate

香港节点调用 Anthropic API 返回 403:怎么判断,怎么绕开

Anthropic 的 API 走 Cloudflare,而 Cloudflare 对香港区做了地域封锁——所有香港节点直连必然 403,响应头里能看到 cf-ray 带 HKG。

判断法:直连 403 + cf-ray 落 HKG,基本就是地域封锁,不是你的 key 或网络的问题。

绕法:在一个非封锁区起一台机器做 nginx TLS 透传代理(SNI 透传,不解密),用自签证书(IP 写进 SAN)、只放行你自己的源 IP。香港的业务机器把请求指到这台代理即可。这个坑对所有部署在香港的项目通用。

香港节点调用 Anthropic API 返回 403:怎么判断,怎么绕开