roim-picx
🖼️ 一款基于 Cloudflare 的 Worker、R2、Pages、D1 实现的免费图床应用
🌐 在线预览 •
✨ 功能特性 •
🚀 部署教程 •
📸 界面截图
📢 预览说明
[!WARNING]
在线预览地址仅作演示使用,每天有使用限额,请勿大量上传图片。
请勿将预览图床地址用于生产环境,数据会定期清理。
预览 Token: 4xVSYkCKw2ExbPNEaMPjCnaaOowU9sTf
💡 为什么选择 roim-picx?
| 特性 |
说明 |
| 💾 免费存储 |
10GB 的免费存储空间 |
| 🚀 高速访问 |
每月 300W 次不计流量的图片访问(每天 10W 次限制) |
| 📤 上传无忧 |
每月 100W 次的图片上传次数 |
| 🆓 零成本部署 |
无需购买服务器,克隆代码后部署 Cloudflare 即可使用 |
| 🔒 数据安全 |
独立部署,无需担心第三方删除数据 |
✨ 功能特性
- [√] 📦 图片批量上传
- [√] 📋 图片列表查询
- [√] 🗑️ 图片删除
- [√] 📁 目录创建
- [√] 🔍 按目录查询
- [√] 📎 链接地址点击复制
- [√] 🔐 简单的身份认证功能
- [√] 🔗 提供删除图片的访问链接
- [√] 📂 上传图片时支持选择目录
- [√] 📄 管理页面支持分页加载
- [√] ✏️ 图片重命名
- [√] 🔑 多平台登录授权[Github/Google/Steam]
- [√] ⏰ 文件过期自动删除
- [√] 🔎 文件前缀搜索
- [√] 👤 上传图片关联登录用户信息
- [√] 📊 访问统计与热度分析
- [√] 💾 D1 数据库持久化存储元数据
- [√] 🔄 历史 R2 数据一键同步到 D1
- [√] 📱 移动端自适应优化
- [√] 🖼️ 相册管理 (创建、编辑、公开/加密分享)
- [√] 📤 进阶上传 (保留原名、自定义过期时间)
- [√] 👀 我的分享管理 (查看状态、复制链接、删除)
- [√] 支持NSFW内容检测
- [√] Hugging Face 存储
- [√] 支持添加文本水印
🏗️ 技术架构
架构概览
graph TB
subgraph 用户端
A[浏览器] -->|HTTPS| B[Cloudflare CDN]
end
subgraph Cloudflare 基础设施
B --> C[Pages 静态托管]
B --> D[Pages Functions]
D -->|读写| E[(R2 对象存储)]
D -->|持久化| H[(D1 数据库)]
D -->|会话管理| F[(KV 键值存储)]
end
subgraph 第三方服务
D -->|OAuth 认证| G[GitHub API]
end
前端技术栈
| 技术 |
版本 |
说明 |
| Vue 3 |
^3.5 |
渐进式 JavaScript 框架,使用 Composition API |
| Vue Router |
^4.6 |
官方路由管理器 |
| Element Plus |
^2.13 |
基于 Vue 3 的组件库 |
| Tailwind CSS |
^4.1 |
原子化 CSS 框架 |
| Vite |
^7.3 |
下一代前端构建工具 |
| TypeScript |
^5.9 |
JavaScript 超集,提供类型安全 |
| Font Awesome |
^7.1 |
图标库 |
| Axios |
^1.13 |
HTTP 客户端 |
后端技术栈
| 技术 |
说明 |
| Cloudflare Pages |
静态网站托管平台,支持全球 CDN 加速 |
| Pages Functions |
基于 Cloudflare Workers 的 Serverless 函数 |
| Hono |
轻量级、高性能的 Web 框架,运行在 Edge Runtime |
| R2 |
S3 兼容的对象存储服务,用于存储图片文件 |
| D1 |
Cloudflare 的原生 SQL 数据库,用于存储结构化元数据和统计信息 |
| KV |
分布式键值存储,用于会话管理和元数据存储 |
项目结构
roim-picx/
├── 📁 src/ # 前端源码
│ ├── 📁 components/ # Vue 组件
│ ├── 📁 views/ # 页面视图
│ ├── 📁 utils/ # 工具函数
│ ├── 📁 plugins/ # 插件配置
│ └── 📄 App.vue # 根组件
├── 📁 functions/ # Cloudflare Pages Functions
│ └── 📁 rest/ # RESTful API 路由
│ └── 📄 [[route]].ts # 动态路由处理
├── 📁 public/ # 静态资源
├── 📁 docs/ # 文档资源
├── 📁 migrations/ # D1 数据库迁移文件
├── 📄 package.json # 项目依赖配置
├── 📄 vite.config.ts # Vite 构建配置
├── 📄 tailwind.config.js # Tailwind CSS 配置
└── 📄 tsconfig.json # TypeScript 配置
数据流程
sequenceDiagram
participant U as 用户
participant F as 前端 (Vue)
participant A as API (Hono)
participant R as R2 存储
participant D as D1 数据库
participant K as KV 存储
U->>F: 选择图片上传
F->>A: POST /rest/upload
A->>K: 验证 Token/Session
K-->>A: 验证结果
A->>R: 存储图片文件
R-->>A: 返回存储路径
A->>D: 存储图片元数据
A-->>F: 返回图片 URL
F-->>U: 显示上传结果
🚀 部署教程
1️⃣ Fork 项目
将本项目 Fork 到自己的 GitHub 账户
2️⃣ 注册 Cloudflare 并开通 R2 服务

3️⃣ 创建 Pages 项目
找到 Pages 选项并创建项目

4️⃣ 链接代码仓库
连接 GitHub 或 GitLab 并选择需要构建的项目

5️⃣ 设置环境变量

6️⃣ 绑定 R2 和 KV 服务
在项目创建后,设置项目的函数信息绑定 R2 和 KV 服务

7️⃣ 构建项目
构建项目,提示成功即可访问

[!NOTE]
Pages 的函数变量名称需要与项目的变量名称一致。
如需修改 functions 里面的 Env 命名空间,对应的文件是 [[route]].ts
8️⃣ 数据库迁移
在本地环境执行以下命令将初始表结构导入到 D1:
npx wrangler d1 execute <YOUR_DATABASE_NAME> --remote --file=./migrations/0001_init.sql
首次升级可以使用命令进行数据库初始化
```bash
wrangler d1 migrations apply <YOUR_DATABASE_NAME> --remote
在部署 Cloudflare Pages 时,需要在 Settings -> Variables and Secrets 中配置以下环境变量:
核心配置
| 变量名 |
必填 |
示例值 |
说明 |
BASE_URL |
是 |
https://picx.your-domain.com |
应用的根域名地址,用于生成完整链接 |
PICX_AUTH_TOKEN |
是 |
your-secret-token |
管理员 Token,用于管理接口认证 |
ALLOW_TOKEN_LOGIN |
否 |
true |
是否允许使用管理 Token 直接登录后台 |
STORAGE_TYPE |
否 |
R2 |
默认存储类型,可选 R2 或 HF (Hugging Face) |
GitHub OAuth 登录(可选)
| 变量名 |
必填 |
说明 |
GITHUB_CLIENT_ID |
是 |
GitHub OAuth App 的 Client ID |
GITHUB_CLIENT_SECRET |
是 |
GitHub OAuth App 的 Client Secret |
VITE_GITHUB_CLIENT_ID |
是 |
同 GITHUB_CLIENT_ID,用于前端调用 |
GITHUB_OWNER |
是 |
允许登录的 GitHub 用户名,* 表示允许所有人 |
ADMIN_USERS |
否 |
超级管理员用户名列表,逗号分隔 (例: user1,user2) |
Google & Steam 登录(可选)
| 变量名 |
必填 |
说明 |
STEAM_LOGIN_ENABLED |
否 |
是否启用 Steam 登录 (true/false) |
STEAM_API_KEY |
否 |
Steam Web API Key |
GOOGLE_LOGIN_ENABLED |
否 |
是否启用 Google 登录 (true/false) |
GOOGLE_CLIENT_ID |
否 |
Google OAuth Client ID |
GOOGLE_CLIENT_SECRET |
否 |
Google OAuth Client Secret |
Hugging Face 存储 (可选)
| 变量名 |
必填 |
说明 |
HF_TOKEN |
否 |
Hugging Face Access Token (需要有写权限) |
HF_REPO |
否 |
Hugging Face 数据集仓库名 (例: username/dataset) |
🔄 历史数据同步
如果你之前已经有一些图片存储在 R2 中但还没同步到 D1 数据库,可以使用内置的同步 API:
- 获取你的管理员 Token (
PICX_AUTH_TOKEN)。
- 调用同步接口:
curl -X POST -H "Authorization: <YOUR_ADMIN_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"limit": 100}' \
"https://your-domain.com/rest/admin/sync-r2-to-d1"
- 如果返回数据中
hasMore 为 true,请将返回的 nextCursor 放入下一次调用的 cursor 参数中:curl -X POST -H "Authorization: <YOUR_ADMIN_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"limit": 100, "cursor": "YOUR_NEXT_CURSOR_HERE"}' \
"https://your-domain.com/rest/admin/sync-r2-to-d1"
📸 界面截图

🔐 登录页面
|

📋 管理页面
|

📤 上传页面
|

📂 选择上传
|

✅ 上传结果
|

🗑️ 删除页面
|

图片分享1
|

图片分享
|

系统管理
|

相册管理
|
🔑 GitHub 登录配置
步骤说明
-
注册 GitHub 应用
前往 GitHub Developer Settings 注册一个新的 GitHub 应用
-
设置回调地址
https://your-domain.com/auth
-
获取客户端凭证
在应用中获取客户端 ID 和客户端密钥
配置截图

找到设置
|

进入开发者设置
|

创建应用
|

填写应用信息
|

设置密钥
|

获取密钥
|
🙏 致谢
本项目参考了以下优秀开源项目:
Made with ❤️ by roimdev
评论