个人项目做素材托管,最大的需求就是便宜 + 国内快 + 能放大文件。我四条路都试过,最后用腾讯云 COS + EdgeOne 私有桶把图床搭起来了
这篇文章记录完整选型、搭建步骤、免费额度和踩坑,给同样想低成本搭图床的朋友参考。
一、为什么需要图床
在"素材重命名"工作流里,图片处理完后需要一个稳定的托管位置,能生成可外链的 URL 供页面加载。核心需求四条:
| 需求 | 说明 |
|---|---|
| 低成本 / 免费优先 | 个人项目,不想月月交钱 |
| 国内访问快 | 素材主要给国内用户看 |
| 能放 500MB 级别大文件 | 不只是图片,还有视频素材 |
| 用自己已备案的域名 | 不想裸用第三方分配域名;域名托管在腾讯云 |
外加一条隐性约束:不想用 Cloudflare(域名托管在别处,迁 NS 麻烦,且国内访问不稳定)。
二、方案探索:四条路全试过
路线 1:Cloudflare Workers 图床(开源项目 CloudFlare-ImgBed)❌
在服务器空间有限的前提下,想到用 Cloudflare 的免费栈(Workers + D1 + R2)部署开源图床 CloudFlare-ImgBed。项目自带 GitHub Actions,fork 后配置 4 个 Secrets(API Token、Account ID、D1 ID、R2 桶名)即可自动部署。
踩坑 1:TOML 换行错误。 第一次部署失败,报错:
✘ [ERROR] Invalid TOML document: newlines are not allowed in strings
deploy/worker/wrangler.toml:17:51:
原因:从 GitHub Secret 复制的 D1_DATABASE_ID 末尾带了个换行,被生成脚本原样写进 TOML,语法就挂了。修复方式:给 generate-toml.js 里所有 Secrets 值加 .trim(),并在部署前对 API Token / Account ID 也去空白。这是给所有"从 Secret 复制粘贴"类问题的通用教训。
踩坑 2:D1 数据库没建表,登录报"密码不正确"。 部署成功后,第一次访问图床输入任何密码都提示"密码不正确"。排查后发现:Docker 模式启动时会自动执行 database/init.sql 建表,但 Worker 模式的 GitHub Actions 流程里根本没有这一步——D1 里 settings 表不存在,登录接口读配置直接抛 503,前端把这个错误当成了"密码错误"(其实从未设过密码)。修复:在 workflow 里加一步 wrangler d1 execute img_d1 --remote --file=database/init.sql,幂等建表。
结局:❌ 放弃。 虽然部署通了,但国内访问 workers.dev 很卡,体验无法接受。清理时发现 R2 桶非空还删不掉,必须先清空对象——顺手记一个经验:删 Cloudflare R2 桶前先清空内容。
路线 2:GitHub 当图床 ❌
思路:public 仓库存图,PicGo + jsDelivr CDN 加载。三个硬伤:
- 单文件 100MB 硬限制,500MB 视频直接拒收;Git LFS 免费额度仅 1GB 存储 + 1GB 带宽/月,几次下载就超
- 仓库必须 public,图片裸奔公开
- jsDelivr 国内访问时好时坏——对"国内用户展示"场景是致命的
路线 3:EdgeOne Pages 托管 ❌
因为已有 EdgeOne,先看它能不能白嫖。查官方文档 Limits and Quotas:
| 项 | 免费版 |
|---|---|
| 单文件最大 | 25 MB |
| 单项目文件数 | 20000 |
| 总存储 | 5 GB |
单文件 25MB 连 500MB 视频的零头都装不下。 CDN 只是加速器,不解决存储;源头放不下,加速无意义。这是"免费 + 大文件 + 国内快"三者不可兼得的第一次实锤。
路线 4:腾讯云 COS + EdgeOne(正解)✅
把已有的资产组合起来:备案域名 + 腾讯云 DNS + EdgeOne,缺的只是一个"免费能放大文件"的存储层——正好是 COS。
三、最终方案架构
用户
│ https://img.swlt.work/xxx.png(访问流量,EdgeOne 免费版不限量)
▼
EdgeOne 边缘节点(CDN 加速 + 缓存,隐藏源站)
│ 回源流量(仅缓存未命中时,0.15 元/GB)
▼
COS 存储桶(私有读写,ap-guangzhou)
三个设计要点:
- COS 桶设为私有读,图只能通过 EdgeOne 访问,无法直连 COS 原始域名 → 防爬 + 省外网流量费
- EdgeOne 开启"私有存储桶访问",让边缘节点有签权回源拉图
- DNS 精确记录覆盖泛解析:
img → CNAME → img.swlt.work.eo.dnse2.com优先于*.swlt.work泛记录,图床子域名单独走 COS 源站,主站其他子域名不受影响
四、搭建步骤
1. 创建 COS 存储桶
用腾讯云官方 CLI coscmd(pip 安装):
pip install coscmd
coscmd config -a <SecretId> -s <SecretKey> -b "imgbed-你的AppId" -r "ap-guangzhou"
coscmd createbucket
coscmd upload test.png img/test.png # 验证读写
坑:COS 桶名格式必须是 桶名-APPID,而账号的 UIN 和 APPID 不一定相等。用 GetUserAppId 接口(CAM)查到真实 AppId 后才配成功。
2. EdgeOne 绑定域名
- 已有
*.swlt.work泛域名站点(EdgeOne 免费版,流量请求均不限量) - 添加加速域名
img.swlt.work,源站类型选"对象存储源站" → 选 COS 桶 → 同意服务授权 → 开启"私有存储桶访问"
3. DNS 配置
DNSPod 一键添加:
img CNAME img.swlt.work.eo.dnse2.com
4. 验证
生成一张测试图传上去,浏览器打开 https://img.swlt.work/img/xxx.png 能显示即全链路打通。
五、免费额度与成本
COS 免费额度(官方文档)
| 项 | 免费额度 | 有效期 |
|---|---|---|
| 存储 | 个人 50GB 标准存储 | 6 个月 |
| 流量/请求 | 基础包不含;新用户活动包另有 10GB 流量/月 + 请求 | 6 个月 |
EdgeOne 免费版(官方文档)
| 项 | 免费版 |
|---|---|
| 安全加速流量 | 不限量 |
| 安全加速请求 | 不限量 |
| 有效期 | 长期有效 |
6 个月后的实际账单(估)
| 计费项 | 价格 | 每月(5GB 素材 / 20GB 访问流量) |
|---|---|---|
| COS 存储 | 0.099 元/GB/月 | ≈ 0.5 元 |
| 用户访问流量 | EdgeOne 不限量 | 0 元 |
| 回源流量 | 0.15 元/GB | ≈ 0.3 元 |
| 请求费 | 0.01 元/万次 | 几毛 |
结论:免费期内 0 元;到期后每月约 1 元量级。 50GB 免费额度能放约 100 个 500MB 素材。省钱优化:生命周期规则把 30 天无访问的图自动转低频存储(0.08 元/GB/月)。
六、踩坑总结
- GitHub Secret 复制粘贴常带换行 → 所有值先
.trim()再进 TOML/配置 - Cloudflare Worker 部署不自动建 D1 表 → 部署前显式执行
init.sql - 删 Cloudflare R2 桶前必须清空对象
- COS 桶名 = 桶名-APPID,不是 UIN → 先查 AppId
- COS 私有桶必须开 EdgeOne"私有存储桶访问",否则回源 403
- 访问务必走自定义域名,别用 COS 原始域名(外网下行 0.5 元/GB,贵)
七、后续待完善【TODO】
以下章节留给配置 PicList 的那台电脑 AI,在完成配置并实测后补充:
- [ ] PicList 配置过程:腾讯云 COS 插件安装、参数填写、设为默认图床
- [ ] 实际使用验证:拖拽上传、剪贴板上传、返回的 URL 是否为
img.swlt.work开头 - [ ] 使用体验:上传速度、国内访问速度、与"素材重命名"流程的衔接
- [ ] 成本实测:上线一个月后回填真实账单数据
感谢他们为本文做出的贡献
https://github.com/MarSeventh/CloudFlare-ImgBed
https://pages.edgeone.ai/document/limits-and-quotas