Add slider captcha for web login, VitePress documentation on GitHub Pages, and fixes for gallery delete refresh, pagination jump, and copy-format persistence.
4.4 KiB
v1.2.0 local disk migration guide
From v1.2.0, all local image files live under data/images/; SQLite keys also start with images/. Legacy top-level folders next to images (e.g. data/blog/, data/twikoo/) are no longer used.
Migration is two steps: run the CLI to move files on disk, then let startup sync align the SQLite index.
Migrating from other image hosts (EasyImage, Lsky, Chevereto, …)
There is no dedicated “pull from URLs” or “import via vendor API” tool. Moving from legacy PicHost or another self-hosted install uses the same local file workflow:
- Locate the image files on the old server (copy the tree, not just the database).
- Place them under PicHost
data/as a top-level folder next toimages(any name — it becomesimages/{name}/...). - Run
migrate/migrate --apply, then restart PicHost.
| Source | Typical path on old server | After copy into PicHost |
|---|---|---|
| PicHost v1.1.x | data/blog/, data/twikoo/ |
Already under data/ → run migrate |
| EasyImage(s) | i/ or upload/ |
e.g. data/easyimage/ → migrate |
| Lsky | public/uploads/ etc. |
e.g. data/lsky/ → migrate |
| Chevereto etc. | images/ or content/ |
e.g. data/chevereto/ → migrate |
| Custom | your folder name | data/your-folder/ → migrate |
The CLI scans every top-level directory under data/ except images, not only blog / twikoo.
Limits: files only — accounts, tokens, and old public URLs are not imported. mapping.json maps old storage keys, not full old-site URLs. For S3/R2-only legacy hosts, sync blobs to data/… or attach the bucket in PicHost Storage settings.
Layout before and after
Before (typical v1.1.x)
/data
├── pichost.db
├── blog/
│ └── 2026/08/TeKJ2fD6cB6j.webp
├── twikoo/
└── images/
Index keys might look like blog/2026/08/TeKJ2fD6cB6j.webp.
After (v1.2.0)
/data
├── pichost.db
├── mapping.json
└── images/
├── blog/
│ └── 2026/08/TeKJ2fD6cB6j.webp
└── twikoo/
Index key: images/blog/2026/08/TeKJ2fD6cB6j.webp.
Step 1: CLI file migration
Run before or after upgrading the image; backup data/ first.
docker exec pichost migrate # preview + mapping.json
docker exec pichost migrate --apply # move files
Local: npm run migrate / npm run migrate -- --apply.
| Item | Behavior |
|---|---|
| Scan | Every top-level directory under data/ except images |
| Target | data/images/{original-top-dir}/{relative-path} |
| Extensions | jpg, jpeg, png, webp, gif, svg, ico |
| Sidecar | .meta.json next to an image is moved if present |
| Other files | Not moved; parent directory kept if anything remains |
| Mapping | data/mapping.json — old key → new key |
Script: server/cli/migrate-to-single-images.mjs.
Step 2: Startup index sync (automatic)
Runs on every start (npm run dev, Docker). No manual command.
[INFO] 开始同步图片索引:扫描本地磁盘 ...
[INFO] 磁盘扫描完成:...
[INFO] 开始归一化遗留图片路径 ...
[INFO] 开始校验索引与磁盘一致性,清理无文件的孤儿记录
[INFO] 图片索引同步结束
| Step | Purpose |
|---|---|
Scan data/images/ |
Insert missing index rows for files on disk |
| Normalize legacy keys | blog/... → images/blog/... when files are in place |
| Purge orphans | Remove index rows with no file on disk |
| Repair Content-Type | Fix application/octet-stream entries |
The CLI only moves files. Index alignment runs at startup — restart after migrate --apply.
Recommended upgrade flow
- Backup
data/. docker exec pichost migrate— review output andmapping.json.docker exec pichost migrate --apply.- Deploy v1.2.0 and restart.
- Check logs for successful index sync.
- Use
mapping.jsonto update external URLs if needed.
Skip step 1 if you only use object storage or everything is already under data/images/.
URLs
| Old key | blog/TeKJ2fD6cB6j.webp |
| New key | images/blog/TeKJ2fD6cB6j.webp |
With “hide folder” mode, short URLs like /TeKJ2fD6cB6j.webp may still resolve by filename. Use mapping.json for bulk replacements.
Chinese version: v1.2 迁移指南