Self-hosted personal gallery application with online photo management and albums, supporting Live/Motion Photos, EXIF parsing, geolocation recognition, and an explore map.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A smooth photo display and management application, supporting multiple image formats and large-size image rendering.
• Manage photos online - Easily manage and browse photos via the web interface
• Explore map - Browse photo locations on a map
• Smart EXIF parsing - Automatically extracts metadata such as capture time, geolocation, and camera parameters
• Reverse geocoding - Automatically identifies photo shooting locations
• Multi-format support - Supports mainstream formats including JPEG, PNG, HEIC/HEIF
• Smart thumbnails - Efficient thumbnail generation using ThumbHash檢視完整 README ↗Languages: English | 中文
ChronoFrame is a self-hosted photo gallery. Upload your photos and it extracts EXIF, creates previews and identifies shooting locations. Visitors can browse by time, album or map, zoom into large images and play Live Photos.
Live demo · Documentation · Changelog
Docker is the recommended option. Create docker-compose.yml:
services:
chronoframe:
image: ghcr.io/hoshinosuzumi/chronoframe:latest
container_name: chronoframe
restart: unless-stopped
ports:
- '3000:3000'
volumes:
- ./data:/app/data
docker compose up -d
You can also use hoshinosuzumi/chronoframe:latest from Docker Hub. Replace the tag with v1.0.0 to pin the version.
To run directly with Docker:
docker run -d --name chronoframe --restart unless-stopped \
-p 3000:3000 -v "$(pwd)/data:/app/data" \
ghcr.io/hoshinosuzumi/chronoframe:latest
Open http://localhost:3000 and use the setup wizard to create your administrator and choose storage. For local storage, enter /app/data/storage. You can add a map token later and start uploading photos first.
Keep the ./data mount: it holds the database, settings, session secret and local photos when using the path above.
Use HTTPS for a public deployment. See Getting Started and the update guide for proxies, backups and migration from older versions.
Sign in and open /dashboard to upload and organize photos. After upload, the task queue processes EXIF, thumbnails, locations and Live Photos. Failed tasks show an error and can be retried.
For Apple Live Photos, the image and MOV must share a filename, such as IMG_1234.heic and IMG_1234.mov; either can be uploaded first. Image formats include JPEG, PNG, WebP, GIF, BMP, TIFF and HEIC / HEIF.
Album passwords control access through ChronoFrame. If S3, OpenList or a CDN exposes public image URLs, manage access in that service too. Read Using ChronoFrame for details.
Use Node.js 22 and the project's pinned pnpm 10.34.6:
corepack enable
pnpm install --frozen-lockfile
pnpm dev
Open http://localhost:3000 and complete local setup in the wizard. Use ./data/storage for local development storage.
pnpm lint # Oxlint
pnpm fmt:check # Oxfmt
pnpm build:deps # Build the WebGL package
pnpm build # Build the application
pnpm docs:build # Build documentation
After changing the database schema, run pnpm db:generate and review the SQL. Generating migrations is unnecessary just to start the app. See the contributing guide for more.
ChronoFrame uses AGPL-3.0-only by default, including the Self-hosted and SaaS
implementations. packages/contracts and packages/webgl-image remain MIT. See LICENSE,
LICENSING.md for scope, historical MIT rights,
and commercial licensing inquiries to ChronoFrame. Paid hosting is permitted
when the applicable AGPL requirements are met.
For suspected vulnerabilities, follow the Security Policy and report privately.
Issues and pull requests are welcome. Explain the problem, resulting behavior and verification. Keep English and Chinese documentation in sync.
GitHub Issues · Discussions · Discord
Thanks to the maintainers of Nuxt, Vue, Tailwind CSS, Drizzle ORM and other open-source dependencies, and everyone contributing testing, translations and code.