Languages: English | 中文
丝滑的照片展示和管理应用,支持多种图片格式和大尺寸图片渲染。
- 在线管理照片 - 通过 Web 界面轻松管理和浏览照片
- 探索地图 - 在地图上浏览照片拍摄位置
- 智能 EXIF 解析 - 自动提取拍摄时间、地理位置、相机参数等元数据
- 地理位置识别 - 自动识别(Reverse Geocoding)照片拍摄地点
- 多格式支持 - 支持 JPEG、PNG、HEIC/HEIF 等主流图片格式
- 智能缩略图 - 基于 ThumbHash 技术的高效缩略图生成
- Nuxt 4 - 基于最新的 Nuxt 框架,提供 SSR/SSG 支持
- TypeScript - 完整的类型安全保障
- TailwindCSS - 现代化的 CSS 框架
- Drizzle ORM - 类型安全的数据库 ORM
- 多存储后端 - 支持 S3 兼容存储、本地文件系统
- CDN 加速 - 可配置 CDN 地址加速图片访问
推荐使用预构建的 docker 镜像部署,在 ghcr 上查看镜像
创建 .env 文件并配置。
下面是最小化配置示例,完整的配置项参考 配置指南:
# 管理员邮箱(必须)
CFRAME_ADMIN_EMAIL=
# 管理员用户名(可选,默认 ChronoFrame)
CFRAME_ADMIN_NAME=
# 管理员密码(可选,默认 CF1234@!)
CFRAME_ADMIN_PASSWORD=
# 站点信息(均可选)
NUXT_PUBLIC_APP_TITLE=
NUXT_PUBLIC_APP_SLOGAN=
NUXT_PUBLIC_APP_AUTHOR=
NUXT_PUBLIC_APP_AVATAR_URL=
# 地图提供器 (maplibre/mapbox)
NUXT_PUBLIC_MAP_PROVIDER=maplibre
# 使用 MapLibre 需要 MapTiler 访问令牌
NUXT_PUBLIC_MAP_MAPLIBRE_TOKEN=
# 使用 Mapbox 需要 Mapbox 访问令牌
NUXT_PUBLIC_MAPBOX_ACCESS_TOKEN=
# Mapbox 无域名限制令牌(反向地理编码,可选)
NUXT_MAPBOX_ACCESS_TOKEN=
# 存储提供者(local、s3 或 openlist)
NUXT_STORAGE_PROVIDER=local
NUXT_PROVIDER_LOCAL_PATH=/app/data/storage
# 会话密码(必须,32 位随机字符串)
NUXT_SESSION_PASSWORD=我们推荐使用预构建的 Docker 镜像进行部署,镜像托管在 GHCR 和 Docker Hub,您可以根据网络情况选择合适的源。
docker pull ghcr.io/hoshinosuzumi/chronoframe:latestdocker pull hoshinosuzumi/chronoframe:latest一行命令启动:
docker run -d --name chronoframe -p 3000:3000 -v $(pwd)/data:/app/data --env-file .env ghcr.io/hoshinosuzumi/chronoframe:latest创建 docker-compose.yml:
services:
chronoframe:
image: ghcr.io/hoshinosuzumi/chronoframe:latest
container_name: chronoframe
restart: unless-stopped
ports:
- '3000:3000'
volumes:
- ./data:/app/data
env_file:
- .env启动:
docker compose up -d如未配置
CFRAME_ADMIN_EMAIL和CFRAME_ADMIN_PASSWORD,默认账号如下:
- 邮箱:
admin@chronoframe.com- 密码:
CF1234@!
- 点击头像跳转到登录页面,可以使用账号密码或 GitHub 登录
- 访问仪表板页面
/dashboard - 在
Photos页面中选择图片并点击上传(支持批量上传和拖拽上传) - 系统将自动提取 EXIF 信息、生成缩略图并逆编码照片地理位置
- Node.js 18+
- pnpm 9.0+
# 使用 pnpm (推荐)
pnpm install
# 或使用其他包管理器
npm install
yarn install复制环境变量模板并根据需要配置:
cp .env.example .env# 2. 生成数据库迁移文件(可选)
pnpm db:generate
# 3. 执行数据库迁移
pnpm db:migratepnpm dev应用将在 http://localhost:3000 启动。
chronoframe/
├── app/ # Nuxt 应用
│ ├── components/ # 组件
│ ├── pages/ # 页面路由
│ ├── composables/ # 组合式函数
│ └── stores/ # Pinia 状态管理
├── packages/
│ └── webgl-image/ # WebGL 图片查看器
├── server/
│ ├── api/ # API 路由
│ ├── database/ # 数据库 schema 和迁移
│ └── services/ # 业务逻辑服务
└── shared/ # 共享类型和工具
# 开发模式 (包含依赖包构建)
pnpm dev
# 仅构建依赖包
pnpm build:deps
# 构建生产版本
pnpm build
# 数据库操作
pnpm db:generate # 生成迁移文件
pnpm db:migrate # 执行迁移
# 预览生产版本
pnpm preview欢迎贡献代码!请确保:
- Fork 本仓库
- 创建功能分支 (
git checkout -b feature/amazing-feature) - 提交更改 (
git commit -m 'Add some amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 开启 Pull Request
- 使用 TypeScript 进行类型安全的开发
- 遵循 ESLint 和 Prettier 代码规范
- 更新相关文档
本项目基于 MIT 许可证 开源。
Timothy Yin
- Email: master@uniiem.com
- GitHub: @HoshinoSuzumi
- Website: bh8.ga
- Gallery: lens.bh8.ga
如何创建管理员用户?
首次启动时,会根据环境变量 CFRAME_ADMIN_EMAIL、CFRAME_ADMIN_NAME 和 CFRAME_ADMIN_PASSWORD 环境变量创建一个管理员用户。CFRAME_ADMIN_EMAIL 必须是登录使用的 GitHub 账户的邮箱。
支持哪些图片格式?
支持 JPEG、PNG、HEIC/HEIF、MOV(作为实况照片) 格式。
为什么无法使用 GitHub/Local 存储?
目前支持 S3 兼容存储,未来计划支持 GitHub 和本地文件系统存储。
为什么需要/如何配置地图服务?
地图服务用于在地图上浏览照片拍摄位置,以及照片详情中的小地图渲染。目前使用 Mapbox,注册后获取访问令牌并配置到 MAPBOX_TOKEN 环境变量中。
为什么我上传的 MOV 文件没有被识别为实况照片?
需要确保实况照片对的图片(.heic)和视频(.mov)的文件名一致(例如 IMG_1234.heic 与 IMG_1234.mov 会自动匹配)。
一般情况来说,不管是上传 .heic 还是 .mov,都会检测一次配对,因此上传的顺序无关紧要。
如果仍然没有被识别为实况照片,请在仪表盘中找到图片,在操作菜单中手动触发配对检测。
如何导入存储中已有的照片?
目前不支持直接导入已有照片,未来计划支持通过指定目录扫描导入。
本项目与 Afilmory 有何区别?
Afilmory 是一个非常优秀的项目,其部署方式是在本地或 CI 中处理存储中的照片并生成清单文件,然后前端通过读取清单文件来展示照片,属于静态部署。 ChronoFrame 则是一个动态的照片管理应用,提供在线上传、管理和浏览照片的功能,适合需要频繁更新照片的场景。
本项目受启发于 Afilmory,同样优秀的个人相册项目。
感谢以下优秀的开源项目和库:



