备案通过后的图床重生记:把 CloudFlare-ImgBed 从 Telegram 渠道搬回境内服务器的完整复刻手册
- 1备案通过后的图床重生记:把 CloudFlare-ImgBed 从 Telegram 渠道搬回境内服务器的完整复刻手册本文
- 2全站动效补完与 anime.js 数字滚动:五项动效计划的落地、四轮实测踩坑与复刻清单
- 3全站视觉移植复刻:把 Firefly 改造成 animal-island-ui 风格的七期工程(含复刻清单与踩坑全录)
- 4导航栏 UI 改造全记录:卡片边框、悬浮胶囊、三段收拢与 PC 收拢态快捷面板(附完整复现指南)
- 5博客性能优化全记录:Lighthouse 报告拆解到帧率根因排查(A–F 六项实战)
- 6Firefly 博客实战:从零搭建任意设备可用的发布台(Vercel + GitHub API)
- 7评论区回复时表情面板被截断:一次 overflow 裁剪排查实录
- 8Firefly 博客实战:给文章页加阅读进度条与圆环百分比
- 9Firefly 博客接入友链朋友圈:从零开始的完整部署教程
- 10从零开始搭建个人图床
- 11文章中添加音乐播放器
- 12基于Firefly主题的列表封面位置改造
- 13基于rehype的博客PDF嵌入组件实现
- 14Twikoo评论系统部署踩坑记录:Vercel域名无法访问的解决之路
- 15这是我的第一篇BLOG

备案通过后的图床重生记:把 CloudFlare-ImgBed 从 Telegram 渠道搬回境内服务器的完整复刻手册
2026 年 10 月,本站的 ICP 备案(鲁ICP备2026062086号-1)下证,随后完成了一轮伤筋动骨的迁移:Cloudflare Pages → 腾讯云 EdgeOne Pages,DNS 权威从 Cloudflare 切到 EdgeOne(qeodns),博客三入口归一到 azuma.mstzuomu.space,途中顺手救活了友圈、发布台、Twikoo 评论三个子系统。
但所有变更里最凶险、坑最密的是图床。本文以图床为主线写完整复刻手册——和我处境一样的人(CloudFlare-ImgBed + Telegram 渠道 + 国内备案 + 备案后必须境内访问)照着做就能重建;其他变更在第三节顺带记录。
〇、变更总览(备案下证后都发生了什么)
| 项目 | 变更前 | 变更后 |
|---|---|---|
| 博客托管 | Cloudflare Pages | 腾讯云 EdgeOne Pages |
| DNS 权威(NS) | Cloudflare | EdgeOne qeodns(ns1/ns2.qeodns.com) |
| 主入口 | azuma.mstzuomu.space(CF 301) | azuma.mstzuomu.space(页面脚本 302) |
| 页脚备案号 | 无 | 鲁ICP备2026062086号-1(FooterConfig.html) |
| 图床 | CF-ImgBed(Telegram 渠道,CF Worker) | CF-ImgBed Docker 版自托管在轻量服务器(详见下文) |
fc / pub / twikoo | DNS 记录随 NS 迁移丢失 | 在 EO zone 补 CNAME → cname.vercel-dns.com |
| 备案载体 | — | 轻量应用服务器 Ubuntu-o66q(140.143.143.178,北京) |
一、图床为什么必须搬:四重死因
原图床是 MarSeventh/CloudFlare-ImgBed(前端为 Sanyue ImgHub),部署在 Cloudflare Worker 上,域名 tu.mstzuomu.space。备案后它在国内的每条活路都被堵死了:
- 图片本体存在 Telegram 渠道。CF-ImgBed 是「元数据存 KV/D1、本体分流到外部渠道」的架构,本站全部图片的二进制在 Telegram 频道里,靠 Bot token 经 Worker 中转。国内服务器直连 Telegram 不可能,Worker 又跑在 CF 上;
workers.dev国内 DNS 污染。实测 114DNS 与 DNSPod 对*.workers.dev均返回假 IP(冒充脸书的地址段),国内访客直连必挂;- EO 反代方案实测 522。把
tu做成 EdgeOne 加速域名、回源workers.dev:EO 海外节点回源正常,国内节点回源超时(522 Connection Timeout with Origin Server)——跨境链路被卡,等于白搭; - CF 封死子域 zone。想把
tu.mstzuomu.space单独挂回 Cloudflare(NS 委派子域):新版控制台拒绝子域名,API 报错码1116(服务器端硬限制)。而整域 NS 迁回 CF 会让博客瘫痪并与备案接入冲突,不可考虑。
结论:数据必须导出,程序必须在境内自己跑。
二、图床重建复刻手册
2.1 架构定稿
访客 → https://tu.mstzuomu.space │ Nginx(:80/:443,certbot 证书) ├─ /file/* → 磁盘静态直出(try_files,老图+新图都在这) │ 查无此文件时回退 @imgbed └─ 其余路径 → 反代 http://127.0.0.1:7658 │ imgbed 容器(Docker) 上传页 / 管理后台 / API │ 存储渠道:WebDAV ▼ rclone serve webdav(172.17.0.1:8081) ▼ /var/www/imgbed/file(真身,Nginx 同时静态托管)要点:新上传经 WebDAV 落到与静态托管同一目录,于是新老图片统一走 Nginx 静态,应用只负责上传/管理;?width= 尺寸参数会被 Nginx 无视并返回原图(博客端本就有回退兜底,显示无碍)。
2.2 数据无损导出(旧站侧)
CloudFlare-ImgBed 的「备份恢复」只导元数据不含图片二进制,别用它当迁移。可用路径:
- 管理 API 枚举 + 逐张下载(本文采用):
POST /api/auth/adminLogin,JSON{"username":"...","password":"..."},保存 HttpOnly Cookie;GET /api/manage/list?start=0&count=1000&recursive=true(或/api/manage/batch/list?limit=1000&includeValue=true)拿全量 fileId 列表;- 逐个
GET /file/<URL逐段编码的fileId>(不带width/fallback参数即为原件),按 fileId 相对路径落盘——fileId 本身含目录(如文章/1791196825739_19文章.jpg),目录结构天然保留;
- 也可在后台开启 WebDAV 后用 rclone/Cyberduck 递归下载,效果等同。
本站实测:56 个文件、45.63 MiB、零失败,JPEG/PNG/PDF 魔数头尾全量校验通过。导出目录整包留了一份本地备份(imgbed-export),确认新站稳定后再删。
注意:Windows 下 PowerShell 5.1 读 UTF-8 JSON 会按 ANSI 解码炸掉,用 pwsh 7 或 [IO.File]::ReadAllText(...,[Text.Encoding]::UTF8);curl 提交登录 JSON 建议 -d @文件(BOM 也会让 JSON 解析失败)。
2.3 服务器侧:Nginx
Ubuntu(备案载体轻量服务器,不要重装系统——备案接入资源绑着它)上:
sudo apt-get install -y nginxsudo mkdir -p /var/www/imgbed/file # 导出的目录树放进 file/ 下,对齐 /file/ URL 空间站点配置(/etc/nginx/sites-available/imgbed,核心段):
server { listen 80 default_server; listen [::]:80 default_server; server_name tu.mstzuomu.space _; root /var/www/imgbed; charset utf-8; client_max_body_size 100m;
location /file/ { add_header Cache-Control "public, max-age=31536000, immutable"; try_files $uri @imgbed; } location @imgbed { proxy_pass http://127.0.0.1:7658; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location / { proxy_pass http://127.0.0.1:7658; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}2.4 服务器侧:Docker 部署 CF-ImgBed 本体
官方提供 Docker 部署(文档 https://cfbed.sanyue.de/ 有专门章节),无需改代码。国内服务器拉 Docker Hub 会超时,必须换镜像源前缀,实测腾讯内网源 mirror.ccs.tencentyun.com 对轻量服务器可用:
services: imgbed: image: mirror.ccs.tencentyun.com/marseventh/cloudflare-imgbed:latest container_name: imgbed restart: unless-stopped ports: - "127.0.0.1:7658:8080" # 注意:应用容器内监听 8080,不是 7658! environment: - BASIC_USER=<管理员用户名> - BASIC_PASS=<管理员密码> volumes: - /opt/imgbed/data:/app/datacd /opt/imgbed && docker compose up -d两个端口坑:
- 容器日志会写
Server running at http://0.0.0.0:8080——映射写宿主机端口:8080,照抄 7658<7658>7658> 会连不上; - 首次启动可能报
duplicate column name: tags迁移警告,无害。
2.5 服务器侧:rclone WebDAV(应用的「本地磁盘」渠道)
图床程序的存储渠道选 WebDAV,指向宿主机上的 rclone:
sudo apt-get install -y rclonesystemd 单元(/etc/systemd/system/rclone-webdav.service):
[Service]User=ubuntuExecStart=/usr/bin/rclone serve webdav /var/www/imgbed/file --addr 172.17.0.1:8081 --user <dav用户名> --pass <dav密码>Restart=on-failuresudo systemctl enable --now rclone-webdav本方案最大的坑在这里:--addr 绝不能写 127.0.0.1:8081。Docker 容器里的 127.0.0.1 是容器自己,访问宿主机要走 docker0 网桥地址 172.17.0.1。绑定网桥地址后容器可达、公网不可达(配合防火墙),安全与功能兼得。症状是上传接口 500、应用日志 WebDAV upload error: fetch failed。
2.6 后台配置
浏览器访问 https://tu.mstzuomu.space/dashboard 登录(BASIC_USER/BASIC_PASS):
- 系统设置 → 上传设置 → 上传渠道管理:添加渠道,类型 WebDAV,基础地址
http://172.17.0.1:8081,填 dav 账号密码;启用该渠道; - 顺手关掉默认开启的
R2_env渠道开关(Docker 版会把上传塞进容器内/app/data/r2,Nginx 静态层看不见,表现为「上传成功但外网 0 字节」); - 安全设置 → 管理端认证可改用户名/密码——注意改密码时除了新密码还有**「确认密码」框**,漏填会静默保存失败(接口表现:旧密码仍可登录)。改完记得同步
docker-compose.yml的BASIC_*环境变量并docker compose up -d。
2.7 HTTPS 与防火墙
sudo apt-get install -y certbot python3-certbot-nginxsudo certbot --nginx -d tu.mstzuomu.space -n --redirect --agree-tos --register-unsafely-without-email轻量应用服务器控制台的防火墙默认只开了 22/80/ICMP,443 需要手动「添加规则」放行 TCP 443,否则证书和 Nginx 都就绪、外网 443 依然不通。certbot 会重排 Nginx 配置,用 IP 直连 <80>80> 可能从此 404,属正常现象,管理走域名即可。
2.8 DNS 与验收
EdgeOne zone(NS 已在 EO)里给 tu 加 A 记录 → 服务器公网 IP。验收清单:
-
https://tu.mstzuomu.space/出上传页; - 老图片原 URL(
/file/目录/文件名)200 且字节数与导出一致; -
http://自动 301 到 https; - 后台拖图上传 → 返回
/file/链接 → 外网可访问 → 服务器磁盘/var/www/imgbed/file能看到该文件; -
/dashboard用新账号登录成功。
自托管后 Docker、rclone、Nginx 均已 enable 开机自启,certbot 走 systemd timer 自动续签。
三、顺带的其他变更记录
3.1 备案号页脚
src/config/FooterConfig.html(Firefly 主题专用页脚注入文件)挂 ICP 号。规则:广东备案挂主体号,非广东挂服务备案号(本站为山东,挂 -1 后缀的服务号),链接到 https://beian.miit.gov.cn/。公安备案号下证后在同文件解注释补挂(去 beian.mps.gov.cn 复制官方 HTML)。
3.2 博客三入口统一到 azuma
Layout.astro 头部有一段 is:inline 跳转脚本,白名单只匹配 www.mstzuomu.space 与根域 mstzuomu.space,302 到 azuma 并保留路径/查询串。两轮收紧的教训:
- 第一版判断「非 azuma 就跳」——
localhost预览也被跳走,改为线上域名匹配; - 第二版用正则匹配所有
*.mstzuomu.space——误伤tu(若某域名返回了含博客脚本的 HTML)。最终白名单化。
另:siteConfig.ts 的 site_url 已同步为 https://azuma.mstzuomu.space(canonical/sitemap 基址)。
平台侧还埋过一颗雷:曾按「所有域名统一 301」的思路在 EO zone 建过边缘函数规则(匹配全部 Host)。EO 的规则只对 zone 加速域名生效、对 EO Pages 域名(www/azuma/根域)不生效——所以博客没事,但后加的 zone 加速域名 tu 被规则误 301 到博客。已删除该规则。复刻时若只要页面级跳转,别在 zone 上留「匹配全部」的边缘函数。
3.3 fc / pub / twikoo 的复活
三个子域在 NS 切换时 DNS 记录丢失,均为 Vercel 项目,在 EO zone 各补一条 CNAME → cname.vercel-dns.com 即复活:
| 子域 | Vercel 项目 | 用途 |
|---|---|---|
fc.mstzuomu.space | friend-circle-lite | 友圈数据站(CORS 头在项目 vercel.json) |
pub.mstzuomu.space | fireflypriweb-publisher | 发布台 |
twikoo.mstzuomu.space | twikoo-api | Twikoo 评论后端 |
博客端评论开关在 src/config/commentConfig.ts(type: "twikoo",envId 指向自有域名)。
3.4 服务器与备案的绑定关系
轻量服务器是 ICP 备案的接入资源(备案单上的云资源 IP),也是本次图床的宿主机。不要释放/退订它——备案接入悬空有被注销风险。网站本体跑在 EdgeOne Pages 上属于常见实践,但服务器必须保持在网。
3.5 DNSPod 控制台的「未生效」提示
域名 NS 在 EdgeOne 的 qeodns 上,不在 DNSPod。腾讯云「云解析 DNS(DNSPod)」控制台提示「未设置正确的 DNS 服务器」是跨产品的正常现象,无视即可,解析记录都在 EO 站点的「域名服务 → DNS 记录」里管理。
四、写给复刻者的最短路径
- 旧站:后台开 WebDAV 或走管理 API,把图片按 fileId 目录树拉到本地,魔数校验,留备份;
- 服务器:装 Nginx(
/file/静态 + 其余反代 <7658>7658>)→ Docker 拉镜像(记得国内源前缀、容器端口 8080)→ rclone WebDAV 绑172.17.0.1→ 后台配 WebDAV 渠道、关 R2_env; - certbot 签证书 + 控制台防火墙放行 443;
- DNS 加 A 记录,跑第 2.8 节验收清单;
- 全绿之后,旧的 Cloudflare Worker 图床留观两周再退役。
数据无价,迁移有路。祝各位同行一次跑通。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!




