ChronoFrame 是 2025 年 8 月才建仓的一个自托管相册项目,一年出头就攒到近 2000 星、158 个 fork,用 TypeScript 写,AGPL-3.0 协议,最近一次提交就在这两天内。它的定位很窄很清楚:不给所有人做网盘,只给拍照片的人做一个「自己的相册」。

把照片丢进去,它会自己解析 EXIF、生成预览图、根据 GPS 反查拍摄地点,然后把照片按时间、相册、地图三个维度摊开给你看。听起来像 Nextcloud 的照片模块,但两者的取舍完全不同——Nextcloud 是顺手做了相册,ChronoFrame 是只为相册而生。

一、先看它长什么样

ChronoFrame 相册页:瀑布流布局,顶部是相册标题与拍摄时间范围

相册首页是瀑布流,顶部写着相册名和拍摄时间跨度(截图里是这个站主人自己的相册,2025 年 5 月到 2026 年 9 月,24 张照片)。界面默认深色,没有多余的导航元素,照片本身是主角。

点开一张照片进入详情页,这里是它比较硬的地方:

ChronoFrame 照片详情页:右侧是完整的 EXIF 参数面板与缩略图条

右侧整块是 EXIF 面板,机身、镜头、光圈、快门、ISO、焦距、曝光补偿、测光模式、白平衡、闪光灯、拍摄模式、场景类型、色彩空间全列出来,下面还有亮度与「单芯片彩色区域」这类参数。这些数据不是从 EXIF 里原样抄出来的——它做了归类,分成技术参数和曝光参数两组,一眼能看完。

浏览大图用的是 WebGL 缩放 + 分块渲染(tiled rendering)。这个技术选择说明作者在意的是什么:一张 6000 万像素的 RAW 转出来的 JPEG,用普通的 img 标签缩放会糊、拖动会卡,分块渲染是把大图切成瓦片按视野加载,和地图是同一个思路。配合直方图显示,这套东西明显是照着「摄影师看片」的习惯做的,而不是照着「家人分享照片」做的。

二、三个浏览维度,地图是差异点

大部分自建相册能按时间和相册浏览就到头了。ChronoFrame 多给了一个地图维度:

ChronoFrame 地图探索页:MapLibre 底图,左下角是图层与定位控件

底图用的是 MapLibre(开源方案),也支持接 Mapbox。照片带 GPS 就自动落到地图上,可以按地点翻照片。地图右下角的定位控件能定位到当前视口,左上角还有回到全局的按钮。反查地名用的是反向地理编码服务,README 特别提到「地名语言可选」——这个细节挺务实,英文地名和中文地名对国内用户来说差别很大。

地图这个功能听起来简单,实际有三个隐性成本:底图服务要有 token(Mapbox 免费额度有限,MapLibre 需要自己找瓦片源)、反向地理编码要走外部 API(有速率限制)、以及一批照片没有 GPS 就什么都显示不出来。README 的处理方式是「可以先不配地图 token,先把照片传上去」——安装向导里地图不是必填项,这点对新手友好。

三、Live Photo 的处理方式,以及它的代价

iPhone 拍的 Live Photo 是一张 HEIC 加一段 MOV。多数自建相册的处理方式是丢掉 MOV,只留一张静图,因为配对逻辑烦。ChronoFrame 是反过来的:它主动做图像与视频的自动配对,鼠标悬停或长按就能播放。

配对的规则写得很明确:图片和 MOV 必须同名,比如 IMG_1234.heic 配 IMG_1234.mov,两个文件谁先传都无所谓。

这条规则好用,但也是一个使用上的摩擦点:只要文件名被改过,配对就断了。从 iPhone 直接导出的原始文件没问题,但凡经过「批量重命名工具」「按日期重命名」「转格式再上传」这些流程,Live 属性就丢了,而界面上不会报错——你只会得到一堆普通照片。支持格式列得挺全(JPEG、PNG、WebP、GIF、BMP、TIFF、HEIC / HEIF),但 MOV 的配对完全依赖文件名,这是它做的取舍。

四、上传之后发生的事:任务队列

ChronoFrame 管理后台:照片库视图与上传入口

登录后进 /dashboard,这是管理和上传的地方。传完不是立刻可用——后台有个任务队列在跑四件事:解析 EXIF、生成缩略图、识别地点、处理 Live Photo。队列有实时日志,失败的单个任务会标错并且可以重试。

这个设计对一个几千张照片的库来说几乎是必须的:一次拖进去 500 张 HEIC,同步处理会直接把浏览器挂死,异步队列则可以让用户关掉页面去干别的。后台还能批量改元数据和评分、批量下载、重建索引(reindexing),以及查看最近活动。评分这个字段说明它确实考虑过「从一堆照片里挑片」的场景。

五、存储:本地、S3、OpenList 三条路

存储层支持三种:本地文件、S3 兼容对象存储、OpenList。存储方案和 CDN 地址都在后台配,不用改配置文件。

存储方式适合的场景要注意的
本地文件单机部署、照片总量不大、要完全自己掌控官方给的路径是 /app/data/storage,必须和 ./data 一起挂载,否则重建容器数据就没了
S3 兼容照片多、要异地备份、想走 CDN 加速如果存储桶设成公开读,相册密码就形同虚设,权限得在存储端另外管
OpenList照片已经散在网盘里,不想搬访问速度取决于 OpenList 背后那个网盘的脸色

这里必须把一件事说清楚,因为它是这类「自建相册」最容易踩的坑:相册密码只在 ChronoFrame 这一层生效。README 原话的意思很直接——如果 S3、OpenList 或者 CDN 把图片的公开地址暴露出来了,那么访问控制得在那个服务里另外做一遍。也就是说,你给一个私密相册设了密码,但只要有人拿到了 S3 直链,照片照样能看。想真私密,就别开公开读,或者干脆用本地存储。

六、部署:一个容器,两个端口映射,一个必须挂的目录

官方推荐 Docker,镜像在 GitHub Container Registry,Docker Hub 上也有同名镜像。compose 里其实只有四个关键项:

配置项值作用
镜像ghcr.io/hoshinosuzumi/chronoframe:latest换成版本号 tag(如 v1.0.0)可以锁版本,避免自动升级踩坑
端口3000:3000容器内固定 3000,外面自己定
数据卷./data:/app/data数据库、设置、会话密钥、本地照片全在这里,丢了等于整个站没了
重启策略unless-stopped机器重启后自动拉起来

起来之后打开首页,会进安装向导:在浏览器里创建管理员、填站点信息、选存储。选本地存储就填 /app/data/storage。装完再进后台调细节(地图 token、语言、OAuth 之类的都可以后补)。

公网部署记得套 HTTPS——这不是客套话,登录、上传、会话密钥都走这条链路。文档站里另有反代、备份、以及从老版本迁移的说明。

七、技术栈与协议

前端是 Nuxt + Vue + Tailwind CSS,数据库层用 Drizzle ORM,开发环境要求 Node.js 22 和项目锁定的 pnpm 10.34.6。仓库是个 monorepo,WebGL 那块被单独拆成了包。

协议这块值得单独说,因为它比多数同类项目复杂:默认 AGPL-3.0-only,而且明确覆盖 Self-hosted 和 SaaS 两套实现。不过 packages/contracts 和 packages/webgl-image 这两个包保持 MIT。README 里还专门提到「历史上以 MIT 发布的版本,其权利不受影响」,以及「满足 AGPL 条件时允许做付费托管」。

对普通自建用户来说,AGPL 意味着你改了代码给外人用,得开源。对想拿它做生意的(比如打包成付费相册服务卖),这几段话就是给你看的——商业授权另有渠道可谈。

八、现状:一年做到近 2000 星,但别忽略这些

截至写这篇文章时,仓库 1981 星、158 fork、33 个未关 issue。对一个 2025 年 8 月才建仓的项目来说,这个速度相当快,也上了 HelloGitHub 和 Product Hunt。但同样地,33 个未关 issue 放在 2000 星的项目上说明它还在快速迭代期,功能变动和数据迁移都可能发生,文档里专门写了「从老版本迁移」的指引,本身就是个信号。

几个实测到的情况,一并写出来:

  • 文档站 docs.chronoframe.art 撰写时可正常访问,结构清楚(入门、使用、更新、开发、更新日志都分开了)。
  • README 里给的官方演示站 lens.bh8.ga,撰写时连接超时,直连和走代理都打不开,所以本文没有放「在线试用」的说法,也没拿它当截图来源——文中四张图全部来自仓库自带的 docs 目录。
  • 作者另外运营一个托管版 ChronoFrame Cloud(chronoframe.art),不想自己维护服务器的人可以直接注册用。这条只作信息说明,本站不做推荐,也没放注册入口。

九、它适合谁

如果你要的是「一家人共享照片、手机上自动备份」——这不太是它的方向,它的上传入口在 Web 后台,移动端体验不是重点,Live Photo 还依赖原始文件名。

如果你要的是「我拍的照片,我自己存着,能按时间翻、按相册整理、按地图看我在哪儿拍的,而且大图能真的看清细节」——这个需求 ChronoFrame 接得很准。EXIF 面板、直方图、WebGL 分块渲染、地图浏览、批量评分挑片,这些点连起来是一条完整的「摄影师看图」链路,不是随手加的功能清单。

一句话总结:它不是一个功能更多的相册,而是一个把「看照片」这件事做深了的相册。代价是 Live Photo 对文件名的依赖、相册密码对存储层无效这两个坑得自己记住;收益是你不需要为一个几千张照片的库去维护一套 Nextcloud。

本文根据项目公开仓库 HoshinoSuzumi/chronoframe 的 README 与源码信息整理撰写,配图取自该仓库 docs/images 目录下的官方截图(已统一转为 JPEG 并去除元数据,未做内容修改)。文中星标数、issue 数、站点可达性均为撰写时实测,项目迭代较快,请以仓库当前状态为准。

本文整理自公开资料并做重写,原始出处:https://github.com/HoshinoSuzumi/chronoframe。文中配图已去除站点叠加水印与推广信息;版权归原作者所有。

Last modification:November 11, 2026
如果觉得我的文章对你有用,请随意赞赏