There's no cloud. It's just someone else's computer. 本文介绍如何使用 PhotoPrism 搭建你自己的「云」相册,让你无需再依赖大公司那并不可靠的云。

一、不可靠的云

曾经有一段时间,互联网用户享受了诸多「云」的红利:

  • 2013 年 5 月,财大气粗的 Yahoo! 收购 Flickr 之后,向免费用户开放 1 TB 的照片存储。
  • 2015 年 3 月,Amazon 推出仅售 11.99 USD/y 支持无限照片存储的 Amazon Cloud Drive。
  • 2015 年 5 月,推出主打免费无限存储人工智能照片识别的 Google Photos。对于 Pixel 用户,Google Photos 更是支持无限原图存储。

然而……

……以及最近的新闻:

这一切都在呐喊:云并不可靠。也许云可以作为一个额外的数据冗余选项,但绝对不能信任它为唯一的备份。

二、自建相册服务的痛点

相信不少阅读本博客的读者家里都是有服务器的,也会在自己的服务器上保存照片之类的重要数据。但如何展示这些照片呢?老实说,我自己的照片虽然有至少 5 份冗余,但是每当我需要找什么历史照片的时候,还是会打开 Flickr 和 Google Photos,而不是访问 NAS。仔细分析,我对相册服务的需求主要有:

  • 多平台、多设备(电脑、手机、平板、电视机等)访问。
  • 不改动文件和目录结构:我现在已经有一整套备份流程了,大部分都依赖固定的路径进行增量检测。
  • 能方便地共享一部分照片发给不在同一个局域网里的人。

这三个需求基本排除了各类本地照片管理软件,我的眼光只能望向各种网页服务。我曾尝试过 ownCloud/nextCloud 以及 Piwigo 之类的自建相册软件,但皆不够满意,这件事也就一直拖延下去了。前段时间看到 @virushuo 推荐了 PhotoPrism,但是当时太忙并未尝试。这两天终于有机会尝试了一下,发现这个项目完美地符合了我所有的需求。至于为啥我之前没发现呢?这个项目第一个 commit 是 2018 年的……

受益于机器学习的发展,PhotoPrism 使用 TensorFlow 对照片进行本地识别,让用户可以在不连接互联网的情况下也能像用那些大公司的云相册一样用自然语言搜索照片。不过 PhotoPrism 最打动我的地方是它可以只读方式运行,完全不修改任何照片文件,而是把 metadata 等信息单独存放。PhotoPrism 解析出的数据除了存在它自己的数据库里,默认也以 YAML 的方式额外存一份(Sidecar)。即使未来 PhotoPrism 停止维护,这些数据也依然可以方便地读取和解析。

三、PhotoPrism 的安装与配置

与那些在 Docker 生态发展完备之前开发的软件不同,PhotoPrism 开发之初就已经是为 Docker 设计的了,因此 PhotoPrism 可以方便地运行于任何支持 Docker 的平台。

官方提供了一个 docker-compose.yml,所有的配置都在里面了。我修改了这些默认值:

diff --git a/docker-compose.yml b/docker-compose.yml
index 162a025..00d3357 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -45,3 +45,3 @@ services:
     environment:
-      PHOTOPRISM_ADMIN_PASSWORD: "insecure"          # PLEASE CHANGE: Your initial admin password (min 4 characters)
+      PHOTOPRISM_ADMIN_PASSWORD: "photoprism"        # PLEASE CHANGE: Your initial admin password (min 4 characters)
       PHOTOPRISM_ORIGINALS_LIMIT: 5000               # File size limit for originals in MB (increase for high-res video)
@@ -50,3 +50,3 @@ services:
       PHOTOPRISM_PUBLIC: "false"                     # No authentication required (disables password protection)
-      PHOTOPRISM_READONLY: "false"                   # Don't modify originals directory (reduced functionality)
+      PHOTOPRISM_READONLY: "true"                    # Don't modify originals directory (reduced functionality)
       PHOTOPRISM_EXPERIMENTAL: "false"               # Enables experimental features
@@ -63,4 +63,4 @@ services:
       PHOTOPRISM_DATABASE_USER: "photoprism"         # MariaDB database user name
-      PHOTOPRISM_DATABASE_PASSWORD: "insecure"       # MariaDB database user password
-      PHOTOPRISM_SITE_URL: "http://localhost:2342/"  # Public PhotoPrism URL
+      PHOTOPRISM_DATABASE_PASSWORD: "photoprism"     # MariaDB database user password
+      PHOTOPRISM_SITE_URL: "https://photoprism.wzyboy.net/"  # Public PhotoPrism URL
       PHOTOPRISM_SITE_TITLE: "PhotoPrism"
@@ -78,3 +78,3 @@ services:
       # Your photo and video files ([local path]:[container path]):
-      - "~/Pictures:/photoprism/originals"
+      - "/media/home2/wzyboy/Photos:/photoprism/originals:ro"
       # Multiple folders can be indexed by mounting them as sub-folders of /photoprism/originals:
@@ -85,3 +85,3 @@ services:
       # Permanent storage for settings, index & sidecar files (DON'T REMOVE):
-      - "./storage:/photoprism/storage"
+      - "/media/data/photoprism/storage:/photoprism/storage"

@@ -96,3 +96,3 @@ services:
     volumes: # Don't remove permanent storage for index database files!
-      - "./database:/var/lib/mysql"
+      - "/media/data/photoprism/database:/var/lib/mysql"
     environment:
@@ -101,3 +101,3 @@ services:
       MYSQL_USER: photoprism
-      MYSQL_PASSWORD: insecure
+      MYSQL_PASSWORD: photoprism

然后 docker-compose up -d 就可以把 PhotoPrism 跑起来了。默认是监听 localhost 的,用 Nginx 加个反代,即可从外部访问并启用 HTTPS。

在上述配置中,PhotoPrism 是以只读模式(PHOTOPRISM_READONLY: true) 运行的,并且挂载的照片目录也是以只读方式(:ro)挂载的,但 storage 目录必须是 rw 的,并且请预留足够多的空间。PhotoPrism 会为每张照片生成 7 个不同尺寸的缩略图,如果你的照片很多的话,这些缩略图的总大小不容小觑。

此外,在上述配置中,MySQL 只有 PhotoPrism 可以访问到,所以用弱密码也没关系,但是当 PhotoPrism 启动之后,建议立刻在网页上或是用 docker exec photoprism photoprism passwd 修改初始密码。

PhotoPrism 成功运行之后,需要进行首次索引。索引可以在网页端触发,也可以用 docker exec photoprism photoprism index 命令触发。这个过程中,PhotoPrism 会为每一张照片生成缩略图,解析 metadata(包括用 TensorFlow 生成自然语言标签)并写入数据库以及 YAML 文件。在我的 Gen10 Plus 上,处理速度大概是一秒一张,我的三万张照片大概要处理 8 个多小时的样子。

四、迁移至 PhotoPrism

对于我来说,在我使用 PhotoPrism 之前,我所有的照片在本地已经有一份,新产生的照片也会通过 rsync 和 Syncthing 从手机和相机流入 NAS 里,再经由 BorgBackuprclone 做异地备份。因此当我决定开始用 PhotoPrism 的时候,我只要把 NAS 上的照片目录只读挂载到 PhotoPrism 里就算完事了,其他工作流不用变动。

如果你没有一个集中的本地照片存储,而是直接把照片「备份」到各种「云相册」服务的话,PhotoPrism 提供了对 Google PhotosApple PhotosFlickr 的导入支持。这种情况下,你也许可以考虑以读写模式运行 PhotoPrism 然后再导入你过去的照片。至于你未来的照片,则可以通过 WebDAV 这类开放协议从手机/相机同步,或是借助 Dropbox 曲线救国。当然,无论用哪种方式,对 PhotoPrism 本身的备份是不可少的。


欢迎留下评论。评论前,请先阅读《隐私声明》。