EDITORIAL NOTE
不花一分钱、不用服务器,我在 Cloudflare 上搭了个免费图床
之前我一直用别人搭的免费图床,用着用着突然就抽风,图挂了还得临时换一个,烦得很。后来想开了:反正用量也不大,干脆自己搭一个,个人博客用完全够。
技术进步,最终要落到真实工作与生活
本文看点
01
第一步:Fork 项目
02
第二步:准备 Cloudflare 资源
03
第三步:绑定 D1 数据库
研究了一圈,发现 CloudFlare ImgBed 这个项目挺合适。它跑在 Cloudflare Workers 上,数据库用 D1,存储可以选 R2 或者 Telegram Bot。最关键的是:不用自己买服务器,Cloudflare 的免费额度对个人图床来说完全够用,边缘网络速度也不差。
部署方式有两种:Pages 和 Workers。Pages 更简单,Dashboard 里点几下就行;Workers 走 GitHub Actions,支持 push 到 main 自动部署,也可以手动触发。功能完全一样,我选了 Workers,主要想试试 GitHub Actions 自动部署的感觉。
01
第一步:Fork 项目
KEY INSIGHT
先去 GitHub 找到 [CloudFlare ImgBed](https://github.com/MarSeventh/CloudFlare-ImgBed),点右上角 Fork 到自己账户下,这一步没什么好说的,应该都会。
02
第二步:准备 Cloudflare 资源
KEY INSIGHT
拿 API Token
登录 Cloudflare Dashboard,点头像进「我的个人资料」→「API 令牌」→「创建令牌」,模板选「编辑 Cloudflare Workers」就行。权限、账户资源那些都是配好的,翻到底提交,把 Token 记下来,后面填 GitHub Secrets 要用。
拿 Account ID
Account ID 在 Dashboard 首页右侧的 Account Details 区域,复制下来备用。我一开始没找到,后来直接问首页的 Ask AI,它告诉我在哪。

创建 D1 数据库
数据库用来存图床的文件元数据,比如文件名、大小、上传时间。KV 和 D1 二选一,我选了 D1,免费额度比 KV 多不少。
进「存储和数据库」→「D1 SQL 数据库」→「创建数据库」,名字填 img_d1,区域选亚太地区。创建完回到概述页,把数据库 ID 复制下来,后面也要填进 Secrets。

接下来去 D1 的「控制台」选项卡,把初始化 SQL 执行一下。这段 SQL 会建 files、settings、index_operations 几个表,还有索引和触发器。
要分段输入,别一次全贴进去,容易出问题。控制台会显示每条语句的执行结果,看到「此查询已成功执行」就说明没问题。

主要的建表语句长这样,方便你对照检查:
CREATE TABLE IF NOT EXISTS files (
id TEXT PRIMARY KEY,
value TEXT,
metadata TEXT NOT NULL,
file_name TEXT,
file_type TEXT,
file_size TEXT,
upload_ip TEXT,
upload_address TEXT,
list_type TEXT,
timestamp INTEGER,
label TEXT,
directory TEXT,
channel TEXT,
channel_name TEXT,
tg_file_id TEXT,
tg_chat_id TEXT,
tg_bot_token TEXT,
is_chunked BOOLEAN DEFAULT FALSE,
tags TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
完整的 SQL 在项目的 [database/init.sql](https://github.com/MarSeventh/CloudFlare-ImgBed/blob/main/database/init.sql) 里。
踩坑提醒:如果之前建过表想重来,先把 SQL 开头几行 DROP TABLE 的注释去掉,执行一遍清掉旧表,再跑建表语句。生产环境慎用。
创建 R2 存储桶(可选)
要用 R2 存储渠道的话,进「存储和数据库」→「R2 对象存储」→「创建存储桶」,记下桶名。我暂时没用 R2,先用默认渠道跑起来再说。
03
第三步:绑定 D1 数据库
DATA CHECK
配 Secrets 之前,先把 D1 绑定到 Worker 上,不然一会部署完图床打开是白的——这是我踩过的一个坑。
进 Workers 和 Pages,找到刚创建的 Worker(默认叫 cloudflare-imgbed),点进去选「绑定」标签页。

点「添加绑定」,选 D1 数据库,变量名称填 `img_d1`(跟代码里用的一致),数据库选你刚创建的那个。

04
第四步:配置 GitHub Secrets
KEY INSIGHT
回到 fork 的仓库,进 Settings → 机密和变量 → 操作。一开始是空的,点「New repository secret」一个个加。Secrets 是加密存储的,Actions 日志里不会泄露;别用 Variables,public 仓库里所有人都能看到。

需要加的 Secrets 如下:
| Secret 名称 | 说明 | 是否必填 | |:--|:--|:--| | CLOUDFLARE_API_TOKEN | Cloudflare API Token | 必填 | | CLOUDFLARE_ACCOUNT_ID | Cloudflare Account ID | 必填 | | D1_DATABASE_ID | D1 数据库 ID | 和 KV 二选一 | | KV_NAMESPACE_ID | KV 命名空间 ID | 和 D1 二选一 | | R2_BUCKET_NAME | R2 存储桶名称 | 可选 | | WORKER_NAME | Worker 名称 | 可选,默认 cloudflare-imgbed | | WORKER_VARS | 业务环境变量(JSON) | 可选 |
说实话大部分不用在这写。存储渠道、审查策略什么的,部署完在管理面板里都能改。我一开始什么都填了,后来发现根本没必要。WORKER_VARS 只有配 Telegram Bot 这类特殊渠道才用得上,格式是 JSON:
{
"TG_BOT_TOKEN": "your-bot-token",
"TG_CHAT_ID": "your-chat-id"
}
不过真要用 Telegram 渠道,我更建议部署完在管理面板里配,比在这儿填 JSON 方便多了。
05
第五步:跑部署
KEY INSIGHT
进仓库的「操作」页面,左边选 「Deploy to Cloudflare Workers」 工作流。

点「Run workflow」,选 main 分支,开跑。

部署完成后,通过 https://<worker-name>.<account-subdomain>.workers.dev 访问。第一次可能慢一点,耐心等。
国内直连 workers.dev 可能不稳,这个后面可以单独写一篇怎么解决(Worker 优先 IP 之类)。
06
最后看看效果
KEY INSIGHT
部署完绑定好,访问 Worker 地址,就能看到图床界面了:

界面还挺好看,支持拖拽上传、点击上传、Ctrl+V 粘贴上传,底部还有文件管理和统计,默认就能用。部署完成后记得去管理面板配置存储渠道,不然图片传不上去。
07
踩坑记录
KEY INSIGHT
整个流程其实挺顺利,就几个小地方要注意:
1. D1 初始化 SQL 要分段执行:一次全贴进去可能报错,我分了几次才跑成功
2. WORKER_VARS 不用急着配:大部分业务设置管理面板都能改,别一开始就写死在 Secrets 里
3. 部署前记得绑定 D1:光配 Secrets 不够,还得在 Cloudflare 这边把数据库绑到 Worker 上,不然部署完图床是白的
08
收尾
KEY INSIGHT
折腾下来最大的感受:没花一分钱,也没碰服务器,一个能用的图床就上线了。下一步打算写一篇配置文章,把存储渠道、管理面板这些坑再填一填。
反正工具是免费的,步骤也就这五步——想自己搞个图床的,可以动手了。
写在最后
看到这儿,说明你把它读完了。这类文章能走多远,只取决于两件事:你的在看和转发。
顺手关注并设为星标,下一篇更新第一时间见。
END NOTE
保持观察
文章来源:mp.weixin.qq.com





