我的博客图床方案:用 CloudFlare-ImgBed 管理文章图片

我的博客图床方案:用 CloudFlare-ImgBed 管理文章图片

_

搭建个人博客之后,我很快遇到一个很现实的问题:文章里的图片到底应该放在哪里?

一开始最简单的做法当然是直接上传到博客后台,比如 Halo 本身也支持文章图片、附件、封面图这些能力。但随着文章越来越多,截图、封面、教程配图也会越来越多。如果所有图片都堆在博客服务器里,后面会带来几个问题:服务器磁盘占用越来越高,迁移博客时图片也要一起搬,文章里的图片链接还可能因为路径变化失效。

所以我最后选择把图片从博客系统里拆出来,单独做一个图床服务。目前我用的是开源项目CloudFlare-ImgBed,它的项目文档

CloudFlare-ImgBed 是什么

管理端页面

CloudFlare-ImgBed 是一个开源文件托管项目。虽然名字里带着 ImgBed,但它不只是一个简单的图片上传页面,更像是一个轻量的个人文件托管系统。

它支持 Docker 部署,也支持 Cloudflare Pages / Workers 这类无服务器部署方式。存储后端也比较灵活,可以接入 Telegram、Discord、Cloudflare R2、S3、HuggingFace、WebDAV 等不同渠道。

对个人博客来说,它最直接的作用就是:把博客文章里的图片独立托管出去,然后在文章中引用图床返回的图片链接。

这样博客系统只负责写文章、展示文章,图片资源交给图床服务管理。

为什么我需要单独的图床

我的博客主站是用 Halo 搭建的。Halo 本身当然可以上传图片,但我更希望博客主站保持轻量一点,不要把文章系统、插件、主题、图片资源全部混在一起。

拆出图床之后,整个结构会更清晰:

写文章 -> 上传图片到图床 -> 获取图片 URL -> 粘贴到 Halo 文章里

这样做有几个好处。

第一,博客服务器的压力更小。图片、截图、封面图这些静态资源不会全部塞进主站目录。

第二,后续迁移更方便。只要图床域名不变,文章里的图片链接就不会失效。

第三,图片有独立后台管理。上传、删除、目录、标签、公开图库这些操作都可以在图床后台完成,不需要全部依赖博客后台。

第四,图床可以绑定独立域名,比如 imgbed.lovexfan.com。这样图片链接看起来也更统一。

技术架构

从源码结构来看,CloudFlare-ImgBed 的整体架构可以分成三层:

前端管理界面
    ↓
API / Functions 服务层
    ↓
元数据数据库 + 文件存储后端

前端管理界面负责上传、文件列表、系统配置、公开图库等操作。这个仓库里直接包含了构建后的前端产物 frontend-dist。

服务层主要在 functions/ 目录下,采用 Cloudflare Pages Functions 风格组织接口,比如:

/upload              文件上传
/file/xxx            文件访问
/random              随机图片
/dav/                WebDAV
/api/manage/list     文件列表
/api/manage/delete   删除文件
/api/manage/sysConfig 系统配置
/api/manage/apiTokens API Token 管理

存储层则分成两部分:一部分是数据库,用来保存文件元数据和系统配置;另一部分是真正的文件存储后端。

这里有一个很重要的设计:文件本体和文件元数据是分开的。

文件本体可以存在 R2、S3、Telegram、Discord、HuggingFace 或 WebDAV 里;而数据库里保存的是文件 ID、文件名、类型、大小、上传时间、目录、标签、存储通道等信息。用户访问图片时,统一访问 /file/xxx,服务再根据元数据判断应该去哪个后端读取文件。

技术栈

这个项目主要使用 JavaScript / Node.js 生态。

从仓库配置可以看到,它使用了:

  • Node.js 22

  • Hono

  • Cloudflare Workers / Pages Functions

  • Wrangler

  • Cloudflare D1 / KV

  • Cloudflare R2

  • SQLite

  • AWS SDK S3 Client

  • WebDAV

  • Telegram Bot API

  • Discord API

  • HuggingFace API

  • Cloudflare Cache / CDN

如果部署在 Cloudflare 上,它可以使用 Cloudflare 的 D1、KV、R2、Workers Assets 这些能力。

如果使用 Docker 部署,它会通过 Node.js 和 Hono 启动一个本地服务,并模拟 Cloudflare 的运行环境。在 Docker 模式下,它用 SQLite 模拟 D1,用本地文件系统模拟 R2。仓库里的 docker-compose.yml 也很简单:

services:
  imgbed:
    image: marseventh/cloudflare-imgbed:latest
    ports:
      - "7658:8080"
    volumes:
      - ./data:/app/data
    restart: unless-stopped

这意味着 Docker 部署时,data 目录非常重要。里面会保存本地数据库和本地文件数据,迁移或备份时一定要关注这个目录。

上传流程

当我在后台上传一张图片时,大致流程是这样的:

浏览器选择图片
    ↓
POST /upload
    ↓
检查登录状态或 API Token 权限
    ↓
检查上传 IP、上传目录、文件类型等配置
    ↓
生成文件 ID 和 metadata
    ↓
根据配置选择上传通道
    ↓
上传到 R2 / S3 / Telegram / WebDAV 等后端
    ↓
把文件记录写入数据库
    ↓
返回 /file/xxx 访问链接

这套逻辑的好处是,前端和博客文章都不需要关心底层存储细节。无论图片实际存在哪里,最终给文章用的都是统一格式的访问链接。

比如我在文章里引用的可能只是:

https://imgbed.example.com/file/xxx.png

至于这个 xxx.png 实际在 R2 里,还是在 S3 里,或者在 WebDAV 后端里,对博客来说并不重要。

图片访问流程

图片访问流程也很清晰。

当浏览器访问 /file/xxx 时,服务会先解析文件 ID,然后从数据库读取对应 metadata。接着判断这个文件属于哪个存储通道,再去对应后端读取文件内容。

如果文件在 Cloudflare R2,就从 R2 读取;如果文件在 S3,就通过 S3 API 或配置好的 CDN 地址读取;如果文件在 Telegram,就通过 Telegram Bot API 获取真实文件路径;如果文件在 WebDAV,就通过 WebDAV 地址读取。

最后,服务会把文件内容返回给浏览器,并设置合适的响应头,比如 Content-Type、Cache-Control、ETag、Range 等。

这对图片和视频资源都很重要。比如视频或大文件如果支持 Range 请求,浏览器就可以分段加载,而不是一次性下载完整文件。

管理后台能力

CloudFlare-ImgBed 的后台不只是上传页面,它已经提供了一套比较完整的文件管理能力。

它支持:

  • 文件上传

  • 文件列表

  • 文件删除

  • 文件重命名

  • 目录管理

  • 标签管理

  • 公开图库

  • 随机图片

  • 系统配置

  • API Token

  • WebDAV

其中 API Token 对我来说比较实用。后续如果我要接入其他上传工具,不一定要暴露管理员账号,可以单独创建一个只允许上传的 Token。这样安全性会更好。

WebDAV 和随机图片

项目还提供了 /dav/ 路径来支持 WebDAV。WebDAV 可以理解成一种通用文件管理协议,一些客户端可以通过它像操作网盘一样操作文件。

另外还有 /random 随机图片接口。这个功能可以用来做随机背景图、随机头像、随机封面之类的效果。它支持指定目录,也支持按图片方向筛选,比如横图、竖图、方图。

这些功能对普通图床来说不一定是刚需,但说明这个项目已经不只是“上传图片然后返回链接”这么简单,而是往轻量文件管理系统方向扩展了。

使用时需要注意什么

图床很方便,但它本质上也是个人网站的基础设施,所以不能只管上传,不管维护。

首先,重要图片一定要考虑备份。不要把任何图床都理解成“免费无限永久存储”。尤其是接入第三方渠道时,要注意平台规则、容量限制和访问稳定性。

其次,不建议上传特别隐私的内容。即使后台有鉴权,文章里引用的图片链接一旦公开,就要默认它可能被别人访问到。

另外,升级前一定要看项目公告。这个项目在 v2.0、v2.6.2、v2.7.1 都有过比较重要的变化,比如 Docker 镜像结构、数据备份、Cloudflare Pages 构建输出目录等。直接无脑升级有可能踩坑。

还有一点,我本地拉仓库的时候发现它体积比较大,主要是 .git 历史和 README 素材占了不少空间。如果只是部署使用,其实没必要完整 clone 仓库,直接看官方文档、使用 Docker 镜像或者按 Cloudflare 部署说明来就够了。

总结

CloudFlare-ImgBed 对我的博客来说,解决的是图片资源独立管理的问题。

它让我的博客架构变成:

Halo 负责文章内容
图床负责图片管理
存储后端负责文件本体
CDN 负责访问加速

这样主站不会因为图片越来越多而变得臃肿,后续迁移博客时也不用担心文章里的图片全部失效。

它不是一个“免费无限存储神器”,而是一个比较完整、可控、适合个人站长使用的媒体资源管理入口。对于经常写博客、插入截图、封面图、教程配图的人来说,把图床独立出来还是很值得的。

一文理解 DDoS:流量型、协议型和应用层攻击有什么区别? 2026-06-18
我的博客可用性监控方案:用 Uptime Kuma 盯住网站状态 2026-06-20

评论区