Paperclip 只能在 localhost 打开?Tailscale 私有访问与 AWS ECS 公网部署两条路
在自己机器上把 Paperclip 跑起来之后,很快会撞上同一个问题:浏览器里 localhost:3100 一切正常,换成手机、换成同一个屋子里的另一台笔记本、换成出差在外的同事,全都打不开。
这不是配错了,而是默认行为。默认启动方式只在本机回环地址上监听,别的设备根本连不到那个端口。要让别人访问,官方文档给的是两条方向完全不同的路:一条是让服务绑定到私有网络接口上,靠 Tailscale(或者 LAN / VPN)做网络层的准入;另一条是把整套东西搬到 AWS,用 ECS Fargate 跑容器、RDS 存数据、EFS 存文件、ALB 做 HTTPS 入口。
这两条路解决的不是同一个问题。第一条几乎不花钱、十分钟能通,但可访问范围严格等于你的 tailnet;第二条能给出一个真正的 HTTPS 域名,代价是一整套 AWS 资源和按月计费。下面按官方文档把两边各自的关键动作、端口和边界摆清楚,顺带说明它们共用的那个健康检查口径。
为什么 pnpm dev 起来只有本机能开
关键在于绑定的网络接口。官方文档把这件事做成了启动参数:
pnpm dev --bind tailnet
这条命令对应的推荐行为是三个环境变量同时生效:
| 变量 | 值 | 作用 |
|---|---|---|
PAPERCLIP_DEPLOYMENT_MODE | authenticated | 部署模式为需要认证 |
PAPERCLIP_DEPLOYMENT_EXPOSURE | private | 暴露面为私有 |
PAPERCLIP_BIND | tailnet | 绑定到 tailnet 接口 |
如果你想要的是更宽的私有网行为——也就是整个局域网都能连,而不限于 tailnet——换成另一个参数:
pnpm dev --bind lan
文档还提到两个遗留别名仍然可用,它们映射到的是 authenticated/private + bind=lan 这一组:
pnpm dev --authenticated-private
pnpm dev --tailscale-auth
这里值得停一下。tailnet 和 lan 的区别不是「新旧」,而是暴露范围:前者只在 Tailscale 网络上可达,后者是文档所说的「旧的宽泛私有网行为」。两个遗留别名走的是后者。所以如果你以为自己开的是 tailnet 专属访问,实际用的却是 --tailscale-auth 这个别名,那你拿到的其实是 LAN 级别的暴露面。想搞清楚这几种模式在整体设计里各自是什么位置,可以对照 三种部署模式怎么选 一起看。
拿到地址、开出去、验通不通
绑定改完,剩下三步都很机械。
第一步,在跑 Paperclip 的那台机器上拿地址:
tailscale ip -4
文档也允许直接用 Tailscale 的 MagicDNS 主机名,比如 my-macbook.tailnet.ts.net。用主机名比用 IP 稳,因为 IP 可能变。
第二步,在另一台设备上按「主机名或 IP + 端口」拼出地址:
http://<tailscale-host-or-ip>:3100
举例就是 http://my-macbook.tailnet.ts.net:3100。注意端口是 3100,这个数字在后面 AWS 那条路上还会反复出现,它是 Paperclip 服务端口。
第三步,别用「页面能不能打开」当验收标准,直接打健康检查接口:
curl http://<tailscale-host-or-ip>:3100/api/health
预期返回:
{"status":"ok"}
这一步能把「网络不通」和「应用有问题」区分开。curl 超时说明是网络层或绑定的问题,curl 有响应但页面不对,那就是应用层的事。
自定义私有主机名要单独进 allowlist
如果你不是用 IP、也不是用默认 MagicDNS 名,而是自己起了一个私有主机名来访问,需要把它显式加进允许列表:
npx paperclipai allowed-hostname my-macbook.tailnet.ts.net
这条命令对应的症状很典型:页面能加载,但一到登录或者跳转就报错。文档把它单列为排查项的第一条。原因不难理解——认证和重定向要校验请求的主机名,主机名不在名单里,跳转链路就断在那儿。
官方文档给的三条排查线索,翻译成对症的判断是这样:
| 症状 | 官方给的原因 | 对应动作 |
|---|---|---|
| 私有主机名下登录或跳转报错 | 主机名不在允许列表里 | paperclipai allowed-hostname <主机名> |
| 只有 localhost 能用,别的地址全不通 | 启动时用的是普通 pnpm dev | 改用 --bind lan 或 --bind tailnet 重启 |
| 本机能连,远程连不上 | 两台设备不在同一 Tailscale 网络,或 3100 端口不可达 | 核对 tailnet 归属与端口连通性 |
按顺序排掉这三条,私有访问这条路基本就通了。
换到公网:ECS Fargate 那条路要立哪些资源
如果你要的是一个带 HTTPS 的正式域名,而不是 tailnet 内网地址,那就是另一套工程量了。官方的 AWS 指南用的是 ECS Fargate(计算)+ RDS Postgres 17(数据库)+ EFS(持久化存储),前面挂一个 ALB 提供 HTTPS,最终结果是一个单任务的 ECS 服务。
动手前的前置条件,文档列了四项:配置好 admin 级权限 profile 的 AWS CLI v2、本地装好 Docker(构建和推镜像用)、一个你能改 DNS 的已注册域名(签证书用)、以及本地已克隆的 Paperclip 仓库。
整个指南从设置几个 shell 变量开始,其中数据库口令和认证密钥都是现场生成的:
export AWS_REGION=us-east-1
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export PAPERCLIP_DOMAIN=paperclip.example.com # your domain
export DB_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=' | head -c 32)
export AUTH_SECRET=$(openssl rand -base64 32)
之后的流程是:建 ECR 仓库 → 本地 docker build 后推镜像 → 建网络与安全组 → 建 RDS → 建 EFS 与挂载点 → 把密钥写进 Secrets Manager → 建两个 IAM 角色 → 建集群并注册任务定义 → 申请证书建 ALB → 最后 aws ecs create-service 起服务。镜像构建这一环和本地容器化是同一个思路,可以对照 Docker 部署 理解 Dockerfile 那一层在做什么。
任务定义不用手写,文档说明用仓库里的模板 docker/ecs-task-definition.json,注册前先把占位符替换掉:
sed -e "s|<ACCOUNT_ID>|$AWS_ACCOUNT_ID|g" \
-e "s|<REGION>|$AWS_REGION|g" \
-e "s|<EFS_ID>|$EFS_ID|g" \
-e "s|<DOMAIN>|$PAPERCLIP_DOMAIN|g" \
docker/ecs-task-definition.json > /tmp/paperclip-task-def.json
aws ecs register-task-definition \
--cli-input-json file:///tmp/paperclip-task-def.json
安全组才是这套部署真正的边界
如果只看一处,我会看安全组。这套 AWS 部署的访问控制不靠应用配置,而是靠四个安全组串成的链条,每一层只对上一层开放:
| 安全组 | 开放端口 | 来源 |
|---|---|---|
paperclip-alb | 443、80 | 0.0.0.0/0 |
paperclip-ecs | 3100 | 仅 ALB 安全组 |
paperclip-rds | 5432 | 仅 ECS 安全组 |
paperclip-efs | 2049(NFS) | 仅 ECS 安全组 |
这个结构的含义是:公网只能碰到 ALB;3100 端口不对外,只接受来自 ALB 的流量;数据库和 EFS 更靠内,只有 ECS 任务能连。80 端口开放的用途文档写得很明确——让 ALB 能接 HTTP 然后重定向到 HTTPS,监听器配的是 HTTP_301。
RDS 那边还有两个容易漏的点:一是自定义 VPC 不带默认 DB 子网组,必须先 create-db-subnet-group 跨两个子网建一个,否则 RDS 没地方放实例;二是实例创建时带了 --no-publicly-accessible,数据库不对公网开放。数据库这一层怎么选、内嵌还是外接,另见 内嵌 Postgres 与外接数据库。
密钥这块,文档建了五个 Secrets Manager 条目:database-url、anthropic-api-key、better-auth-secret、openai-api-key、github-token。任务执行角色被单独授予了 secretsmanager:GetSecretValue,且资源范围限定在 paperclip/* 前缀下,不是全账号放开。密钥体系的整体设计见 密钥管理与 AWS provider。
健康检查两边是同一个口径
有意思的是,私有访问那条路和 AWS 那条路验收用的是同一个端点。目标组的健康检查路径配的就是 /api/health,间隔 30 秒,健康阈值 2 次、不健康阈值 3 次。部署完成后的验证也是 curl -sf https://$PAPERCLIP_DOMAIN/api/health。
文档给的三条「健康」判据是:ECS 任务状态 RUNNING、健康状态 HEALTHY;日志里出现 plugin job coordinator started 和 plugin-loader: loadAll complete;/api/health 返回 200。第二条尤其有用——任务 RUNNING 不代表插件加载完了,日志里这两行才说明应用层真正起来了。
更新部署走的是重新构建推镜像后 --force-new-deployment,ECS 做滚动更新:起新任务、等它过健康检查、再排空旧任务。服务配置里启用了部署熔断器且开了 rollback,新任务过不了健康检查会自动回滚;要手动回滚就查上一个任务定义修订号再 update-service 指过去。
上线后第一件事:关掉公开注册
这条藏在文档靠后的位置,但优先级不低。第一个注册的用户会拿到 admin 角色,注册通道一直开着就意味着别人也能自己建账号。文档给的做法是往任务定义的环境变量里加:
{ "name": "PAPERCLIP_AUTH_DISABLE_SIGN_UP", "value": "true" }
然后 --force-new-deployment 让它生效。之后再要加人,走邀请流程(invite flow,文档标注为 v2026.416.0 加入)。顺序不能反——先关注册再自己注册,你就把自己也挡在门外了。
成本:官方给的估算区间
文档附了一张成本参考表,按公网子网、不带 NAT 的配置,总计约每月 110 美元;如果用私有子网加 NAT Gateway,约 145 美元。大头是 ECS Fargate(2 vCPU / 4 GB,7×24 运行)约 70 美元、ALB 约 22 美元、RDS db.t4g.micro 20 GB 约 15 美元;NAT Gateway 单可用区约 35 美元。EFS、Secrets Manager、CloudWatch Logs、ECR 加起来只有几美元。文档同时提到用 Fargate Spot 加非工作时段定时缩容到 0,可以降到约 60 到 85 美元。这些都是官方文档给的估算,实际账单以 AWS 计费为准。
不用的时候可以直接把服务缩到零:
aws ecs update-service --cluster paperclip \
--service paperclip-server --desired-count 0
RDS 也能停,但文档提醒它会在 7 天后自动重启,所以停机省钱这件事对数据库只是短期有效。
什么时候这两条路都不合适
先说私有访问这条。它依赖的是网络层准入,谁在 tailnet 里谁就能到达那个端口,不在里面的人一概到不了。这对个人和小团队很省事,但如果你需要给外部协作方、客户或者没法装 Tailscale 客户端的设备开访问,它就不成立。另外,--bind 系列参数出现在 pnpm dev 上下文里,文档在这一页并没有交代把它用作长期常驻服务时的进程管理、日志与自启方式。
再说 AWS 这条。指南产出的明确是「单任务 ECS 服务」,--desired-count 1,RDS 也是 --no-multi-az。也就是说这套配置不含多副本和数据库高可用;文档同样没有说明并发承载能力、单任务能跑多少 Agent,这些数字它就没给,别自己推。它还预设你有一个能改 DNS 的域名用来做 ACM 的 DNS 验证——没有域名,这条路第 9 步就走不下去。
还有几件事这两份文档都没覆盖:EFS 上那些持久化数据的备份和恢复演练(RDS 有 7 天保留期,EFS 这边没提)、跨区域容灾、以及 Tailscale 侧的 ACL 怎么配。前两条得你自己补,最后一条属于 Tailscale 自己的配置范畴,不在 Paperclip 文档的射程内。
最后一个实操提醒:拆除资源必须按逆序来。文档特意写了 EFS 挂载点删除是异步的,得轮询到一个都不剩才能删文件系统,否则 delete-file-system 会以 FileSystemInUse 失败。这种坑一般是在你想省钱清环境的时候才撞上。
延伸阅读
- 从头读起:Paperclip 是什么:一个自己不跑 Agent 的控制平面,怎么管住一整家 AI 公司
- 本专题共 40 篇,完整分组目录见专题页
- Paperclip 建第一家 AI 公司:官方六步顺序,以及每步跳过会留下什么坑
- Paperclip 的组织架构与汇报线:一棵严格无环的树,决定了任务怎么往下派
本文依据 Paperclip 官方仓库(github.com/paperclipai/paperclip,MIT 协议)的 docs/ 用户文档
与 doc/ 下的规范、运维与连接器手册整理,核对日 2026-08-17。
我们没有部署或运行过 Paperclip,因此不涉及界面外观与操作手感;
部分规范文档描述的是目标架构而非当前实现,文中已就地标注,不构成对实际行为的保证。
请以仓库最新内容为准。