ChronoFrame - 一款优雅的瀑布流相册系统
碎碎念
一个月没有更新文章啦,不过放心,煮啵不是似了,煮啵只是染上了Arch瘾在捣鼓新系统呢!虽然过程不是很顺利,结果也不是很顺利,但是起码也是玩过的人了,本来打算玩明白了写一个对应的教程,但是玩明白之后,自己先逃离了,倒不是说没配置好,主要是很多软件都没有,维护也不太行,比如腾讯视频,网易邮箱大师……诸如此类的应用还有很多,Arch确实很漂亮,也很符合我的开发习惯,但是,还有很大的进步空间哦~
(等煮啵研究一下能不能刷个MacOS,这个总不缺生态了吧,哼哼)
这一个月,虽然一直在研究新系统,但也不是一点没碰网站,由于嫖上了群友的ChatGPT组织,反倒写代码更多了,比如前面的兰空图床美化,还有煮啵自己的临时邮箱,再就是新相册,相册是我最喜欢的网站之一,他承载了我之前的记忆,之前的相册由于玩崩了,所以干脆没迁移,从头开始新整了一个相册,尽可能将之前的一些照片搬了上来,全新的系统有了更大的维护需求,原来的Typecho只需要填写直链即可,现在的相册主要手动上传原图,他会自动生成缩略图,虽然说更加的系统化,但是对于存储的要求也更高啦,最后煮啵找到了一个更好的方案,基本摆脱了未来的存储焦虑!
介绍
首先放上项目地址,项目的配置较多,如果看到这里溜了的小伙伴要自己看好哦!
这个项目的灵感来自一个同样很优秀的开源项目 —— Afilmory。
Afilmory更偏向于“静态相册”的思路:通过预处理照片生成清单文件,然后以静态站点的形式进行展示。这种方式部署简单、成本低,非常适合纯展示类需求。
而ChronoFrame在此基础上走向了另一个方向:它不是一个“生成好的相册”,而是一个真正可以在线管理的动态照片系统。
相比传统相册项目,ChronoFrame不仅可以上传、整理和浏览照片,还能自动解析EXIF、展示拍摄位置、在地图上回溯足迹,虽然说我目前对这个功能不太满意,由于它支持自动生成缩略图,所以在大尺寸图片下依然保持非常丝滑的浏览体验。
下面是俺自己的地址:
如果你只是想做一个静态展示站,Afilmory可能已经足够,但如果你希望拥有一个可以长期使用、持续管理、并且体验优秀的个人相册系统,那 ChronoFrame会是一个更值得尝试的选择。
竞品
竞品?实则是项目介绍!
在刚开始建立相册的时候,我找了很多相册程序,那时候的相关程序远没有现在这么丰富,所以我甚至研究了博客程序的相册主题,比如洪哥的TimePlus,地址如下:
对于之前的我来说,这款主题十分合适,只需要填写图片直链和对应信息即可完美的实现展示的功能,虽然说精度不是很高,但是对于只想展示照片的我已经是够够的啦,配合piclist和自建的兰空图床,可以做到存储的极致轻量化。
后面,随着Typecho的更新和主题的更新,作为强迫症的我,势必要用上最新的系统,但是我又懒得去配置一些环境,并且由于PHP众所周知的特性,安全性也较差,再加上对接的数据库,内存占用也比较严重,已经工作了的我可没这么多闲时间耗,我直接一个雷霆大踹给项目踢飞了,找了一些同类型的竞品项目,如下:
这个项目并不算是一个真正意义上的的开放性展示相册,而像是一个个人备份相册,后台需要密码才能进入,虽然说可以分享相册对外展示,但是路径仍然不是根目录,如果没有途径获取到你的分享链接,也无法查看。是一个优秀的项目,但不是我想要的效果。
下面我比较关注的项目就是PicImpact啦,这个是一个彻底的相册站,由NextJS开发,支持S3,R2,OpenList等多种存储方式,上传图像时会自动抓取EXIF进行信息获取,比如拍照位置,拍照设备,图像大小,并按照美观的展示方式进行展示。
从一个相册的角度来看,这个程序已经具有基本上所有的功能,但是不知道为什么,我看issue中的演示站,总感觉卡卡的,并且按照我个人的审美而言,我更喜欢瀑布流展示,PicImpact虽然也有瀑布流,但是只能在时光相册页面看到,整体页面很清爽,但是个人不太喜欢(纯主观),如下:
下面就是Afilmory了,其实刚发现他的时候,我并不知道他只能通过获取列表展示,我还以为是后台上传显示,但是由于那时候还是学生的我没法负担起较高价格的存储,虽然说免费的少量存储很多,但是对于我来说,更在乎服务的持续性,我不想使用那种一眼看到头的服务,所以就一直搁置。
虽然我到最后也没使用过,但是这并不影响他是一个很优秀的相册程序,项目地址如下:
注意,这个程序官方并没有提供Docker镜像,所以可能需要自己打包一个哦,当然官方也带托管,感兴趣可以去体验一下!
由于没有给docker镜像,所以我也不太清楚后台功能有多少,需要大家自行探索咯。
除了这个,我还发现了一个相册站,与其说是相册站,不如说是壁纸站,并且自带图源,可以直接搭建一个免维护,带登录功能的图片采集站,不仅可以自己上传图片,也可以实现自动聚合各类壁纸,比如每日一图Bing等等,项目如下:
如果你想做一个偏商业化的壁纸站,或者用于展示自己的摄影作品作为壁纸,那么这个项目应该是很适合你!图片如下:
部署
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 | https://nominatim.openstreetmap.org | 否 |
| 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:
不会还真有人直接这样启动吧
1 | docker run -d \ |
这里为本地存储,如果你打算将图片存到服务器本地,可以直接启动,修改账号密码和邮箱即可。
如果打算使用S3存储,可以替换下面几个配置为:
1 | -e NUXT_STORAGE_PROVIDER=s3 \ |
如果打算使用OpenList,按照文档修改一下配置就可以啦!当然这里我还是推荐使用docker-compose,配置保存到本地之后会更好看一些,并且方便修改,直接使用docker命令总有点拉屎到服务器的感觉。
如果使用docker-compose,如下配置,我将一些无用配置筛掉了,大家自行选择即可,如果不需要可以留空,compose文件如下:
1 | version: "3.8" |
以上就是docker启动的方式啦,如果你使用的是1Panel,我更推荐使用应用商店安装!
应用商店
首先按照之前已经有的教程,添加站长的应用商店:
然后搜索Chronoframe即可直接安装啦!
这样你就可以获得一个很完美的相册!
存储
我并不想多讲别的存储,这里我只讲一下我的存储,由于刚开始实在不想单开一个存储桶,维护起来也麻烦,市面上付费的存储桶也没有太多的额度,并且存储和流量都是费用,还得操心是否被打穿,众所周知,存储桶脆的跟纸一样……
ChronoFrame提供了OpenList存储,于是派生了一系列邪修操作,当然大家要注意封号风险哈。
世界没有密不透风的墙,各大网盘商其实都能被OpenList挂载,在这之中,天翼云盘,Onedrive,夸克加会员,都能做到无损的品质,夸克的会员之所以能塞进来,主要因为很便宜啊,可以使用88VIP,不过建议不要去某鱼上买,很容易掉号,夸克会不定期叫你验证,如果到期没验证,会直接停掉会员。
煮啵这里用的是天翼云盘,默认带了30GB存储,可以通过手机端签到实现无限增长存储,一天能领大概60MB,只要电信不封锁这条线路,那我可以一直使用,当然我也套了一层CDN,缓存十年,虽然可能不太准嘻嘻,但是也能大幅度减少回源的概率,希望电信别给我干掉了。
如果有想要开相册的,大家也可以参考一下我的使用方式哦~
总结
喵了个咪的这个文章写了七天才写完,上周天就开始写,这个周又开始玩鱼缸了,每天只动一点点,导致上个月就月初一篇文章,嘻嘻献丑了。
清明时节雨纷纷,这句话在上海彻底体现出来了,天天从公司回家都能赶上暴雨,最后要么淋雨回家,要么熬到十点半打车回,也是没招了,下雨一点征兆都没有。
坏了总结写成碎碎念了,进入正题,其实我最初的想法是,给我一个填写直链的位置即可,为此我甚至找过静态主题,hugo中也有一些很好看的静态相册,但是终究维护起来较难。后面使用了洪哥的TimePlus主题,直接填写直链即可,这个相册跟随了我很长的时间,从刚建站到我的学生生涯结束。
进入工作后,对于成本的控制开始变得松散,只想给网站做好,做精,价格上从之前的肉疼到现在的无感(咳咳,虽然现在依旧是免费的),至少服务器上升级了吧!写文章也佛系了很多,倒不是说没时间写,主要是天天工作后,回来只记得玩手机了,根本不想写嘻嘻,不过一个月一篇是基本的,我尽量做到之前的频率,一个月两三篇,感觉过几个月就能做到啦!目前的工作已经逐渐变平缓,后续应该能多一些个人时间干点自己喜欢的事情!
每日一图
图片来自哲风壁纸



















