release: v1.2.1 — login captcha, docs site, and bug fixes
Add slider captcha for web login, VitePress documentation on GitHub Pages, and fixes for gallery delete refresh, pagination jump, and copy-format persistence.
This commit is contained in:
1 parent
469d3be735
commit
ff20f97522
66 files changed
+2497
-616
No files matched your search
@@ -0,0 +1,99 @@
|
||||
# API
|
||||
|
||||
PicHost 提供 REST 接口与 Twikoo 兼容端点。部署后登录 **API** 页可查看当前 Token 与可复制 cURL 示例。
|
||||
|
||||
## 鉴权
|
||||
|
||||
所有 REST 接口使用请求头:
|
||||
|
||||
```http
|
||||
Auth-Token: YOUR_TOKEN
|
||||
```
|
||||
|
||||
| Token 类型 | 获取方式 | 说明 |
|
||||
| ---------- | -------- | ---- |
|
||||
| **全局 Token** | 管理员 **API** 页生成;或 `API_UPLOAD_TOKEN` 环境变量 | 环境变量优先且锁定后台重新生成 |
|
||||
| **个人 Token** | 各用户 **API** 页 | 仅用于该用户脚本,上传归属本人 |
|
||||
|
||||
表单上传仍可使用字段 `token`(Twikoo 协议)。
|
||||
|
||||
## 接口列表
|
||||
|
||||
### 1. 上传图片
|
||||
|
||||
`POST /api/images/upload`
|
||||
|
||||
上传单张或多张图片。字段 `image` 传图片;仍兼容 `file`、`files`。存入 `images/`。
|
||||
|
||||
```bash
|
||||
curl -X POST "https://admin.example.com/api/images/upload" \
|
||||
-H "Auth-Token: YOUR_TOKEN" \
|
||||
-F "image=@./demo.png"
|
||||
```
|
||||
|
||||
### 2. 获取图片列表
|
||||
|
||||
`GET /api/images`
|
||||
|
||||
分页列出图库。`limit` 默认 20、最大 100。
|
||||
|
||||
```bash
|
||||
curl "https://admin.example.com/api/images?limit=20&page=1" \
|
||||
-H "Auth-Token: YOUR_TOKEN"
|
||||
```
|
||||
|
||||
### 3. 搜索图片
|
||||
|
||||
`GET /api/images/search`
|
||||
|
||||
按文件名或路径关键词搜索,参数 `q` 必填。
|
||||
|
||||
```bash
|
||||
curl "https://admin.example.com/api/images/search?q=demo&limit=20&page=1" \
|
||||
-H "Auth-Token: YOUR_TOKEN"
|
||||
```
|
||||
|
||||
### 4. 删除图片
|
||||
|
||||
`DELETE /api/images`
|
||||
|
||||
通过 `key` 删除单张,`key` 为存储路径(如 `images/2026/08/xxx.webp`)。
|
||||
|
||||
```bash
|
||||
curl -X DELETE "https://admin.example.com/api/images?key=images/2026/08/xxxx.webp" \
|
||||
-H "Auth-Token: YOUR_TOKEN"
|
||||
```
|
||||
|
||||
### 5. 批量删除
|
||||
|
||||
`POST /api/images/batch-delete`
|
||||
|
||||
请求体 JSON:`{"keys":["images/2026/08/a.webp","images/2026/08/b.webp"]}`
|
||||
|
||||
```bash
|
||||
curl -X POST "https://admin.example.com/api/images/batch-delete" \
|
||||
-H "Auth-Token: YOUR_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"keys":["images/2026/08/a.webp","images/2026/08/b.webp"]}'
|
||||
```
|
||||
|
||||
## 错误格式
|
||||
|
||||
REST 接口返回 JSON,含 `code` 与 `message`(如 `UNAUTHORIZED`、`FORBIDDEN`、`INVALID_REQUEST`)。Twikoo 端点使用 EasyImage 兼容 JSON 格式。
|
||||
|
||||
## 权限与可见范围
|
||||
|
||||
- 普通用户 Token:列表/搜索/删除仅作用于自己的图片
|
||||
- 管理员 Token:可访问全部图片
|
||||
- 全局 Token 上传的图片归属管理员
|
||||
|
||||
详见 [用户与权限](./users-and-permissions.md)。
|
||||
|
||||
## Twikoo
|
||||
|
||||
`POST /api/index.php` 见 [Twikoo](./twikoo.md)。
|
||||
|
||||
## 相关
|
||||
|
||||
- [环境变量](./configuration.md) — `API_UPLOAD_TOKEN`
|
||||
- [反向代理](./reverse-proxy.md) — 公网 URL 与 HTTPS
|
||||
@@ -0,0 +1,101 @@
|
||||
# 环境变量
|
||||
|
||||
PicHost 支持通过环境变量(Docker / `.env`)与后台 **设置** 页配置。多数项 **SQLite 优先**;部分项环境变量可覆盖或锁定后台编辑。
|
||||
|
||||
## 优先级总览
|
||||
|
||||
| 配置项 | 优先级(高 → 低) | 环境变量覆盖后台 |
|
||||
| ------ | ----------------- | ---------------- |
|
||||
| API 上传 Token | 环境变量 → SQLite | **是**(设了则后台无法重新生成) |
|
||||
| WebP 质量 | SQLite → 环境变量 → 默认 80 | 否(未在 DB 存时读 env) |
|
||||
| 防盗链白名单 | SQLite → 环境变量 | 否 |
|
||||
| 网站 / 图片域名 | SQLite → 环境变量 → 当前请求 | 否 |
|
||||
| 隐藏 `images/` 前缀 | SQLite → 环境变量 → 默认 false | 否 |
|
||||
| 按年/月分组存储 | SQLite → 环境变量 → 默认 true | 否 |
|
||||
| 全局自动删除天数 | SQLite → 环境变量 → 默认 0 | 否 |
|
||||
|
||||
## 变量说明
|
||||
|
||||
### `API_UPLOAD_TOKEN`
|
||||
|
||||
外部脚本上传 Token(Twikoo / 油猴 / 博客)。请求头:`Auth-Token: <token>`;表单上传仍可用 `token` 字段。
|
||||
|
||||
- 未配置时可在后台 **API** 页生成
|
||||
- **环境变量一旦设置,优先级最高**,后台显示「由环境变量覆盖」且无法重新生成
|
||||
- 别名:`NUXT_API_UPLOAD_TOKEN`
|
||||
|
||||
### `ALLOWED_REFERER_HOSTS`
|
||||
|
||||
防盗链白名单,逗号分隔域名。自身域名自动放行。可选;不填可在设置页配置。若环境变量有值且 SQLite 未存,则使用环境变量。
|
||||
|
||||
### `SITE_BASE_URL` / `IMAGE_BASE_URL`
|
||||
|
||||
- **网站域名**:管理后台、API、Twikoo 上传入口
|
||||
- **图片域名**:复制链接与直链使用的公网地址
|
||||
|
||||
双域名分离需两者主机名不同,详见 [双域名分离](./domain-separation.md)。填写后须与反代 `server_name` 一致;**勿**通过 `localhost`、IP 或未配置的域名访问生产后台。
|
||||
|
||||
### `HIDE_FOLDER_IN_URL`
|
||||
|
||||
`true` 时直链隐藏 `images/` 前缀(如 `images/2026/08/a.webp` → `/2026/08/a.webp` 或仅文件名,取决于路径模式)。
|
||||
|
||||
### `STORAGE_USE_DATE_PATH` / `STORAGE_LAYOUT`
|
||||
|
||||
- `STORAGE_USE_DATE_PATH=true`(默认)或 `STORAGE_LAYOUT=date`:新图保存为 `images/年/月/随机ID.webp`
|
||||
- `false` 或 `STORAGE_LAYOUT=flat`:保存为 `images/随机ID.webp`
|
||||
|
||||
也可在设置页切换。
|
||||
|
||||
### `DATA_DIR`
|
||||
|
||||
图片与 SQLite 根目录。默认 `./data`,容器内为 `/data`。
|
||||
|
||||
### `WEBP_QUALITY`
|
||||
|
||||
服务端 WebP 压缩质量 1–100,默认 **80**。
|
||||
|
||||
### `AUTO_DELETE_DAYS`
|
||||
|
||||
全局自动删除超过 N 天的图片,`0` 表示关闭。启用后仅影响**之后新上传**的图片(与按用户策略一致)。也可在设置页配置。
|
||||
|
||||
### `DEV_BYPASS_ACCESS`
|
||||
|
||||
仅本地开发:`true` 绕过登录验证。生产环境勿用。
|
||||
|
||||
### 存储后端(可选)
|
||||
|
||||
管理员通常在 **存储** 页添加后端;也可用环境变量引导(如 `STORAGE_BACKEND=s3` 与 `S3_*`)。详见 [存储](./storage.md)。
|
||||
|
||||
## Docker Compose 示例
|
||||
|
||||
```yaml
|
||||
services:
|
||||
pichost:
|
||||
image: muxui/pichost:latest
|
||||
ports:
|
||||
- "6892:6892"
|
||||
volumes:
|
||||
- ./data:/data
|
||||
environment:
|
||||
SITE_BASE_URL: https://admin.example.com
|
||||
IMAGE_BASE_URL: https://pic.example.com
|
||||
API_UPLOAD_TOKEN: your-secret-token
|
||||
WEBP_QUALITY: "85"
|
||||
```
|
||||
|
||||
修改环境变量后需 **重启容器** 才能生效(Token、质量等读取在启动时或请求时按实现读取)。
|
||||
|
||||
## 与后台设置对照
|
||||
|
||||
| 后台设置项 | 对应环境变量 |
|
||||
| ---------- | ------------ |
|
||||
| API Token | `API_UPLOAD_TOKEN` |
|
||||
| 防盗链 | `ALLOWED_REFERER_HOSTS` |
|
||||
| 网站域名 | `SITE_BASE_URL` |
|
||||
| 图片域名 | `IMAGE_BASE_URL` |
|
||||
| 隐藏目录前缀 | `HIDE_FOLDER_IN_URL` |
|
||||
| 按年/月分组 | `STORAGE_USE_DATE_PATH` / `STORAGE_LAYOUT` |
|
||||
| WebP 质量 | `WEBP_QUALITY` |
|
||||
| 自动删除 | `AUTO_DELETE_DAYS` |
|
||||
|
||||
完整模板见仓库根目录 [`.env.example`](https://github.com/O96u/PicHost/blob/main/.env.example)。
|
||||
@@ -0,0 +1,172 @@
|
||||
# 双域名分离 · 推荐部署架构
|
||||
|
||||
启用「后台与图片域名分离」后,管理后台、API 与图片直链使用不同域名。PicHost 通过 **Host 中间件** 双向隔离:
|
||||
|
||||
- **网站域**:后台、API、上传;**禁止**直链出图(图片路径返回 404)
|
||||
- **图片域**:仅放行图片路径;其余请求返回 404
|
||||
|
||||
## 架构说明
|
||||
|
||||
**单 Docker 实例 + 两个域名**,均可 **全量反代** 到 `6892`(隔离由 PicHost 中间件负责,无需在 Nginx 层拆分路径)。
|
||||
|
||||
| 域名 | 用途 |
|
||||
| ---- | ---- |
|
||||
| `admin.example.com` | 管理后台、API、Twikoo 上传 |
|
||||
| `pic.example.com` | 图片直链(中间件拦截非图片路径) |
|
||||
|
||||
初始化时在 `/setup` 或后台 **设置** 中填写:
|
||||
|
||||
- **网站域名**:`https://admin.example.com`
|
||||
- **图片域名**:`https://pic.example.com`
|
||||
|
||||
## Nginx 示例
|
||||
|
||||
```nginx
|
||||
# admin.example.com — 后台 + API(不出图,直链请走图片域)
|
||||
server {
|
||||
server_name admin.example.com;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:6892;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
client_max_body_size 12m;
|
||||
}
|
||||
}
|
||||
|
||||
# pic.example.com — 同样全量反代;PicHost 中间件会拦截非图片路径
|
||||
server {
|
||||
server_name pic.example.com;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:6892;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
|
||||
# 默认 server:拒绝裸 IP、未配置域名等其它 Host(生产环境强烈建议)
|
||||
server {
|
||||
listen 443 ssl default_server;
|
||||
listen 80 default_server;
|
||||
server_name _;
|
||||
return 444;
|
||||
}
|
||||
```
|
||||
|
||||
> Caddy、NPM(Nginx Proxy Manager)等工具同理:两个域名均反代到 `http://<主机>:6892`,并保留 `Host` 与 `X-Forwarded-Proto` 头。
|
||||
|
||||
## 安全与注意事项
|
||||
|
||||
### 中间件只隔离「已配置的两个域名」
|
||||
|
||||
PicHost 根据请求 **Host**(反代会转发为 `X-Forwarded-Host`,应用会一并识别)判断当前是网站域还是图片域:
|
||||
|
||||
- **图片域**:非图片路径(如 `/`、`/settings`)→ 404
|
||||
- **网站域**:图片直链路径(如 `/images/...`)→ 404
|
||||
|
||||
若 Host **既不是网站域也不是图片域**(例如 `localhost`、服务器 **公网 IP**、Cloudflare **Pages** 的 `*.pages.dev`、**Workers** 的 `*.workers.dev`、或其它未在设置里填写的域名),**当前版本不会拦截**,后台与 API 仍可能被访问。这与域名是否带 `-`、长短无关,而是多了一条未纳入双域名配置的入口。
|
||||
|
||||
**生产环境建议:**
|
||||
|
||||
1. 反代层仅为网站域、图片域配置 `server_name`,并增加 **default server** 拒绝其它 Host 与裸 IP(见上方 Nginx 示例)
|
||||
2. 使用 Cloudflare **橙云** 时,源站防火墙 **仅放行 [Cloudflare IP 段](https://www.cloudflare.com/ips/)**,避免绕过 CDN 直连源站
|
||||
3. **仅使用** 设置中的网站域名登录后台,不要用 `localhost`、IP 或未配置的域名混用
|
||||
4. **不要** 用 Cloudflare Pages / Workers 对 PicHost **整站反代**(会多出 `pages.dev` / `workers.dev` 等第三入口,且易出现上述绕过)
|
||||
5. PicHost **不能** 作为 Node 应用直接部署到 Pages/Workers(依赖 `node-server`、SQLite、`sharp` 与本地 `data/`);应用请继续 Docker/VPS 部署,CF 侧用橙云 DNS + 可选 R2 存储即可
|
||||
|
||||
### Cloudflare 橙云(含 DNS 优选)
|
||||
|
||||
**推荐架构:** `admin.example.com` 与 `pic.example.com` 均 **DNS Proxied(橙云)** → 源站 Nginx / 1Panel 反代 `6892`,SSL 模式 **Full (strict)**(源站可用 Cloudflare Origin Certificate)。
|
||||
|
||||
| 能力 | 说明 |
|
||||
| ---- | ---- |
|
||||
| 橙云 CDN | 与 PicHost 双域名兼容;回源须保留 `Host`、`X-Forwarded-Proto` |
|
||||
| DNS 优选 | 仅改变用户连到 CF 边缘的 IP,Host 仍为正式域名,无额外配置 |
|
||||
| R2 对象存储 | 在 **存储** 页添加 R2 后端即可,与是否橙云无关 |
|
||||
| `cloudflare` Git 分支 | R2 专用部署线,仍是 Docker 运行,**不是** Workers 托管 |
|
||||
|
||||
**勿混淆:** CF 控制台「创建 Worker」并连接本仓库 **无法** 直接部署 PicHost;`npm run build` + `wrangler deploy` 与当前 `node-server` 预设不兼容。
|
||||
|
||||
反代与源站加固详见 [反向代理](./reverse-proxy.md#cloudflare-橙云)。
|
||||
|
||||
## 飞牛 NAS · Lucky 反向代理
|
||||
|
||||
在 [Lucky](https://github.com/gdy666/lucky) 中为两个域名各建一条 **反向代理** 规则,**前端地址** 填公网域名,**后端地址** 填 PicHost 所在内网 IP 与端口(如 `http://192.168.8.3:6892`)。
|
||||
|
||||
**网站域名(管理后台)**
|
||||
|
||||
| 项 | 示例值 |
|
||||
| -- | ------ |
|
||||
| 服务类型 | 反向代理 |
|
||||
| 前端地址 | `admin.pichost.com` |
|
||||
| 后端地址 | `http://192.168.8.3:6892` |
|
||||
|
||||
**图片域名**
|
||||
|
||||
| 项 | 示例值 |
|
||||
| -- | ------ |
|
||||
| 服务类型 | 反向代理 |
|
||||
| 前端地址 | `image.pichost.com` |
|
||||
| 后端地址 | `http://192.168.8.3:6892` |
|
||||
|
||||
两条规则的后端地址相同即可;域名分离与路径隔离由 PicHost 根据请求 `Host` 自动处理。
|
||||
|
||||
## 环境变量(可选)
|
||||
|
||||
除 Web 设置外,也可在 `.env` 或 Docker 环境中配置:
|
||||
|
||||
```env
|
||||
SITE_BASE_URL=https://admin.example.com
|
||||
IMAGE_BASE_URL=https://pic.example.com
|
||||
```
|
||||
|
||||
详见 [环境变量](./configuration.md)。
|
||||
|
||||
## 本地测试(Windows / macOS)
|
||||
|
||||
### 1. 修改 hosts
|
||||
|
||||
```text
|
||||
127.0.0.1 admin.pichost.test
|
||||
127.0.0.1 pic.pichost.test
|
||||
```
|
||||
|
||||
建议使用 `.test` 后缀,避免 `.local` 在部分系统上与 mDNS 冲突。
|
||||
|
||||
### 2. 启动开发服务
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
项目已默认绑定 `127.0.0.1:3000`(与 hosts 的 IPv4 一致)。若曾出现 `ping` 通但浏览器连不上,多半是 dev 只监听了 IPv6 `::1`。
|
||||
|
||||
### 3. 填写双域名
|
||||
|
||||
| 项 | 示例 |
|
||||
| -- | ---- |
|
||||
| 网站域名 | `http://admin.pichost.test:3000` |
|
||||
| 图片域名 | `http://pic.pichost.test:3000` |
|
||||
|
||||
**后台请始终用网站域名打开**,不要用 `localhost`(Cookie 与 Host 不一致)。
|
||||
|
||||
### 4. 预期结果
|
||||
|
||||
| 地址 | 预期 |
|
||||
| ---- | ---- |
|
||||
| `http://admin.pichost.test:3000/` | 正常进入后台 |
|
||||
| `http://admin.pichost.test:3000/images/...` 或 `/2026/08/xxx.webp` | **404**(请用图片域直链) |
|
||||
| `http://pic.pichost.test:3000/` | **404**(正常,图片域不提供后台) |
|
||||
| `http://pic.pichost.test:3000/images/...` | 能出图 |
|
||||
| `http://localhost:3000/` 或 `http://127.0.0.1:3000/` | **能打开后台**(第三 Host,隔离不生效;仅开发可接受,生产须用反代封禁) |
|
||||
|
||||
上传一张图后,复制链接应指向 `pic.pichost.test` 域名;在后台图库中缩略图也应能正常显示。
|
||||
|
||||
## 相关说明
|
||||
|
||||
- 两个域名 **主机名不能相同**(可同机、不同子域)
|
||||
- 设置里的网站域 / 图片域须与反代 `server_name` **完全一致**(含是否带 `www`)
|
||||
- 图片域无需单独部署静态目录;与 EasyImages 等不同,PicHost 在应用内完成隔离
|
||||
- 单域名部署可不启用分离,仅配置 `IMAGE_BASE_URL` 或使用默认当前访问域名
|
||||
- 配置了 Referer 防盗链时,网站域与图片域会自动加入白名单,无需手写两个域名
|
||||
|
||||
单域名反代要点见 [反向代理](./reverse-proxy.md)。英文版:[Dual-domain separation](/en/guide/domain-separation)
|
||||
@@ -0,0 +1,65 @@
|
||||
# 常见问题
|
||||
|
||||
## 忘记管理员密码怎么办?
|
||||
|
||||
能执行 `docker exec` 时:
|
||||
|
||||
```bash
|
||||
docker exec pichost reset-password
|
||||
# 或指定用户名
|
||||
docker exec pichost reset-password 用户名
|
||||
```
|
||||
|
||||
本地:`npm run reset-password`。详见 [快速开始](./getting-started.md#忘记密码)。
|
||||
|
||||
## 为什么后台无法重新生成 API Token?
|
||||
|
||||
若设置了环境变量 `API_UPLOAD_TOKEN`,Token 由环境变量 **锁定**,需修改 env 并 **重启服务**。见 [环境变量](./configuration.md#api-upload-token)。
|
||||
|
||||
## 图片外链显示「盗链」或无法加载?
|
||||
|
||||
检查 **防盗链白名单**(`ALLOWED_REFERER_HOSTS` 或设置页)。引用图片的站点域名需在白名单中;PicHost 自身域名与双域名场景下的网站域、图片域会自动放行。
|
||||
|
||||
## 双域名下为什么用 pages.dev / workers.dev / IP 也能进后台?
|
||||
|
||||
PicHost 双域名隔离**只对已配置的网站域、图片域做路径分流**;其它 Host(`localhost`、公网 IP、Cloudflare Pages 的 `*.pages.dev`、Workers 的 `*.workers.dev` 等)**当前不会拦截**,因此可能出现「奇怪地址也能开后台」。
|
||||
|
||||
常见原因:在橙云之外又用 **Pages/Workers 整站反代** 到源站,或源站未限制 `server_name` / 允许裸 IP 访问。
|
||||
|
||||
处理:仅用正式两个域名访问;反代加 default server;橙云时源站只放行 CF IP。详见 [双域名分离 · 安全与注意事项](./domain-separation.md#安全与注意事项)。
|
||||
|
||||
## 能把 PicHost 部署到 Cloudflare Workers / Pages 吗?
|
||||
|
||||
**不能(现状)。** 项目使用 `node-server`、SQLite、`sharp` 与本地 `data/`,需 Docker / VPS。CF 控制台「从 Git 创建 Worker」连本仓库会部署失败。
|
||||
|
||||
推荐:源站跑 PicHost,CF 用 **橙云 DNS**(含优选)+ 可选 **R2 存储**;不要用 Pages/Workers 反代整站。
|
||||
|
||||
## 双域名下后台能打开但缩略图裂图?
|
||||
|
||||
- 确认 **图片域名** 配置正确且反代到同一实例
|
||||
- 后台请用 **网站域名** 打开,不要用 `localhost` 混用
|
||||
- 见 [双域名分离](./domain-separation.md)
|
||||
|
||||
## 升级 v1.2 后图库有删不掉的记录?
|
||||
|
||||
可能是 **孤儿索引**(有记录无文件)。重启后启动同步会自动清理;也可手动删除仅索引项。见 [v1.2 迁移](./migration.md#第二步启动时自动同步索引)。
|
||||
|
||||
## 遗留 `data/blog/` 目录还要吗?
|
||||
|
||||
执行 `migrate --apply` 后文件已迁入 `data/images/blog/`。若原目录只剩空壳或非图片文件,可自行备份后删除;迁移脚本不会删除仍含非图片文件的目录。
|
||||
|
||||
## 只用对象存储需要跑 migrate 吗?
|
||||
|
||||
不需要。图片在桶内时跳过 CLI;启动同步主要面向本地 `data/images/` 磁盘扫描。
|
||||
|
||||
## 如何替换博客里的旧图片 URL?
|
||||
|
||||
使用 `data/mapping.json`(`migrate` 预览时生成)批量替换旧 key。注意映射的是 **存储 key**,不是完整旧站 URL。见 [迁移指南](./migration.md#外链与直链)。
|
||||
|
||||
## 开发时如何跳过登录?
|
||||
|
||||
`DEV_BYPASS_ACCESS=true`(仅本地,勿用于生产)。正常流程请访问 `/setup` 创建管理员。
|
||||
|
||||
## 文档与仓库 README 哪个为准?
|
||||
|
||||
**本 VitePress 文档站** 为完整用户指南;README 保留摘要与快速开始。在线地址:<https://o96u.github.io/PicHost/>
|
||||
@@ -0,0 +1,75 @@
|
||||
# 快速开始
|
||||
|
||||
PicHost 适合在 NAS、家用服务器或 VPS 上自托管图床。推荐用 Docker 部署,首次访问通过 Web 向导创建管理员。
|
||||
|
||||
## 在线体验
|
||||
|
||||
| 分支 | 说明 |
|
||||
| ---- | ---- |
|
||||
| **main** | 无公网演示;产品界面见 [文档首页](./index.md#截图预览) 或仓库 README |
|
||||
| **cloudflare** | R2 专用线在线演示:[pic.roven.cc](https://pic.roven.cc) |
|
||||
|
||||
## Docker(推荐)
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name pichost \
|
||||
-p 6892:6892 \
|
||||
-v ./data:/data \
|
||||
--restart unless-stopped \
|
||||
muxui/pichost:latest
|
||||
```
|
||||
|
||||
默认端口 **6892**。浏览器打开 `http://<主机IP>:6892`,按引导创建管理员即可。
|
||||
|
||||
已克隆仓库时也可用:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
见仓库内 `docker-compose.yml`。
|
||||
|
||||
## 首次设置
|
||||
|
||||
1. 访问实例 URL(Docker 默认 `http://<主机>:6892`)。
|
||||
2. 在 `/setup` 填写管理员用户名与密码。
|
||||
3. (可选)配置网站域名、图片域名、防盗链等 — 详见 [环境变量](./configuration.md) 与 [双域名分离](./domain-separation.md)。
|
||||
4. 登录后可在首页上传图片;管理员可进入 **存储**、**设置**、**API** 页。
|
||||
|
||||
## 登录
|
||||
|
||||
访问上传、统计、设置等管理页面前需登录。在登录卡片中填写用户名与密码,**拖动滑块对齐缺口**完成验证后点击 **登录**。
|
||||
|
||||

|
||||
|
||||
若管理员开启了开放注册,可前往注册页创建账号。遗留部署仍可能使用密钥登录(见界面提示)。
|
||||
|
||||
## 忘记密码
|
||||
|
||||
需能执行 `docker exec`(相当于服务器权限):
|
||||
|
||||
```bash
|
||||
# 无参数:重置管理员(仅当系统中只有一个管理员时)
|
||||
docker exec pichost reset-password
|
||||
|
||||
# 指定用户名:可重置管理员或普通用户
|
||||
docker exec pichost reset-password 用户名
|
||||
```
|
||||
|
||||
终端会打印随机新密码;用户不存在时会报错。登录后请到「修改密码」更换。
|
||||
|
||||
本地开发:`npm run reset-password` 或 `npm run reset-password -- 用户名`
|
||||
|
||||
## 升级到 v1.2.0
|
||||
|
||||
若 `data/` 下存在与 `images` 并列的遗留目录(如 `blog/`、`twikoo/`),升级前请阅读 [v1.2 迁移指南](./migration.md)。
|
||||
|
||||
仅对象存储、或图片已在 `data/images/` 下时,拉取新镜像并重启即可。
|
||||
|
||||
## 下一步
|
||||
|
||||
- [本地开发](./local-dev.md) — `npm run dev` 与 `.env`
|
||||
- [环境变量](./configuration.md) — 生产配置
|
||||
- [存储](./storage.md) — 多后端与直链
|
||||
- [API](./api.md) — Token 与 REST 接口
|
||||
@@ -0,0 +1,39 @@
|
||||
# PicHost 文档
|
||||
|
||||
欢迎使用 PicHost 用户文档。本站为完整指南的单一事实来源;仓库 README 保留特性摘要与快速开始。
|
||||
|
||||
## 推荐阅读顺序
|
||||
|
||||
1. [快速开始](./getting-started.md) — Docker 部署与首次设置
|
||||
2. [环境变量](./configuration.md) — 生产环境配置与后台设置对照
|
||||
3. [存储](./storage.md) — 多后端与直链模式
|
||||
4. [API](./api.md) — REST 接口与 Token
|
||||
|
||||
## 截图预览
|
||||
|
||||
**main** 分支暂无公网演示,以下为 v1.2.0 产品界面。
|
||||
|
||||
| 首次设置 | 登录 |
|
||||
| :------: | :--: |
|
||||
|  |  |
|
||||
|
||||
| API | 统计与图库 |
|
||||
| :-: | :--------: |
|
||||
|  |  |
|
||||
|
||||
| 存储管理 | 系统设置 |
|
||||
| :------: | :------: |
|
||||
|  |  |
|
||||
|
||||
| 操作日志 |
|
||||
| :------: |
|
||||
|  |
|
||||
|
||||
## 分支说明
|
||||
|
||||
| 分支 | 说明 |
|
||||
| ---- | ---- |
|
||||
| [**main**](https://github.com/O96u/PicHost/tree/main) | 主线:多后端、双域名、统一 `images/` 存储;界面见上表 |
|
||||
| [**cloudflare**](https://github.com/O96u/PicHost/tree/cloudflare) | 仅 Cloudflare R2;在线演示 [pic.roven.cc](https://pic.roven.cc) |
|
||||
|
||||
需要多种云存储或完整管理界面请用 **main**;图床只接 R2 可选用 **cloudflare** 分支。
|
||||
@@ -0,0 +1,54 @@
|
||||
# 本地开发
|
||||
|
||||
在仓库根目录进行 Nuxt 4 全栈开发,数据默认写入 `./data`。
|
||||
|
||||
## 环境要求
|
||||
|
||||
- Node.js **22**
|
||||
- npm **11**(与 `package.json` 中 `packageManager` 一致)
|
||||
|
||||
## 启动
|
||||
|
||||
```bash
|
||||
npm install
|
||||
cp .env.example .env # 可选
|
||||
npm run dev
|
||||
```
|
||||
|
||||
访问 `http://localhost:3000/setup` 创建管理员。数据目录默认 `./data`(`DATA_DIR` 可改)。
|
||||
|
||||
## 常用命令
|
||||
|
||||
| 命令 | 说明 |
|
||||
| ---- | ---- |
|
||||
| `npm run dev` | 开发服务器 |
|
||||
| `npm run build` | 生产构建 |
|
||||
| `npm run start` | 运行 `.output` |
|
||||
| `npm run lint` | ESLint |
|
||||
| `npm run typecheck` | 类型检查 |
|
||||
| `npm test` | 单元测试 |
|
||||
| `npm run reset-password` | 重置密码(可选用户名) |
|
||||
| `npm run migrate` | 预览遗留目录迁移(加 `-- --apply` 执行) |
|
||||
|
||||
## 开发专用环境变量
|
||||
|
||||
| 变量 | 说明 |
|
||||
| ---- | ---- |
|
||||
| `DEV_BYPASS_ACCESS` | 设为 `true` 可绕过登录(跳过 `/setup`,一般无需开启) |
|
||||
| `DATA_DIR` | 数据目录,默认 `./data` |
|
||||
|
||||
完整变量列表见 [环境变量](./configuration.md)。
|
||||
|
||||
## 双域名本地测试
|
||||
|
||||
修改系统 `hosts` 后可用两个测试域名验证分离逻辑,步骤见 [双域名分离](./domain-separation.md#本地测试-windows-macos)。
|
||||
|
||||
## 文档站
|
||||
|
||||
```bash
|
||||
npm run docs:dev # VitePress 开发
|
||||
npm run docs:build # 构建静态站点
|
||||
npm run docs:preview # 预览构建结果
|
||||
```
|
||||
|
||||
文档源码在 `docs-site/`;截图源文件在 `docs/screenshots/`(含 `login.png` 登录页),构建前会复制到 `docs-site/public/screenshots/`。
|
||||
@@ -0,0 +1,178 @@
|
||||
# v1.2.0 本地磁盘迁移指南
|
||||
|
||||
v1.2.0 起,**所有本地图片文件**统一放在 `data/images/` 下;SQLite `images` 表中的 `key` 也以 `images/` 开头。旧版在 `data/blog/`、`data/twikoo/` 等与 `images` **并列的顶层目录**不再符合新模型。
|
||||
|
||||
迁移分 **两步**:先用手动 CLI **搬文件**,再由服务 **启动时自动同步索引**。
|
||||
|
||||
---
|
||||
|
||||
## 从其它图床迁入(EasyImage / 兰空 / Chevereto 等)
|
||||
|
||||
**没有**单独的「一键从外链拉取」或「对接某某图床 API」工具。从 **PicHost 旧版** 或其它自托管图床迁入,走的是同一套 **本地文件迁移**:
|
||||
|
||||
1. 在旧图床服务器上找到图片**物理目录**(整目录拷贝,不要只拷数据库)。
|
||||
2. 把该目录放到 PicHost 的 `data/` 下,作为与 `images` **并列的顶层文件夹**(文件夹名任意,会保留为 `images/{文件夹名}/...`)。
|
||||
3. 执行 `migrate` / `migrate --apply`,再重启 PicHost。
|
||||
|
||||
### 常见来源示例
|
||||
|
||||
| 来源 | 典型图片目录(在旧服务器上) | 放入 PicHost 后示例 |
|
||||
| ---- | ---------------------------- | ------------------- |
|
||||
| PicHost v1.1.x | `data/blog/`、`data/twikoo/` | 已在 `data/` 下,直接 `migrate` |
|
||||
| EasyImage / EasyImages | `i/` 或安装目录下的 `upload/` | 拷到 `data/easyimage/` 再 `migrate` |
|
||||
| 兰空图床 (Lsky) | `public/uploads/` 等 | 拷到 `data/lsky/` 再 `migrate` |
|
||||
| Chevereto 等 | `images/` 或 `content/` | 拷到 `data/chevereto/` 再 `migrate` |
|
||||
| 任意自定义目录 | 你的顶层文件夹名 | 拷到 `data/你的目录名/` 再 `migrate` |
|
||||
|
||||
脚本会扫描 `data/` 下**除 `images` 外所有顶层目录**里的图片,不限于 `blog` / `twikoo`。子目录结构会原样保留在 `images/{顶层名}/` 下。
|
||||
|
||||
### 操作示例(Docker)
|
||||
|
||||
```bash
|
||||
# 在宿主机:把从旧图床打包的目录放进挂载卷(名称自定)
|
||||
# 例如:./data/easyimage/2026/01/photo.jpg
|
||||
|
||||
docker exec pichost migrate # 预览
|
||||
docker exec pichost migrate --apply
|
||||
# 重启容器 → 启动日志会补全 SQLite 索引
|
||||
```
|
||||
|
||||
### 说明与限制
|
||||
|
||||
- **只迁移文件**:旧图床的账号、Token、外链 URL **不会**自动导入;`mapping.json` 里的 key 是「旧磁盘相对 key → 新 key」,**不是**旧站完整 URL,替换外链需自行对照。
|
||||
- **对象存储**:若旧图床图片在 S3/R2 桶里,请用桶工具同步到本地 `data/某目录/`,或直接在 PicHost **存储**页配置同一桶(不经过本 CLI)。
|
||||
- **已直接在 `data/images/` 下**:无需 `migrate`,重启后启动同步会自动建索引。
|
||||
|
||||
---
|
||||
|
||||
## 存储结构对比
|
||||
|
||||
### 迁移前(v1.1.x 常见)
|
||||
|
||||
```
|
||||
/data
|
||||
├── pichost.db
|
||||
├── blog/
|
||||
│ └── 2026/08/TeKJ2fD6cB6j.webp
|
||||
├── twikoo/
|
||||
│ └── xxx.webp
|
||||
└── images/ # 可能已有部分新图
|
||||
└── ...
|
||||
```
|
||||
|
||||
SQLite 中 `key` 可能是 `blog/2026/08/TeKJ2fD6cB6j.webp`(与磁盘顶层目录一致)。
|
||||
|
||||
### 迁移后(v1.2.0)
|
||||
|
||||
```
|
||||
/data
|
||||
├── pichost.db
|
||||
├── mapping.json # CLI 生成:旧 key → 新 key(供替换外链)
|
||||
└── images/
|
||||
├── blog/
|
||||
│ └── 2026/08/TeKJ2fD6cB6j.webp
|
||||
├── twikoo/
|
||||
│ └── xxx.webp
|
||||
└── ... # 新上传:images/随机ID.webp 或 images/年/月/随机ID.webp
|
||||
```
|
||||
|
||||
对应 `key`:`images/blog/2026/08/TeKJ2fD6cB6j.webp`。
|
||||
|
||||
---
|
||||
|
||||
## 第一步:CLI 迁移磁盘文件
|
||||
|
||||
在 **升级镜像之前或之后**均可执行;建议在升级前完成,并先备份整个 `data/` 目录。
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# 预览:列出待迁移文件,写入 data/mapping.json(旧 key → 新 key)
|
||||
docker exec pichost migrate
|
||||
|
||||
# 确认无误后执行文件移动
|
||||
docker exec pichost migrate --apply
|
||||
```
|
||||
|
||||
### 本地开发
|
||||
|
||||
```bash
|
||||
npm run migrate # 预览
|
||||
npm run migrate -- --apply # 执行
|
||||
```
|
||||
|
||||
### 脚本行为
|
||||
|
||||
| 项目 | 说明 |
|
||||
| ---- | ---- |
|
||||
| 扫描范围 | `data/` 下**除 `images` 外所有顶层目录**(不限于 blog/twikoo) |
|
||||
| 迁移目标 | `data/images/{原顶层目录名}/{相对路径}` |
|
||||
| 图片类型 | `.jpg` `.jpeg` `.png` `.webp` `.gif` `.svg` `.ico` |
|
||||
| 伴随文件 | 若存在同名的 `.meta.json` 会一并移动 |
|
||||
| 非图片文件 | 不移动;若目录内仍有其它文件,**保留原目录**不删除 |
|
||||
| 映射表 | `data/mapping.json`,例如 `"blog/foo.webp": "images/blog/foo.webp"` |
|
||||
|
||||
脚本路径:`server/cli/migrate-to-single-images.mjs`。
|
||||
|
||||
---
|
||||
|
||||
## 第二步:启动时自动同步索引
|
||||
|
||||
每次 PicHost 启动(`npm run dev`、Docker 容器启动)会自动执行,**无需手动命令**。日志示例:
|
||||
|
||||
```text
|
||||
[INFO] 开始同步图片索引:扫描本地磁盘 {"path":".../data/images/"}
|
||||
[INFO] 磁盘扫描完成:已补全缺失索引 {"inserted":3}
|
||||
[INFO] 开始归一化遗留图片路径(如 blog/ → images/blog/)
|
||||
[INFO] 遗留路径归一化完成:无需调整
|
||||
[INFO] 开始校验索引与磁盘一致性,清理无文件的孤儿记录
|
||||
[INFO] 孤儿索引清理完成:未发现孤儿记录
|
||||
[INFO] 开始修复存量 Content-Type 元数据
|
||||
[INFO] Content-Type 修复完成:无需修复
|
||||
[INFO] 图片索引同步结束
|
||||
```
|
||||
|
||||
| 步骤 | 作用 |
|
||||
| ---- | ---- |
|
||||
| 扫描 `data/images/` | 磁盘上有、索引里没有 → **补全** `images` 表 |
|
||||
| 归一化遗留 key | 将 `blog/...` 等旧 key 更新为 `images/blog/...`(文件已在正确路径时) |
|
||||
| 清理孤儿索引 | 索引里有记录、磁盘无文件 → **删除**幽灵记录(避免图库出现删不掉的项) |
|
||||
| 修复 Content-Type | 修正错误的 `application/octet-stream` |
|
||||
|
||||
CLI 只负责**搬文件**;索引对齐、遗留 key、孤儿记录由启动同步处理。执行 `migrate --apply` 后**重启一次**服务即可。
|
||||
|
||||
---
|
||||
|
||||
## 推荐升级流程
|
||||
|
||||
1. **备份** `data/`(含 `pichost.db` 与各目录)。
|
||||
2. `docker exec pichost migrate` 预览,检查输出与 `mapping.json`。
|
||||
3. `docker exec pichost migrate --apply` 执行迁移。
|
||||
4. 拉取 / 部署 **v1.2.0** 镜像并重启容器。
|
||||
5. 查看启动日志,确认「图片索引同步结束」无报错。
|
||||
6. 用 `mapping.json` 批量替换博客、Twikoo 等外链中的旧路径(若需要)。
|
||||
|
||||
仅使用对象存储、或图片早已全部在 `data/images/` 下时,**跳过第一步**;第二步仍会在启动时运行,通常几秒内完成且无变更日志。
|
||||
|
||||
---
|
||||
|
||||
## 外链与直链
|
||||
|
||||
| 场景 | 说明 |
|
||||
| ---- | ---- |
|
||||
| 旧 key | `blog/TeKJ2fD6cB6j.webp` |
|
||||
| 新 key | `images/blog/TeKJ2fD6cB6j.webp` |
|
||||
| 隐藏目录模式 | 若开启「隐藏 images 前缀」,短链可能为 `/TeKJ2fD6cB6j.webp`;服务按文件名反查索引 |
|
||||
| 替换建议 | 以 `mapping.json` 为准;或重新在图库复制新链接 |
|
||||
|
||||
---
|
||||
|
||||
## 相关命令
|
||||
|
||||
| 命令 | 说明 |
|
||||
| ---- | ---- |
|
||||
| `docker exec pichost migrate` | 预览磁盘迁移 |
|
||||
| `docker exec pichost migrate --apply` | 执行磁盘迁移 |
|
||||
| `docker exec pichost reset-password` | 重置密码(与迁移无关) |
|
||||
|
||||
英文版:[v1.2 migration guide](/en/guide/migration)
|
||||
@@ -0,0 +1,85 @@
|
||||
# 反向代理
|
||||
|
||||
生产环境建议通过 Nginx、Caddy、NPM(Nginx Proxy Manager)或 NAS 自带反代,将 HTTPS 流量转发到 PicHost 容器 **6892** 端口。
|
||||
|
||||
## 基本要求
|
||||
|
||||
- 反代目标:`http://127.0.0.1:6892`(或容器所在主机 IP)
|
||||
- 保留请求头:`Host`、`X-Forwarded-Proto`(及常见的 `X-Forwarded-For`)
|
||||
- 上传大小:Nginx 建议 `client_max_body_size 12m` 或更大
|
||||
- 公网访问请配置 **HTTPS**
|
||||
|
||||
## 单域名示例(Nginx)
|
||||
|
||||
管理、API、出图同一域名:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name pic.example.com;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:6892;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
client_max_body_size 12m;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
环境变量(可选):
|
||||
|
||||
```env
|
||||
IMAGE_BASE_URL=https://pic.example.com
|
||||
```
|
||||
|
||||
未设置 `IMAGE_BASE_URL` 时,PicHost 会根据反代转发的 `Host` 与 `X-Forwarded-Proto` 推断公网地址。
|
||||
|
||||
## 双域名
|
||||
|
||||
若后台与图片使用不同域名,两个 `server` 块均可 **全量反代** 到同一端口;隔离由 PicHost 中间件完成。
|
||||
|
||||
详见专章:[双域名分离](./domain-separation.md)。
|
||||
|
||||
## Cloudflare 橙云
|
||||
|
||||
PicHost 应用运行在 **自有服务器 / Docker**(端口 `6892`),Cloudflare 侧推荐:
|
||||
|
||||
| 做法 | 说明 |
|
||||
| ---- | ---- |
|
||||
| **DNS 橙云** | `admin` / `pic` 两个子域 Proxied → 源站反代 `6892`,SSL **Full (strict)** |
|
||||
| **DNS 优选** | 与 PicHost 兼容;Host 仍为正式域名 |
|
||||
| **R2** | 在存储页作对象后端,非 Pages 托管应用 |
|
||||
| **源站防火墙** | 仅放行 [Cloudflare IP](https://www.cloudflare.com/ips/),禁止公网直连 `6892` |
|
||||
|
||||
**不建议:**
|
||||
|
||||
- 用 **Cloudflare Pages**(`*.pages.dev`)或 **Workers**(`*.workers.dev`)对 PicHost **整站反代** — 会多出第三 Host,且可能绕过双域名隔离(见 [双域名分离 · 安全与注意事项](./domain-separation.md#安全与注意事项))
|
||||
- 在 CF 控制台「从 Git 创建 Worker」部署本仓库 — 当前为 `node-server` 预设,无法直接 `wrangler deploy`
|
||||
|
||||
## 源站安全(双域名推荐)
|
||||
|
||||
除 PicHost 中间件外,建议在反代 / 防火墙层加固:
|
||||
|
||||
1. **`server_name` 白名单** — 仅网站域与图片域;`default_server` 拒绝裸 IP 与其它 Host
|
||||
2. **禁止公网暴露 6892** — 仅本机或内网反代访问;公网只开 80/443
|
||||
3. **橙云时限制源站来源 IP** — 仅 Cloudflare 回源 IP 段
|
||||
|
||||
双域名场景下 PicHost **不会** 拒绝未配置的 Host;上述措施由运维层补齐。
|
||||
|
||||
## Caddy 示例
|
||||
|
||||
```caddy
|
||||
pic.example.com {
|
||||
reverse_proxy 127.0.0.1:6892
|
||||
}
|
||||
```
|
||||
|
||||
双域名时添加第二个站点块,后端地址相同即可。
|
||||
|
||||
## 缓存注意
|
||||
|
||||
图片 404/403 与域名隔离 404 响应带 **禁止缓存** 头,避免 CDN 长时间缓存错误页面。若在前端再加 CDN,请对动态 API 路径谨慎缓存。
|
||||
|
||||
## 相关
|
||||
|
||||
- [环境变量](./configuration.md) — `SITE_BASE_URL`、`IMAGE_BASE_URL`
|
||||
- [快速开始](./getting-started.md) — Docker 端口
|
||||
@@ -0,0 +1,72 @@
|
||||
# 存储
|
||||
|
||||
PicHost 支持 **本地磁盘** 与 **S3 兼容对象存储**(Cloudflare R2、腾讯云 COS、阿里云 OSS、AWS S3 等)。管理员在 **存储**(`/storage`)页管理后端;新上传写入 **默认后端**。
|
||||
|
||||

|
||||
|
||||
## 存储结构(本地)
|
||||
|
||||
```
|
||||
/data
|
||||
├── pichost.db # SQLite:用户、会话、设置、storage_backends、images 索引
|
||||
└── images/ # 本地后端时的全部图片文件
|
||||
```
|
||||
|
||||
- 新上传:`images/随机ID.webp` 或 `images/年/月/随机ID.webp`(可在设置中切换扁平模式)
|
||||
- 迁移遗留:`images/blog/...` 等子路径
|
||||
- 云存储时文件在对应桶内,索引仍在 SQLite `images` 表
|
||||
|
||||
所有图片 **key** 以 `images/` 开头。上传 API **不再接受** `folder` 参数。
|
||||
|
||||
## 添加存储后端
|
||||
|
||||
1. 以管理员登录,打开 **存储** → **添加存储**。
|
||||
2. 选择类型:**本地磁盘** 或 **S3 兼容**(含 R2 / COS / OSS 预设)。
|
||||
3. 填写连接信息(桶名、Endpoint、Access Key 等)。
|
||||
4. 保存后可 **设默认**,新上传将写入该后端。
|
||||
|
||||
### Cloudflare R2 要点
|
||||
|
||||
| 项 | 值 |
|
||||
| -- | -- |
|
||||
| Endpoint | `https://<account_id>.r2.cloudflarestorage.com` |
|
||||
| Region | `auto` |
|
||||
| 桶 | 你的 R2 桶名 |
|
||||
| 密钥 | R2 API Token 的 Access Key / Secret Key |
|
||||
|
||||
若仓库 **cloudflare** 分支专用于「仅 R2」部署,也可用环境变量预设,见 [文档首页](./index.md) 分支说明。
|
||||
|
||||
### 环境变量(可选)
|
||||
|
||||
部分部署用环境变量初始化默认 S3 后端(如 `STORAGE_BACKEND=s3`、`S3_ENDPOINT`、`S3_BUCKET`、`S3_ACCESS_KEY`、`S3_SECRET_KEY`、`S3_REGION`)。**UI 中配置的后端信息存于 SQLite**,与环境变量并存时以管理界面为准管理多后端。
|
||||
|
||||
## 直链模式
|
||||
|
||||
每个后端可配置公开 URL 行为:
|
||||
|
||||
| 模式 | 说明 |
|
||||
| ---- | ---- |
|
||||
| **proxy** | 通过 PicHost 同源代理出图(`GET /images/...`) |
|
||||
| **public** | 302 重定向到桶/CDN 公网地址 |
|
||||
|
||||
复制链接时使用 **图片域名**(`IMAGE_BASE_URL`)拼接路径。开启「隐藏 images 前缀」后 URL 可能更短,服务按文件名或路径反查索引。
|
||||
|
||||
## 用量与筛选
|
||||
|
||||
- 存储页展示各后端用量(本地扫描目录,对象存储查询 API)
|
||||
- 图库可按存储后端筛选(管理员)
|
||||
|
||||
## 备份
|
||||
|
||||
请同时备份:
|
||||
|
||||
- `data/images/`(本地后端)
|
||||
- `data/pichost.db`
|
||||
- 各云桶中的对象
|
||||
|
||||
从 v1.1.x 升级且存在 `data/blog/` 等并列目录时,见 [v1.2 迁移](./migration.md)。
|
||||
|
||||
## 相关
|
||||
|
||||
- [环境变量](./configuration.md) — `STORAGE_USE_DATE_PATH`、`HIDE_FOLDER_IN_URL`
|
||||
- [用户与权限](./users-and-permissions.md) — 谁可以管理存储
|
||||
@@ -0,0 +1,53 @@
|
||||
# Twikoo
|
||||
|
||||
PicHost 兼容 **Twikoo** 与 **EasyImage 2.0** 图片上传协议,评论系统可像接 EasyImage 一样配置。
|
||||
|
||||
## Twikoo 配置
|
||||
|
||||
在 Twikoo 环境变量或配置中设置:
|
||||
|
||||
| 配置项 | 值 |
|
||||
| ------ | -- |
|
||||
| `IMAGE_CDN` | `easyimage` |
|
||||
| `IMAGE_CDN_URL` | `https://你的域名/api/index.php` |
|
||||
| `IMAGE_CDN_TOKEN` | 与全局 `API_UPLOAD_TOKEN` 相同 |
|
||||
|
||||
- 使用 **网站域名**(管理后台域)作为 `IMAGE_CDN_URL` 的主机名
|
||||
- Token 需在 PicHost **API** 页生成,或通过 `API_UPLOAD_TOKEN` 环境变量设置
|
||||
|
||||
## 上传接口
|
||||
|
||||
`POST /api/index.php`
|
||||
|
||||
表单字段:
|
||||
|
||||
| 字段 | 说明 |
|
||||
| ---- | ---- |
|
||||
| `image` | 图片文件 |
|
||||
| `token` | 全局 API Token(与 `Auth-Token` 等效) |
|
||||
|
||||
```bash
|
||||
curl -X POST "https://admin.example.com/api/index.php" \
|
||||
-F "token=YOUR_TOKEN" \
|
||||
-F "image=@./demo.png"
|
||||
```
|
||||
|
||||
上传的图片存入 `images/` 目录,归属与 **全局 Token** 相同(管理员)。
|
||||
|
||||
## 与 REST API 的区别
|
||||
|
||||
| 项目 | REST `/api/images/upload` | Twikoo `/api/index.php` |
|
||||
| ---- | ------------------------- | ------------------------ |
|
||||
| 鉴权 | `Auth-Token` 请求头 | 表单 `token` |
|
||||
| 响应格式 | PicHost JSON | EasyImage 兼容 JSON |
|
||||
| Token | 全局或个人 | 仅全局 Token |
|
||||
|
||||
## 双域名部署
|
||||
|
||||
Twikoo 上传应走 **网站域名**(`SITE_BASE_URL`),图片展示走 **图片域名**(`IMAGE_BASE_URL`)。详见 [双域名分离](./domain-separation.md)。
|
||||
|
||||
## 相关
|
||||
|
||||
- [API](./api.md)
|
||||
- [用户与权限](./users-and-permissions.md)
|
||||
- [环境变量](./configuration.md)
|
||||
@@ -0,0 +1,58 @@
|
||||
# 用户与权限
|
||||
|
||||
PicHost 使用基于角色的访问控制(RBAC):**管理员(admin)** 与 **普通用户(user)**。权限在服务端强制,不可仅靠前端绕过。
|
||||
|
||||
## 角色能力
|
||||
|
||||
| 能力 | 管理员 | 普通用户 |
|
||||
| ---- | :----: | :------: |
|
||||
| 上传图片 | ✓ | ✓ |
|
||||
| 查看自己的图库 | ✓ | ✓ |
|
||||
| 查看全部图库 / 上传者标签 | ✓ | — |
|
||||
| 存储后端管理(`/storage`) | ✓ | — |
|
||||
| 系统设置(`/settings`) | ✓ | — |
|
||||
| 开放注册开关 | ✓ | — |
|
||||
| 全局 API Token 管理 | ✓ | — |
|
||||
| 个人 API Token | ✓ | ✓ |
|
||||
| 统计页(含注册用户数) | ✓ | 部分 |
|
||||
| 操作日志 | ✓ | — |
|
||||
|
||||
普通用户顶栏:**API**、**统计**;用户菜单:**修改密码**、**退出登录**。
|
||||
|
||||
## 鉴权场景
|
||||
|
||||
| 场景 | 鉴权方式 | 图片归属 / 可见范围 |
|
||||
| ---- | -------- | ------------------- |
|
||||
| 网页上传 | Session Cookie | 当前登录用户 |
|
||||
| API 上传 + **个人 Token** | `Auth-Token` 头 | Token 所属用户 |
|
||||
| API 上传 + **全局 Token** | `Auth-Token` 头 | 管理员(`userId` 为空) |
|
||||
| Twikoo `POST /api/index.php` | 表单 `token` | 与全局 Token 相同 |
|
||||
| 图库列表 / 搜索 / 删除 | Session 或 Token | 普通用户仅自己;管理员全部 |
|
||||
| 图片直链 `GET /images/...` | 无(Referer 防盗链) | 知道 URL 即可访问 |
|
||||
|
||||
## 注册与账号
|
||||
|
||||
- 默认仅管理员可创建用户;管理员可在设置中 **开放注册**
|
||||
- 密码使用 scrypt 哈希存储
|
||||
- Web 登录需先完成滑动拼图验证(拖动滑块对齐缺口)
|
||||
- 登录失败有速率限制
|
||||
|
||||
## 上传偏好与自动删除
|
||||
|
||||
- **上传偏好**(首页卡片翻转):客户端预压缩、自动复制链接等,按用户保存
|
||||
- **自动删除**:管理员可设全局策略;用户可设个人策略。启用后仅影响 **之后新上传** 的图片
|
||||
|
||||
## API Token 说明
|
||||
|
||||
| 类型 | 谁管理 | 上传归属 | 典型用途 |
|
||||
| ---- | ------ | -------- | -------- |
|
||||
| **全局 Token** | 管理员(API 页) | 管理员账号 | Twikoo、站点级脚本 |
|
||||
| **个人 Token** | 各用户(API 页) | 该用户 | 个人博客、私有脚本 |
|
||||
|
||||
若设置了环境变量 `API_UPLOAD_TOKEN`,则全局 Token 被锁定,见 [环境变量](./configuration.md)。
|
||||
|
||||
## 相关
|
||||
|
||||
- [API](./api.md)
|
||||
- [Twikoo](./twikoo.md)
|
||||
- [存储](./storage.md)
|
||||
Reference in new issue
Block a user