GitHub Release / release (push) Canceled after 0s
Publish Docker image / build (linux/amd64, ubuntu-latest, amd64) (push) Canceled after 0s
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Canceled after 0s
Publish Docker image / merge (push) Canceled after 0s
ci / ci (22, ubuntu-latest) (push) Canceled after 0s
修复设置页误清空管理域、配置与生效 URL 混淆及第三 Host 绕过隔离;加固 Settings API 与中间件,并更新文档站。
6.9 KiB
6.9 KiB
v1.2.0 本地磁盘迁移指南
v1.2.0 起,所有本地图片文件统一放在 data/images/ 下;SQLite images 表中的 key 也以 images/ 开头。旧版在 data/blog/、data/twikoo/ 等与 images 并列的顶层目录不再符合新模型。
迁移分 两步:先用手动 CLI 搬文件,再由服务 启动时自动同步索引。
从其它图床迁入(EasyImage / 兰空 / Chevereto 等)
没有单独的「一键从外链拉取」或「对接某某图床 API」工具。从 PicHost 旧版 或其它自托管图床迁入,走的是同一套 本地文件迁移:
- 在旧图床服务器上找到图片物理目录(整目录拷贝,不要只拷数据库)。
- 把该目录放到 PicHost 的
data/下,作为与images并列的顶层文件夹(文件夹名任意,会保留为images/{文件夹名}/...)。 - 执行
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)
# 在宿主机:把从旧图床打包的目录放进挂载卷(名称自定)
# 例如:./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
# 预览:列出待迁移文件,写入 data/mapping.json(旧 key → 新 key)
docker exec pichost migrate
# 确认无误后执行文件移动
docker exec pichost migrate --apply
本地开发
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 容器启动)会自动执行,无需手动命令。日志示例:
[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 后重启一次服务即可。
推荐升级流程
- 备份
data/(含pichost.db与各目录)。 docker exec pichost migrate预览,检查输出与mapping.json。docker exec pichost migrate --apply执行迁移。- 拉取 / 部署 v1.2.0 镜像并重启容器。
- 查看启动日志,确认「图片索引同步结束」无报错。
- 用
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 |
重置密码(与迁移无关) |