ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

GitHub 暂停后,给我的 3D 作品网站搬家:Cloudflare + Bunny 实操手册

GitHub 暂停后,给我的 3D 作品网站搬家:Cloudflare + Bunny 实操手册

GitHub 账号突然被暂停,好在我的网页、模型、代码和 Git 历史都在本地。这次先把作品网站恢复出来,代码托管平台以后再安排。

我的网站不是只有几张图片:封面是 Angelina,下面有 3D 展陈馆、可以拖动观看的小世界、镜头巡游和动画短片。其中一只九尾狐模型就有约 60 MiB。直接把原来的文件全部扔到新平台,并不能算迁移完成。

这篇把实际操作、踩到的地方和以后更新的办法放在一起,留给自己回看。

上线后的入口:

  • Angelina 首页
  • Working Volumes 3D 展陈馆
  • 动画短片

目录

    • 1. 网页放 Cloudflare,大模型放 Bunny
    • 2. 先看单文件限制,再决定怎么搬
    • 3. 在 Bunny 建普通文件存储
    • 4. 给模型接上 CDN 地址
    • 5. 别漏掉跨域访问设置
    • 6. 修改加载地址,保留原来的场景
    • 7. 首页也要改,不能只换一个域名
    • 8. 浏览器上传遇到的问题
    • 9. 用 Wrangler 从本地发布
    • 10. 视频这次怎么处理
    • 11. 发布后需要检查什么
    • 12. 以后更新时怎么做

1. 网页放 Cloudflare,大模型放 Bunny

这次按下面的方式分工:

放在哪里放什么
本地项目完整源码、素材原件和 Git 历史
Cloudflare:Angelina 首页名字、简介、作品入口和动画站
Cloudflare:Working Volumes3D 展陈馆、场景程序和普通资源
Bunny Storage + CDN约 60 MiB 的九尾狐 GLB 模型
原有 Bunny Stream已经托管的 4 部世界巡游影片

我开始也有一个疑问:九尾狐本来就在画面里面,模型放在 Bunny,房屋和河流放在 Cloudflare,网页还能把它们组装起来吗?

可以。访客的浏览器先下载场景程序,再根据模型地址下载九尾狐,最后把它放进同一个 Three.js 场景。模型的位置、缩放、灯光和动画由场景程序控制,跟文件放在哪家公司没有直接关系。

这次检查现有代码,九尾狐本来就是单独加载.glb后再加入场景。因此需要改的是模型访问地址,模型本身不需要重新生成,也不需要为了托管限制降低画质。

2. 先看单文件限制,再决定怎么搬

我使用的是 Cloudflare 控制台中的 Workers 静态资源入口。

官方当前列出的限制是:免费版每个 Worker 版本最多 20,000 个静态文件,单个静态文件最多 25 MiB;付费版的单文件上限也是 25 MiB。静态资源请求免费且不限次数,资源存储没有额外费用。执行服务端 Worker 程序则另有额度,不能把这两种请求混在一起看。

官方文档:

  • Workers 平台限制
  • 静态资源计费说明

我的展陈馆原来约 159 MiB。移走九尾狐这个大文件后,Cloudflare 发布目录约 99 MiB,剩下最大的单文件不到 18 MiB。

要注意:25 MiB 是单个文件限制,不是说整个网站只能有 25 MiB。把网站拆成两个站方便分别维护,但不能自动解决某个模型文件太大的问题。

3. 在 Bunny 建普通文件存储

我以前使用的是 Bunny Stream。它主要处理视频。GLB 模型这次使用 Bunny Storage,再连接 Bunny CDN。

操作入口:

  1. 登录 Bunny 控制台。
  2. 左侧点Storage。
  3. 点Add Storage Zone。
  4. 输入名称:angelina-world-assets。
  5. 使用Standard存储层,主存储区域为Frankfurt (DE)。
  6. 检查复制区域和费用,再创建。

这次页面显示的存储报价为$0.03/GB·月。按模型约 0.063 GB 估算,纯存储用量约$0.002/月,但这不是最终账单:CDN 流量另算,账户适用的最低消费也需要计入。

创建后进入File manager,通过Upload上传原始模型:

kitsune-v10-plush-CpknAwSU.glb

文件实际大小是63,076,284字节,约60.15 MiB,Bunny 页面按十进制显示约63.08 MB。

4. 给模型接上 CDN 地址

Storage 负责存文件;网站访问模型,需要一个 CDN 分发地址。

操作路径:

  1. 在刚创建的 Storage Zone 中打开Connected pull zones。
  2. 点Connect Pull Zone。
  3. 选择Add Pull Zone。
  4. 源站类型选择Storage Zone,确认对应angelina-world-assets。
  5. Pull Zone 名称同样使用angelina-world-assets。
  6. 检查 Standard Tier 的分地区流量价格后创建。

系统生成的访问域名是:

https://angelina-world-assets.b-cdn.net/

九尾狐模型的完整地址是:

https://angelina-world-assets.b-cdn.net/kitsune-v10-plush-CpknAwSU.glb

这里用的是公开 CDN 地址。Storage 的访问密码和 API Key 不能写进网页 JavaScript,也不应该放进文章或公开仓库。

5. 别漏掉跨域访问设置

网页和模型来自不同的域名。浏览器读取模型时,需要 Bunny 返回允许跨域读取的响应头。

在 Bunny 的这个 Pull Zone 中:

  1. 打开Headers。
  2. 查看Add CORS headers。
  3. 在Extension List原有内容后面追加glb。
  4. 点Save。

这次实际检查模型响应得到:

HTTP 200 Content-Type: model/gltf-binary Access-Control-Allow-Origin: *

这个模型本来就要公开展示,所以允许公开跨域读取符合用途。如果存的是私人文件,就需要另外设计访问控制,不能照抄公开模型的配置。

我还下载了一次 CDN 上的文件,与本地原件做 SHA-256 校验,结果一致。这一步能确认上传后的模型没有被改变。

6. 修改加载地址,保留原来的场景

核心改动可以用下面这个示意代码理解:

constmodelUrl="https://angelina-world-assets.b-cdn.net/kitsune-v10-plush-CpknAwSU.glb";constmodel=awaitloader.loadAsync(modelUrl);scene.add(model.scene);

实际工程继续使用原来的 GLTFLoader、Meshopt 解码器、材质、站趴动画和场景位置设置。上面只是说明“模型从哪里下载”这件事,不是拿这几行替换整套场景代码。

本地保留完整原始模型;Cloudflare 的发布目录不再包含这个 60 MiB 文件。

7. 首页也要改,不能只换一个域名

原来的封面首页除了链接 GitHub Pages,还会请求 GitHub API 获取公开仓库列表。如果只把index.html搬到 Cloudflare,页面仍然会访问失效的旧地址。

这次处理了这些地方:

  • 首页的作品入口改为新站点地址。
  • 展陈馆和动画的清单仍然从各自的manifest.json读取。
  • 去掉暂时不可用的 GitHub 仓库列表和对应请求。
  • 展陈馆增加返回 Angelina 首页的入口。
  • 跨站链接带上?lang=zh或?lang=en,让中文/英文选择跟着访问入口走。
  • 分享卡片的 canonical、Open Graph 和 Twitter 图片地址在打包时换成新域名。

两个不同域名不能直接共用同一份localStorage。所以跨站语言选择通过链接参数传递,同一站内部再使用自己的本地设置。

代码动画还做了一个观看入口调整。本次浏览器里,远程 iframe 内的画面为空,但同一个短片直接打开能够正常渲染和播放。因此,代码动画卡片直接打开独立播放器;如果从放映室进入,就展示封面和“打开播放器”链接。短片本身的程序、画面和音乐没有改动。这个调整不影响 MP4 和 Bunny Stream 视频在放映室里播放。

8. 浏览器上传遇到的问题

Cloudflare 的入口是:

Compute → Workers & Pages → Create application → Upload your static files

这次在新的 Workers 上传入口里,约 94 MB 的 ZIP 被当成一个普通静态资源,触发了 25 MiB 单文件限制。不要把这个现象套用到所有 Cloudflare 产品:Pages 的 Direct Upload 和这个 Workers 入口不是同一套上传界面。

这次浏览器自动化选择文件夹时也没有把目录内容带入,于是改用官方 Wrangler 命令行工具发布。它会按目录里的实际文件上传,不需要连接 GitHub。这个现象是本次操作中遇到的情况,不表示手动选择文件夹一定不行。

9. 用 Wrangler 从本地发布

本机已经有 Node.js。这次使用的 Wrangler 版本为4.151.3:

npx--yes wrangler@4.151.3--version

首次使用需要登录。为了这次静态网站发布,只请求账号读取、用户读取和 Workers Scripts 写入权限:

npx--yes wrangler@4.151.3 login--device--scopes account:read user:read workers_scripts:write

命令会给出设备验证网址和本次设备码。打开网址、输入设备码,检查登录账号和权限,确认后点击Authorize。设备码有效期为 5 分钟,过期后重新运行命令即可。Wrangler 还会请求保持登录的后台访问权限,后面可以在 Cloudflare 的 Connected Applications 中撤销。

这次也踩到了普通网页登录的回调问题:旧授权页与新的登录请求没有匹配,浏览器点过授权,本机仍然没有登录成功。因此使用--device,让终端等待设备授权结果,不再依赖localhost:8976的回调。最终要以wrangler whoami能正确显示账号为准。

项目里的打包脚本从三个本地目录收集发布资源:

node scripts/package-cloudflare.mjs `--museum"D:/atlas-museum"`--animations"D:/Projects/animations"

在我这台电脑上,需要先进入D:/Projects/feiyanglyy-stack.github.io再运行。其他电脑按实际目录调整。

脚本输出两个发布目录:

.cloudflare/home/ 首页和动画 .cloudflare/museum/ 3D 展陈馆

它还会生成对应的 Wrangler 配置,检查发布文件数量、单文件大小,并把九尾狐加载地址改成已经验证的 Bunny 地址。

发布命令:

npx--yes wrangler@4.151.3 deploy--config.cloudflare/working-volumes.jsonc npx--yes wrangler@4.151.3 deploy--config.cloudflare/angelina.jsonc

以命令返回的线上地址为准。不要把.git、本地配置、API Key、临时截图和检查文件一起当成网站上传。

package-cloudflare.mjs是这个项目配套准备的本地脚本,不是 Wrangler 自带的命令。如果只是发布一个已经构建好的普通静态网站,可以在项目根目录准备wrangler.jsonc:

{"name":"my-static-site","compatibility_date":"2026-10-20","assets":{"directory":"./dist"}}

把name换成自己的网站名,directory指向实际发布目录,再运行npx wrangler deploy。我这次因为有两个网站和一个外置模型,才额外准备了收集文件、修改链接和检查大小的脚本。

10. 视频这次怎么处理

核对 Bunny Stream 后,现有视频库里是 4 部世界巡游影片,它们的播放地址继续保留。

动画目录里另外有 7 部 MP4,当前仍由原来的动画站目录提供,每个文件都小于 25 MiB。它们与已有的 Bunny 巡游影片是两组内容,不能仅凭“有 Bunny 账号”就认为所有视频都已经在 Bunny。

11. 发布后需要检查什么

  • 首页能显示名字、书架、世界、影片和动画入口。
  • 首页与展陈馆之间的链接可往返。
  • 中文/英文切换以及跨站语言参数有效。
  • 九尾狐从 Bunny 加载,场景完整出现。
  • 站姿/趴卧、机位、黄昏/月夜等交互正常。
  • 已有 Bunny 视频能播放。
  • 动画站的代码短片和 MP4 能打开。
  • 浏览器没有资源 404、跨域报错或模型加载错误。

这次两个站都已经发布成功。实际检查了首页的 19 张作品卡片、两个站之间的往返、中文/英文切换,以及 Cloudflare 页面从 Bunny 加载九尾狐的完整画面。站姿/趴卧与黄昏/月夜切换正常;Bunny 的山塘街巡游影片、动画站的 EP.01 MP4 都实际播放到结尾,还验证了“Claude 的一天”的独立入口和点击播放。

这些检查针对本次迁移的入口和代表性内容,并不等于逐个重新验收所有作品的全部交互。代码仓库列表暂时没有展示;动画目录里那 7 个 MP4 仍按上面的安排保留。

12. 以后更新时怎么做

改首页或动画,就重新打包并发布angelina。改展陈馆或场景程序,就重新打包并发布working-volumes。

如果修改了九尾狐模型,建议上传一个带新文件名的版本,再更新cloudflare.config.json里的modelUrl,这样比较容易管理 CDN 缓存。原始模型继续保存在本地。

日常更新不需要每次打开浏览器重新拖文件。登录有效时,Wrangler 可以直接发布;只有登录过期或需要重新授权时才回到浏览器。

最后,本地源码和 Git 历史仍要单独备份。Cloudflare 和 Bunny 保存的是运行网站需要的文件,不能代替完整的开发资料。

最后的最后,宣传一下我搬家的网页地址:https://angelina.feiyanglyy.workers.dev/?lang=zh
里面都是我做的一些尝试,github都是开源的,当然最近suspended了,后面我申诉成功了大家可以找feiyanglyy-stack来自取,顺便帮我点一个星星,虽然不一定能申诉成功,也顺手做个广告吧。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进