PocketChest 部署教程:Cloudflare 搭一个「取件码」式临时文件分享站

摘要
PocketChest 用 Workers + D1 + R2 搭免注册文件分享站:6 位取件码、200GB 分片上传、自动过期与可选 TOTP。含建库建桶、部署与排错。
PocketChest 部署教程:Cloudflare 搭一个「取件码」式临时文件分享站
给朋友传个 4GB 的镜像包,网盘要登录、要装客户端、还限速;微信传不上去;一次性网盘又怕文件躺在别人服务器上。PocketChest 的思路很直白——上传后给你一个 6 位取件码,像快递柜一样,对方拿到码就能取,到期自动销毁。
仓库地址:Hzao/PocketChest(MIT)。完整部署细节以仓库的 DEPLOYMENT.md 为准,本文是把它读薄后的实操版。

一、它是什么,为什么值得自建
一个 chest(文件包)就是你一次上传的一批文件和文本,服务端给你一个 ABC123 这样的 6 位码。核心能力:
免注册:没有账号体系,上传即用
大文件:走 R2 分片上传,单个文件最大 200GB
自动过期:1 / 3 / 7 / 15 天可选,也可以设永久
可选 TOTP:开启后只有持验证码的人能上传,适合团队内部用
每小时自动清理:定时任务删除过期会话、24 小时以上的未完成上传,以及对应的 R2 对象
架构上前后端分离:
层 | 技术 | 部署位置 |
|---|---|---|
后端 | Cloudflare Worker + D1 + R2 | Workers |
前端 | Next.js 14 + Tailwind | Cloudflare Pages |
语言 | TypeScript | — |
二、前置条件
Cloudflare 账号(免费层可用),并且有一个托管在 Cloudflare 的域名
本机装好 Wrangler CLI:
Node.js 环境(跑 npm 与脚本)
三、第一步:拉代码、填两份配置模板
官方把配置做成了模板,先复制出来(wrangler.jsonc 与 .env.local 都不该进 Git):
四、第二步:建 D1 与 R2 并回填配置
把 d1 create 输出的 database_id 填进 pocket-chest-backend/wrangler.jsonc:
R2 绑定默认就对,除非你换了桶名:
binding字段名必须保持DB和R2_STORAGE,改名代码就找不到资源了。
然后初始化表结构:
五、第三步:生成本地能跑起来的环境
后端:
前端另开一个终端:
前端通过 .env.local 里的 NEXT_PUBLIC_API_URL 找后端。本地调试时把它指向 http://localhost:8787 即可。先在这里把上传 → 取件跑通,再去部署,能省掉一半排错时间。
六、第四步:配置密钥与 TOTP
1. 用官方脚本生成密钥
脚本会输出 JWT_SECRET 以及每个用户的 otpauth:// 链接,后者直接扫进 1Password / Google Authenticator 就行。
2. 决定要不要开 TOTP
在 pocket-chest-backend/wrangler.jsonc 里控制:
团队内部用 →
"true",只有持码的人能上传公开分享用 →
"false",任何人拿到前端地址就能上传
3. 写入 Cloudflare Secrets
密钥绝不能写进 wrangler.jsonc 的 vars 段:
被问「是否创建同名 Worker 并写入密钥」时选 Y。
⚠️ Worker 的 Secret 是加密且不可回读的。以后要加 TOTP 用户,最省事的做法是重新生成全部用户的密钥,再整体
wrangler secret put TOTP_SECRETS,然后让每个人重新录入——比手工拼接旧密钥靠谱。
七、第五步:部署后端 Worker
清理用的 Cron 任务写在 wrangler.jsonc 里,会跟着一起部署,不用手动配。
绑自定义域名(国内访问必需)
默认的 *.workers.dev 在国内打不开,所以自定义域名不是可选项。直接在 wrangler.jsonc 里写路由:
三个容易踩的点:
不要提前手工加 DNS 记录,Cloudflare 部署时会自己创建
用三级域名(
api.yourdomain.com)才能自动签发 SSL;四级及以上(api.pc.yourdomain.com)拿不到证书workers_dev: false可以关掉 workers.dev 域名,生产环境建议关
八、第六步:部署前端到 Cloudflare Pages
先把 .env.local 里的后端地址改成真实地址:
然后构建并部署:
--project-name是全局唯一的,太大众的名字会撞车,加个前缀更稳。也可以用 Git 集成方式接入,参考官方 Pages Git 集成文档。
最后到 Cloudflare Dashboard → Pages → 你的项目 → Custom domains 给前端也绑上域名,等证书签发完成(通常几分钟)。
九、验证
打开前端域名,点 Start Sharing(开了 TOTP 会先弹验证框)
传一个小文件,拿到 6 位取件码
换一个浏览器/无痕窗口,用取件码取回,确认能下载
传一个大于 100MB 的文件,确认分片上传没断(这是 R2 分片路径,最值得单独验一次)
十、常见问题排查
现象 | 可能原因 | 处理 |
|---|---|---|
上传报跨域错误 | 后端 | 检查后端 CORS 配置 |
接口报数据库错误 | D1 没绑定或 binding 名不对 | 确认 |
上传/下载失败 | R2 桶不存在或 binding 名不对 | 桶要在,且 |
TOTP 一直验证不过 | 密钥格式不对或手机时间不同步 | 检查 secret 是否完整粘贴,校准设备时间 |
国内访问不了 | 用的还是 | 绑三级自定义域名 |
想加人但看不到旧密钥 | Secret 不可回读 | 重新生成全部用户的 TOTP 密钥后整体覆盖 |
表不存在 | 没跑 schema 初始化 | 重跑 |
日常排错命令:
十一、免费额度与适用边界
资源 | 免费层 | 说明 |
|---|---|---|
D1 | 10 万读 / 5 万写 / 天 | 只有元数据,个人用量绰绰有余 |
R2 | 前 10GB 存储免费 | 之后约 $0.015/GB/月,出站流量免费 |
Workers | 10 万请求 / 天 | 之后约 $0.5/百万 |
Pages | 静态请求不限 | 函数调用 2 万次/月 |
它适合做「带过期的临时中转站」,不适合当长期网盘。 大文件分发也别指望它长期扛流量——过期时间设短一点,既安全也省钱。
写在最后
PocketChest 最聪明的地方是去掉了账号体系:没有注册、没有密码、没有找回,只有一个取件码和一条过期时间。这在「传完就完」的场景里,比任何网盘都干净。
自建它的真正理由不是省那点会员费,而是——文件始终躺在你自己的 R2 桶里,到期那一刻是真的被删掉,而不是「服务商说会删」。
