O96u 7c45a78572 release: v1.0.4
Add PasswordInput with show/hide toggle, align legacy setup/register
routing, merge duplicate i18n keys, and remove unused jose dependency.
2026-08-25 16:11:50 +08:00
2026-08-25 16:11:50 +08:00
2026-08-25 16:11:50 +08:00
2026-08-22 14:36:57 +08:00
2026-08-25 16:11:50 +08:00
2026-08-22 14:36:57 +08:00
2026-08-23 17:43:42 +08:00
2026-08-22 14:36:57 +08:00
2026-08-22 14:36:57 +08:00
2026-08-22 14:36:57 +08:00
2026-08-22 14:36:57 +08:00
2026-08-25 16:11:50 +08:00
2026-08-25 16:11:50 +08:00
2026-08-23 17:43:42 +08:00
2026-08-22 14:36:57 +08:00
2026-08-22 14:36:57 +08:00
2026-08-23 17:43:42 +08:00
2026-08-25 16:11:50 +08:00
2026-08-25 16:11:50 +08:00
2026-08-22 14:36:57 +08:00
2026-08-22 14:36:57 +08:00
2026-08-25 16:11:50 +08:00

PicHost

PicHost

Lightweight personal image hosting · Simple uploads, clean management

Self-hosted / Multi-user / Docker / API / Twikoo · Zero-config setup

version CI Nuxt 4 Docker MIT

Quick Start · Screenshots · Features · Tech Stack · Roadmap · 简体中文


Screenshots

Login Upload
Login Upload
Upload preferences Stats & gallery
Preferences Stats
Settings
Settings

Features

  • Drag, click, or Ctrl+V paste to upload; admins can use custom folder paths
  • Server-side WebP (sharp), Referer hotlink protection, configurable public base URL
  • Multi-user — username/password login; optional registration; users see only their images
  • Upload preferences (card flip UI): client-side compression, auto-copy links, per-user auto-delete
  • Gallery — browse, search, batch delete; admin sees uploader badges
  • Stats — upload/delete metrics, folder breakdown; admin sees registered user count
  • API — global token (admin) + per-user tokens; in-app cURL snippets
  • Twikoo — POST /api/index.php (image + token)
  • Zero-config Docker — first-run web wizard, no secrets required upfront

Quick Start

docker run -d \
  --name pichost \
  -p 6892:6892 \
  -v ./data:/data \
  --restart unless-stopped \
  muxui/pichost:latest

Default port: 6892. Open http://<host>:6892 in your browser and complete the setup wizard.

Forgot password (requires docker exec / server access):

docker exec pichost reset-password              # admin only, when there is exactly one
docker exec pichost reset-password <username>   # admin or regular user

A random password is printed. Fails if the user does not exist.

If you cloned the repo, you can also use docker compose up -d (see docker-compose.yml).

Local development

npm install
cp .env.example .env   # optional
npm run dev

Open http://localhost:3000/setup to create the admin account. Data defaults to ./data.

Legacy migration

If you only had ADMIN_SECRET and no user table, log in with the secret once and follow the migration wizard.

Tech Stack

Layer Technology
Frontend Nuxt 4, Vue 3, Nuxt UI 4, Tailwind CSS 4
Backend Nitro (Node.js), SQLite
Images sharp (WebP transcoding & compression)
Auth Session cookie, scrypt password hashing, API tokens
Storage Local disk (DATA_DIR)
Deploy Docker (amd64 / arm64), docker compose
Tests Vitest

Environment variables

Variable Description
API_UPLOAD_TOKEN Global upload token (Auth-Token header); can be generated in the API page
ALLOWED_REFERER_HOSTS Hotlink allowlist (comma-separated hostnames)
IMAGE_BASE_URL Public base URL for image links
WEBP_QUALITY Server WebP quality 1–100, default 80
AUTO_DELETE_DAYS Global auto-delete days (0 = off); admin + orphan images only
DATA_DIR Data directory, default /data (container) or ./data (local)
ADMIN_SECRET Legacy v1.0 migration only
DEV_BYPASS_ACCESS Dev only — bypass auth (never in production)

Environment variables override database settings. See .env.example.

Users & permissions

Scenario Auth Ownership / visibility
Web upload Session Current user
API upload + user token Auth-Token Token owner
API upload + global token Auth-Token Admin (userId null)
Twikoo /api/index.php form token Same as global token
Gallery list / search / delete Session or token Users: own only; admin: all
Direct link GET /images/... None (Referer rules) Public if URL is known

Regular users are limited to the images/ folder; custom folder requires admin or global token.

Storage layout

/data
├── pichost.db          # SQLite: users, sessions, settings, logs
├── images/             # Default upload folder
├── blog/               # Example custom folder
└── twikoo/             # Twikoo comment images

Pattern: folder/YYYY/MM/randomId.webp + .meta.json. Back up the entire /data directory.

API overview

Method Path Description
POST /api/images/upload Upload image
GET /api/images Paginated list
DELETE /api/images Delete one (key)
POST /api/index.php Twikoo / EasyImage 2.0

Upload example:

curl -X POST "https://pic.example.com/api/images/upload" \
  -H "Auth-Token: YOUR_TOKEN" \
  -F "folder=blog" \
  -F "image=@./demo.png"

Full docs and copyable cURL snippets are on the API page after deployment.

Twikoo

Setting Value
IMAGE_CDN easyimage
IMAGE_CDN_URL https://your-domain/api/index.php
IMAGE_CDN_TOKEN Same as API_UPLOAD_TOKEN

Reverse proxy

  • Proxy to port 6892; HTTPS recommended
  • Nginx: client_max_body_size ≥ 12m
  • Set IMAGE_BASE_URL for public access

Development

npm run dev          # Dev server
npm run build        # Production build
npm run start        # Run .output
npm run lint         # ESLint
npm run typecheck    # Type check
npm test             # Unit tests

Roadmap

Version Plan
v1.0.3 CI and Docker multi-arch build fixes (current)
v1.0.2 i18n, mobile menus, stats/upload UI, Docker password reset
v1.0.1 Settings version display, mobile upload preferences layout fix
v1.0.0 Local storage, multi-user, API, Twikoo
v1.1.0 S3, Cloudflare R2, and more object storage backends

License

MIT

LINUX DO

S
Description
Lightweight self-hosted image hosting — Docker, multi-user, gallery & API, local disk or S3-compatible storage.
https://O96u.github.io/PicHost/
Readme GPL-3.0
4.6 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 50.8%
Vue 47.3%
JavaScript 1.3%
CSS 0.4%
Dockerfile 0.1%