首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >ChronoFrame - 一款优雅的瀑布流相册系统

ChronoFrame - 一款优雅的瀑布流相册系统

作者头像
柳神
发布2026-04-05 09:18:59
发布2026-04-05 09:18:59
1420
举报
文章被收录于专栏:清羽飞扬清羽飞扬

关于AI

清羽AI正在绞尽脑汁想思路ING···

清羽のAI摘要

MiniMax-M2.5

碎碎念

一个月没有更新文章啦,不过放心,煮啵不是似了,煮啵只是染上了Arch瘾在捣鼓新系统呢!虽然过程不是很顺利,结果也不是很顺利,但是起码也是玩过的人了,本来打算玩明白了写一个对应的教程,但是玩明白之后,自己先逃离了,倒不是说没配置好,主要是很多软件都没有,维护也不太行,比如腾讯视频,网易邮箱大师……诸如此类的应用还有很多,Arch确实很漂亮,也很符合我的开发习惯,但是,还有很大的进步空间哦~

(等煮啵研究一下能不能刷个MacOS,这个总不缺生态了吧,哼哼)

这一个月,虽然一直在研究新系统,但也不是一点没碰网站,由于嫖上了群友的ChatGPT组织,反倒写代码更多了,比如前面的兰空图床美化,还有煮啵自己的临时邮箱,再就是新相册,相册是我最喜欢的网站之一,他承载了我之前的记忆,之前的相册由于玩崩了,所以干脆没迁移,从头开始新整了一个相册,尽可能将之前的一些照片搬了上来,全新的系统有了更大的维护需求,原来的Typecho只需要填写直链即可,现在的相册主要手动上传原图,他会自动生成缩略图,虽然说更加的系统化,但是对于存储的要求也更高啦,最后煮啵找到了一个更好的方案,基本摆脱了未来的存储焦虑!

介绍

首先放上项目地址,项目的配置较多,如果看到这里溜了的小伙伴要自己看好哦!

🙄引用站外地址,不保证站点的可用性和安全性

ChronoFrame: 丝滑的照片展示和管理应用

github.com@HoshinoSuzumi

这个项目的灵感来自一个同样很优秀的开源项目 —— Afilmory

Afilmory更偏向于“静态相册”的思路:通过预处理照片生成清单文件,然后以静态站点的形式进行展示。这种方式部署简单、成本低,非常适合纯展示类需求。

ChronoFrame在此基础上走向了另一个方向:它不是一个“生成好的相册”,而是一个真正可以在线管理的动态照片系统

相比传统相册项目,ChronoFrame不仅可以上传、整理和浏览照片,还能自动解析EXIF、展示拍摄位置、在地图上回溯足迹,虽然说我目前对这个功能不太满意,由于它支持自动生成缩略图,所以在大尺寸图片下依然保持非常丝滑的浏览体验。

下面是俺自己的地址:

😃来自本站,本站可确保其安全性,请放心点击跳转

清羽飞扬の时光相册

LiuShen's Blog

如果你只是想做一个静态展示站,Afilmory可能已经足够,但如果你希望拥有一个可以长期使用、持续管理、并且体验优秀的个人相册系统,那 ChronoFrame会是一个更值得尝试的选择。

竞品

竞品?实则是项目介绍!

在刚开始建立相册的时候,我找了很多相册程序,那时候的相关程序远没有现在这么丰富,所以我甚至研究了博客程序的相册主题,比如洪哥的TimePlus,地址如下:

🙄引用站外地址,不保证站点的可用性和安全性

TimePlus: 洪墨时光。由Heo维护的Time主题版本,基于Typecho

github.com@zhheo

对于之前的我来说,这款主题十分合适,只需要填写图片直链和对应信息即可完美的实现展示的功能,虽然说精度不是很高,但是对于只想展示照片的我已经是够够的啦,配合piclist和自建的兰空图床,可以做到存储的极致轻量化。

后面,随着Typecho的更新和主题的更新,作为强迫症的我,势必要用上最新的系统,但是我又懒得去配置一些环境,并且由于PHP众所周知的特性,安全性也较差,再加上对接的数据库,内存占用也比较严重,已经工作了的我可没这么多闲时间耗,我直接一个雷霆大踹给项目踢飞了,找了一些同类型的竞品项目,如下:

🙄引用站外地址,不保证站点的可用性和安全性

CloudImgs - 极简风格的云图库,支持NAS部署

github.com@qazzxxx

这个项目并不算是一个真正意义上的的开放性展示相册,而像是一个个人备份相册,后台需要密码才能进入,虽然说可以分享相册对外展示,但是路径仍然不是根目录,如果没有途径获取到你的分享链接,也无法查看。是一个优秀的项目,但不是我想要的效果。

下面我比较关注的项目就是PicImpact啦,这个是一个彻底的相册站,由NextJS开发,支持S3R2OpenList等多种存储方式,上传图像时会自动抓取EXIF进行信息获取,比如拍照位置,拍照设备,图像大小,并按照美观的展示方式进行展示。

🙄引用站外地址,不保证站点的可用性和安全性

PicImpact - 自部署的摄影作品网站,支持多种功能特性。

github.com@besscroft

从一个相册的角度来看,这个程序已经具有基本上所有的功能,但是不知道为什么,我看issue中的演示站,总感觉卡卡的,并且按照我个人的审美而言,我更喜欢瀑布流展示,PicImpact虽然也有瀑布流,但是只能在时光相册页面看到,整体页面很清爽,但是个人不太喜欢(纯主观),如下:

下面就是Afilmory了,其实刚发现他的时候,我并不知道他只能通过获取列表展示,我还以为是后台上传显示,但是由于那时候还是学生的我没法负担起较高价格的存储,虽然说免费的少量存储很多,但是对于我来说,更在乎服务的持续性,我不想使用那种一眼看到头的服务,所以就一直搁置。

虽然我到最后也没使用过,但是这并不影响他是一个很优秀的相册程序,项目地址如下:

🙄引用站外地址,不保证站点的可用性和安全性

Afilmory - Modern photo gallery for photographers

github.com@Afilmory

注意,这个程序官方并没有提供Docker镜像,所以可能需要自己打包一个哦,当然官方也带托管,感兴趣可以去体验一下!

由于没有给docker镜像,所以我也不太清楚后台功能有多少,需要大家自行探索咯。

除了这个,我还发现了一个相册站,与其说是相册站,不如说是壁纸站,并且自带图源,可以直接搭建一个免维护,带登录功能的图片采集站,不仅可以自己上传图片,也可以实现自动聚合各类壁纸,比如每日一图Bing等等,项目如下:

🙄引用站外地址,不保证站点的可用性和安全性

wallpaper-gallery

github.com@IT-NuanxinPro

如果你想做一个偏商业化的壁纸站,或者用于展示自己的摄影作品作为壁纸,那么这个项目应该是很适合你!图片如下:

部署

OK聊了一大堆有的没的,现在进入正题,针对于ChronoFrame,为了更加方便,我将其适配到了我个人的应用商店,欢迎使用,当然也带上了正常的部署方式啦,按需选择!

Docker

首先就是我们最常见的Docker咯,其实项目是给了教程的,但是他喵的配置也忒多了,如下:

环境变量

说明

默认值

必需

CFRAME_ADMIN_EMAIL

初始管理员用户的邮箱

admin@chronoframe.com

CFRAME_ADMIN_NAME

初始管理员用户的用户名

Chronoframe

CFRAME_ADMIN_PASSWORD

初始管理员用户的密码

CF1234@!

NUXT_PUBLIC_APP_TITLE

应用标题

ChronoFrame

NUXT_PUBLIC_APP_SLOGAN

应用口号

NUXT_PUBLIC_APP_AUTHOR

应用作者

NUXT_PUBLIC_APP_AVATAR_URL

应用头像 URL

NUXT_PUBLIC_COLOR_MODE_PREFERENCE

颜色模式偏好,可选 light、dark、system

system

NUXT_PUBLIC_MAP_PROVIDER

地图提供者,可选 mapbox、maplibre

maplibre

NUXT_PUBLIC_MAPBOX_ACCESS_TOKEN

Mapbox 访问令牌(可限制 URL),用于地图服务

当 NUXT_PUBLIC_MAP_PROVIDER 为 mapbox 时必需

NUXT_NOMINATIM_BASE_URL

Nominatim 反向地理编码服务的基础 URL

NUXT_MAPBOX_ACCESS_TOKEN

Mapbox 访问令牌(无 URL 限制),用于位置信息服务

NUXT_STORAGE_PROVIDER

存储提供者,支持 local、s3、openlist

local

NUXT_PROVIDER_LOCAL_PATH

本地存储路径

/app/data/storage

NUXT_PROVIDER_LOCAL_BASE_URL

本地存储的访问 URL

/storage

NUXT_PROVIDER_S3_ENDPOINT

S3 兼容存储服务的 Endpoint

当 NUXT_STORAGE_PROVIDER 为 s3 时必需

NUXT_PROVIDER_S3_BUCKET

S3 存储桶名称

chronoframe

当 NUXT_STORAGE_PROVIDER 为 s3 时必需

NUXT_PROVIDER_S3_REGION

S3 存储桶区域

auto

当 NUXT_STORAGE_PROVIDER 为 s3 时必需

NUXT_PROVIDER_S3_ACCESS_KEY_ID

S3 访问密钥 ID

当 NUXT_STORAGE_PROVIDER 为 s3 时必需

NUXT_PROVIDER_S3_SECRET_ACCESS_KEY

S3 访问密钥

当 NUXT_STORAGE_PROVIDER 为 s3 时必需

NUXT_PROVIDER_S3_PREFIX

S3 存储前缀

photos/

NUXT_PROVIDER_S3_CDN_URL

S3 存储的 CDN 地址

NUXT_PROVIDER_OPENLIST_BASE_URL

OpenList 服务器 URL

当 NUXT_STORAGE_PROVIDER 为 openlist 时必需

NUXT_PROVIDER_OPENLIST_ROOT_PATH

OpenList 根路径

当 NUXT_STORAGE_PROVIDER 为 openlist 时必需

NUXT_PROVIDER_OPENLIST_TOKEN

OpenList API 令牌

当 NUXT_STORAGE_PROVIDER 为 openlist 时必需(用于 OpenList 认证)

NUXT_PROVIDER_OPENLIST_ENDPOINT_UPLOAD

OpenList 上传端点

/api/fs/put

NUXT_PROVIDER_OPENLIST_ENDPOINT_DOWNLOAD

OpenList 下载端点

NUXT_PROVIDER_OPENLIST_ENDPOINT_LIST

OpenList 列表端点

NUXT_PROVIDER_OPENLIST_ENDPOINT_DELETE

OpenList 删除端点

/api/fs/remove

NUXT_PROVIDER_OPENLIST_ENDPOINT_META

OpenList 元数据端点

/api/fs/get

NUXT_PROVIDER_OPENLIST_PATH_FIELD

OpenList 路径字段名

path

NUXT_PROVIDER_OPENLIST_CDN_URL

OpenList CDN 地址

NUXT_PUBLIC_OAUTH_GITHUB_ENABLED

是否启用 GitHub OAuth 登录

false

NUXT_OAUTH_GITHUB_CLIENT_ID

GitHub OAuth 应用的 Client ID

否(可选,用于 GitHub 登录)

NUXT_OAUTH_GITHUB_CLIENT_SECRET

GitHub OAuth 应用的 Client Secret

否(可选,用于 GitHub 登录)

NUXT_SESSION_PASSWORD

用于加密会话的密码,32 位随机字符串

NUXT_PUBLIC_GTAG_ID

Google Analytics 追踪 ID

NUXT_PUBLIC_ANALYTICS_MATOMO_ENABLED

是否启用 Matomo 分析追踪

false

NUXT_PUBLIC_ANALYTICS_MATOMO_URL

Matomo 实例 URL 地址(如: https://matomo.example.com)

否(启用 Matomo 时必需)

NUXT_PUBLIC_ANALYTICS_MATOMO_SITE_ID

Matomo 站点 ID

否(启用 Matomo 时必需)

NUXT_UPLOAD_MIME_WHITELIST_ENABLED

是否启用上传文件 MIME 类型白名单验证

true

NUXT_UPLOAD_MIME_WHITELIST

上传文件允许的 MIME 类型列表(逗号分隔)

见下方说明

NUXT_UPLOAD_DUPLICATE_CHECK_ENABLED

是否启用重复文件检测

true

NUXT_UPLOAD_DUPLICATE_CHECK_MODE

重复文件处理模式,可选 warn、block、skip

skip

ALLOW_INSECURE_COOKIE

是否允许非安全 Cookie(仅在开发环境使用)

false

而且需要在Docker配置或者Docker-compose.yaml写好,无法在后台进行设置,这个是缺点,希望后面作者可以支持在后台配置存储,而不是在应用拉起后硬编码。

回到正题,上面的配置项虽然多,但是也不是所有都得填写,我整理了一份比较完善的大部分可用的启动命令,首先是纯docker:

不会还真有人直接这样启动吧

代码语言:javascript
复制
docker run -d \
  --name chronoframe \
  -p 3000:3000 \
  -v /opt/chronoframe/data:/app/data \
  -e CFRAME_ADMIN_NAME=admin \
  -e CFRAME_ADMIN_EMAIL=admin@example.com \
  -e CFRAME_ADMIN_PASSWORD=StrongPassword123 \
  -e NUXT_SESSION_PASSWORD=$(openssl rand -base64 32) \
  -e NUXT_STORAGE_PROVIDER=local \
  -e NUXT_PROVIDER_LOCAL_PATH=/app/data/storage \
  -e NUXT_PROVIDER_LOCAL_BASE_URL=/storage \
  -e NUXT_UPLOAD_MIME_WHITELIST_ENABLED=false \
  --restart=always \
  ghcr.io/hoshinosuzumi/chronoframe:0.14.1

这里为本地存储,如果你打算将图片存到服务器本地,可以直接启动,修改账号密码和邮箱即可。

如果打算使用S3存储,可以替换下面几个配置为:

代码语言:javascript
复制
-e NUXT_STORAGE_PROVIDER=s3 \
-e NUXT_PROVIDER_S3_ENDPOINT=https://s3.amazonaws.com \
-e NUXT_PROVIDER_S3_BUCKET=my-bucket \
-e NUXT_PROVIDER_S3_REGION=us-east-1 \
-e NUXT_PROVIDER_S3_ACCESS_KEY_ID=xxx \
-e NUXT_PROVIDER_S3_SECRET_ACCESS_KEY=xxx \

如果打算使用OpenList,按照文档修改一下配置就可以啦!当然这里我还是推荐使用docker-compose,配置保存到本地之后会更好看一些,并且方便修改,直接使用docker命令总有点拉屎到服务器的感觉。

如果使用docker-compose,如下配置,我将一些无用配置筛掉了,大家自行选择即可,如果不需要可以留空,compose文件如下:

代码语言:javascript
复制
version: "3.8"

services:
  chronoframe:
    container_name: chronoframe

    image: registry.liiiu.cn/ghcr.io/hoshinosuzumi/chronoframe:0.14.1

    # 端口映射:宿主机 -> 容器
    ports:
      - "3000:3000"   # 可改成 127.0.0.1:3000:3000 仅本机访问

    # 数据持久化
    volumes:
      - ./data:/app/data

    # 自动重启
    restart: always

    environment:
      ########################################
      # ===== 基础管理员配置(必须) =====
      ########################################
      CFRAME_ADMIN_NAME: admin
      CFRAME_ADMIN_EMAIL: admin@example.com
      CFRAME_ADMIN_PASSWORD: admin123

      ########################################
      # ===== 站点 UI 信息(可选) =====
      ########################################
      NUXT_PUBLIC_APP_TITLE: "ChronoFrame"
      NUXT_PUBLIC_APP_SLOGAN: "My Photo Timeline"
      NUXT_PUBLIC_APP_AUTHOR: "YourName"
      NUXT_PUBLIC_APP_AVATAR_URL: ""

      ########################################
      # ===== 地图(不用可以留空) =====
      ########################################
      NUXT_PUBLIC_MAP_MAPLIBRE_TOKEN: ""

      ########################################
      # ===== 存储方式(三选一) =====
      ########################################

      ## 👉 1. 本地存储(推荐)
      NUXT_STORAGE_PROVIDER: local
      NUXT_PROVIDER_LOCAL_PATH: /app/data/storage
      NUXT_PROVIDER_LOCAL_BASE_URL: /storage

      ## 👉 2. S3(不用可以不填)
      NUXT_PROVIDER_S3_ENDPOINT: ""
      NUXT_PROVIDER_S3_BUCKET: ""
      NUXT_PROVIDER_S3_REGION: ""
      NUXT_PROVIDER_S3_ACCESS_KEY_ID: ""
      NUXT_PROVIDER_S3_SECRET_ACCESS_KEY: ""
      NUXT_PROVIDER_S3_PREFIX: ""
      NUXT_PROVIDER_S3_CDN_URL: ""

      ## 👉 3. OpenList(不用可以不填)
      NUXT_PROVIDER_OPENLIST_BASE_URL: ""
      NUXT_PROVIDER_OPENLIST_ROOT_PATH: ""
      NUXT_PROVIDER_OPENLIST_TOKEN: ""
      NUXT_PROVIDER_OPENLIST_ENDPOINT_UPLOAD: ""
      NUXT_PROVIDER_OPENLIST_ENDPOINT_DOWNLOAD: ""
      NUXT_PROVIDER_OPENLIST_ENDPOINT_LIST: ""
      NUXT_PROVIDER_OPENLIST_ENDPOINT_DELETE: ""
      NUXT_PROVIDER_OPENLIST_ENDPOINT_META: ""
      NUXT_PROVIDER_OPENLIST_PATH_FIELD: ""
      NUXT_PROVIDER_OPENLIST_CDN_URL: ""

      ########################################
      # ===== 安全相关(必须) =====
      ########################################
      NUXT_SESSION_PASSWORD: "change_to_random_32_char_secret"

      ########################################
      # ===== 上传策略 =====
      ########################################
      NUXT_UPLOAD_MIME_WHITELIST_ENABLED: "false"

以上就是docker启动的方式啦,如果你使用的是1Panel,我更推荐使用应用商店安装!

应用商店

首先按照之前已经有的教程,添加站长的应用商店:

😃来自本站,本站可确保其安全性,请放心点击跳转

不同姿势部署Anheyu-App应用

LiuShen's Blog

然后搜索Chronoframe即可直接安装啦!

这样你就可以获得一个很完美的相册!

存储

我并不想多讲别的存储,这里我只讲一下我的存储,由于刚开始实在不想单开一个存储桶,维护起来也麻烦,市面上付费的存储桶也没有太多的额度,并且存储和流量都是费用,还得操心是否被打穿,众所周知,存储桶脆的跟纸一样……

ChronoFrame提供了OpenList存储,于是派生了一系列邪修操作,当然大家要注意封号风险哈。

世界没有密不透风的墙,各大网盘商其实都能被OpenList挂载,在这之中,天翼云盘,Onedrive,夸克加会员,都能做到无损的品质,夸克的会员之所以能塞进来,主要因为很便宜啊,可以使用88VIP,不过建议不要去某鱼上买,很容易掉号,夸克会不定期叫你验证,如果到期没验证,会直接停掉会员。

煮啵这里用的是天翼云盘,默认带了30GB存储,可以通过手机端签到实现无限增长存储,一天能领大概60MB,只要电信不封锁这条线路,那我可以一直使用,当然我也套了一层CDN,缓存十年,虽然可能不太准嘻嘻,但是也能大幅度减少回源的概率,希望电信别给我干掉了。

如果有想要开相册的,大家也可以参考一下我的使用方式哦~

总结

喵了个咪的这个文章写了七天才写完,上周天就开始写,这个周又开始玩鱼缸了,每天只动一点点,导致上个月就月初一篇文章,嘻嘻献丑了。

清明时节雨纷纷,这句话在上海彻底体现出来了,天天从公司回家都能赶上暴雨,最后要么淋雨回家,要么熬到十点半打车回,也是没招了,下雨一点征兆都没有。

坏了总结写成碎碎念了,进入正题,其实我最初的想法是,给我一个填写直链的位置即可,为此我甚至找过静态主题,hugo中也有一些很好看的静态相册,但是终究维护起来较难。后面使用了洪哥的TimePlus主题,直接填写直链即可,这个相册跟随了我很长的时间,从刚建站到我的学生生涯结束。

进入工作后,对于成本的控制开始变得松散,只想给网站做好,做精,价格上从之前的肉疼到现在的无感(咳咳,虽然现在依旧是免费的),至少服务器上升级了吧!写文章也佛系了很多,倒不是说没时间写,主要是天天工作后,回来只记得玩手机了,根本不想写嘻嘻,不过一个月一篇是基本的,我尽量做到之前的频率,一个月两三篇,感觉过几个月就能做到啦!目前的工作已经逐渐变平缓,后续应该能多一些个人时间干点自己喜欢的事情!

每日一图

图片来自哲风壁纸

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 碎碎念
  • 介绍
  • 竞品
  • 部署
    • Docker
    • 应用商店
  • 存储
  • 总结
  • 每日一图
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档