可替代 Google Photos/iCloud Photos 的开源解决方案 Ente Photo 图片备份服务Docker部署教程 – 服务端部署

月初看到印度大佬开源了一个图片备份的解决方案,作者把所有的源代码都开源了,包括了移动/Web/桌面客户端、服务器和CLI程序,开源协议为AGPL。我也是持续关注了有一段时间,并尝试进行本地部署,经过几天的使用,整体的体验非常不错。

20240303214919491-photos

官方有专门的文档介绍本地部署,但说实话并不是非常的详细,还是得仔细研究一下整个源代码才行。因此就有了这篇文章,方便感兴趣的朋友们能多了解一下。

Ente开源的源代码涵盖了服务端、CLI管理工具、Web客户端、移动客户端(iOS、Android)、桌面客户端(Win、MacOS、Linux),因此本文也大致按照这个框架进行部署。需要注意的是,源码最近更新非常频繁,如果你对全栈开发不甚了解,建议不要用于正式用途。

克隆源代码

Ente的源代码存储在Github中,本例所有操作都基于这份源代码,所以请提前clone到本地环境中。

git clone https://github.com/ente-io/ente

服务端的部署

在Ente项目中,服务端的命名是museum,个人认为非常有灵性,对此命名官方的说法是:

We named our server museum because for us and our customers, personal photos are worth more than any other piece of art.

服务端museum的源码存放在源码路径下的server目录,依赖项只有一个postgres数据库,用户图片存储在官方教程里是使用本地minio自建的S3对象存储。而我是直接把Ente当作正经项目运行,因此我是直接在Backblaze创建一个存储桶用于图片的存储。

此外,还需要了解museum最为重要的配置文件,需要了解它的逻辑。详细说明可以浏览local.yaml文件的头部,路径在 /server/configurations/local.yaml,在前面的几十行注释里面,详细描述了如何通过配置文件对服务端进行修改。

# Configuring museum
# ------------------
#
# 1. If the environment variable `ENVIRONMENT` is specified, then it is used to
#    load one of the files from the `configurations/` directory. If not present,
#    then by default `local.yaml` (this file) will get loaded.
#
# 2. Then, museum will look for a file named `museum.yaml` in the current
#    working directory. If found, this file will also be loaded, and entries
#    specified therein will override the defaults specified here.
#
# 3. If the "credentials-file" config option is set, then museum will also load
#    that and merge it in.
#
# 4. Config can be overridden with via environment variables (details below).
#
# Environment variables
# ---------------------
#
# All configuration options can be overridden via environment variables. The
# environment variable should have the prefix "ENTE_", and any nesting should be
# replaced by underscores.
#
# For example, the nested string "db.user" in the config file can alternatively
# be specified (or be overridden) by setting an environment variable named
# ENTE_DB_USER.
#
#
# Empty strings
# -------------
#
# The empty string indicates missing values (to match go convention).
#
# This also means that to override a value that is specified in local.yaml in a
# subsequently loaded config file, you should specify the key as an empty string
# (`key: ""`) instead of leaving it unset.
#
# ---

# If this option is specified, then it is loaded and gets merged-in over the
# defaults present in default.yaml. This provides a way to inject credentials
# and other overrides.
#
# The default is to look for a file named credentials.yaml in the CWD.
#credentials-file: credentials.yaml

# Some credentials (e.g. the TLS cert) are cumbersome to provide inline in the
# YAML configuration file, thus these are loaded at runtime from separate files.
#
# This is the directory where museum should look for them.
#
# Currently, the following files are loaded (if needed)
#
# - credentials/{tls.cert,tls.key}
# - credentials/pst-service-account.json
# - credentials/fcm-service-account.json
#
# The default is to look for a these files in a directory named credentials
# under the CWD.
#credentials-dir: credentials

TL;DR

简单来说,系统存在一个默认的配置文件以及默认的配置项,如果没有明确定义环境,那么加载local.yaml作为默认环境;可通过museum.yaml文件或credentials-file文件对配置进行合并覆盖;也声明了环境变量具有最高的优先级,环境变量需要使用ENTE_的前缀,且需要转换为大写字母,标点符号需转换为下划线;还有也明确了空值的定义,反过来也就是说,默认配置项你可以不动,只需要提供你想变更的配置项内容即可。

注意⚠️,按以下内容进行服务部署,后续使用可能会因使用了商用的S3存储而产生费用。

服务端museum和postgres数据库直接使用docker compose进行部署,图片存储使用Backblaze b2存储桶,没有开启异地多存储桶备份。开始吧!

创建Backblaze b2存储桶

首先前往Backblaze官方网站注册账户,注册过程这里略过。然后到后台创建一个存储桶,注意这里存储桶的类型要使用private。

20240325175308889-WX20240325-175230

创建完成之后到Application Keys菜单,创建一个专属于该存储桶的密钥对,并保存到安全的地方,待会要用到。

20240325175807491-WX20240325-175651
20240325180030592-WX20240325-175756
20240325180056650-WX20240325-175925

部署服务端程序

服务端包含Ente的museum程序和postgres的数据库,使用Docker Compose进行部署,服务端ente-server使用的镜像是基于Ente最新源代码进行打包的,没有添加任何东西,只是为了方便部署。如果你对安全性有疑虑,可以自行打包。挂载的volume存储卷也都是当前目录内。这样如果需要对服务端进行迁移,就只需要停止docker,再打包这个目录迁移到新服务器就好了。

首先在服务器端的/opt路径创建ente文件夹,你也可以在其他路径创建,这个没有要求,本例放在/opt/ente。

mkdir -p /opt/ente-server

然后创建docker-compose.yml

version: "3.3"

services:
  museum:
    image: icodex/ente-server:latest
    ports:
      - 8080:8080 # API
      - 2112:2112 # Prometheus metrics
    depends_on:
      postgres:
        condition: service_healthy
    volumes:
      - ./logs:/var/logs
      - ./museum.yaml:/museum.yaml:ro
    networks:
      - internal

  postgres:
    image: postgres:12
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: pguser
      POSTGRES_PASSWORD: pgpass
      POSTGRES_DB: ente_db
    healthcheck:
      test: ["CMD", "pg_isready", "-q", "-d", "ente_db", "-U", "pguser"]
      interval: 1s
      timeout: 5s
      retries: 20
    volumes:
      - ./postgres-data:/var/lib/postgresql/data
    networks:
      - internal

networks:
  internal:

然后在同目录下创建museum.yaml文件,输入以下内容:

log-file: /var/logs/museum.log

db:
    host: postgres
    port: 5432
    name: ente_db
    user: pguser
    password: pgpass

s3:
    are_local_buckets: false
    b2-eu-cen:
        key: 00000000000000000000000001
        secret: w7q3begvx6gyx4+8d85ImiV1/OO+v+s
        endpoint: s3.us-west-004.backblazeb2.com
        region: us-west-004
        bucket: entephoto-evlit

key:
    encryption: yvmG/RnzKrbCb9L3mgsmoxXr9H7i2Z4qlbT0mL3ln4w=
    hash: KXYiG07wC7GIgvCSdg+WmyWdXDAn6XKYJtp/wkEU7x573+byBRAYtpTP0wwvi8i/4l37uicX1dVTUzwH3sLZyw==

jwt:
    secret: i2DecQmfGreG6q1vBj5tCokhlN41gcfS2cjOs9Po-u8=

smtp:
    host: wednesday.mxrouting.net
    port: 587
    username: no-reply@ente.io
    password: xxxxxxxxxx

文件为yaml格式,要注意缩进。有几个配置项你需要根据你的实际情况进行填写,有这些:

1. s3存储桶信息,需要修改的内容有这些:

b2-eu-cen:
        key: Application Keys对应存储桶的keyID
        secret: Application Keys对应存储桶的applicationkeys
        endpoint: 存储桶的endpoint
        region: 一般是endpoint的中间那段
        bucket: 你的存储桶名称

注意,b2-eu-cen这个名称不能改。

2. 一些加密密钥、盐、以及jwt私钥这些,可以通过在server目录下运行命令go run tools/gen-random-keys/main.go生成。然后替换。

20240325191234317-WX20240325-191224

全部检查没问题之后,执行docker compose运行服务端吧!

docker compose up -d

最后

服务端部署完毕之后,业务运行在8080端口,如需更改端口,可以在docker-compose.yml做出更改。使用时一般建议在它前面在放一个nginx,接管http和https的流量,也方便维护https证书这些操作。域名这里可以用 api 的子域名,毕竟它是作为后端用的。后续的各种客户端连接的endpoint也都是填这个地址。

反向代理可以按以下的nginx配置进行:

location ^~ /
{
    proxy_pass http://127.0.0.1:8080;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_set_header X-Forwarded-Proto $scheme;
}

另外,如果使用了https证书,在操作存储桶的时候,你会遇到跨域问题,可以通过b2命令行工具进行修改。注意⚠️,修改Cors需要的权限比较高,需要使用Master Application Key,注意不要跟业务用的混淆了。

首先到这个网址下载b2命令行工具,例如用brew

brew install b2-tools

然后命令行输入

b2 authorize-account

依次输入keyID和applicationKey。

然后输入以下命令,更新存储桶的配置。

b2 update-bucket --corsRules '[
    {
        "corsRuleName": "entephoto",
        "allowedOrigins": [
            "*"
        ],
        "allowedHeaders": [
            "*"
        ],
        "allowedOperations": [
            "s3_delete",
            "s3_get",
            "s3_head",
            "s3_post",
            "s3_put"
        ],
        "exposeHeaders": [
            "ETag",
            "Content-Length"
        ],
        "maxAgeSeconds": 3600
    }
]' entephoto allPrivate

注意更改以上命令行中的出现的存储桶名称,即entephoto,改为你自己的存储桶名称,第二个参数allPrivate是存储桶的权限,默认给私有。执行之后没有报错就可以了。

20240325232439686-WX20240325-232427@2x

或使用s3兼容的命令行的方式进行修改。引用来源

首先创建cors.json文件

{
    "CORSRules": [
        {
            "AllowedOrigins": ["*"],
            "AllowedHeaders": ["*"],
            "AllowedMethods": ["GET", "HEAD", "POST", "PUT", "DELETE"],
            "MaxAgeSeconds": 3000,
            "ExposeHeaders": ["Etag"]
        }
    ]
}

然后执行命令:

aws s3api put-bucket-cors --bucket YOUR_S3_BUCKET --cors-configuration file://cors.json

然后还有一个问题,默认情况下,没有默认用户的,每个用户都是需要输入邮箱,获取验证码的方式进行,需要另外配置邮件(如需配置,则需要使用SMTP或是zoho的Zeptomail),如果没有配置邮件,则可以通过读取日志文件的方式,获得某个用户的验证码,或使用读取数据库的otts表(引用来源

20240325195055621-WX20240325-195042

除此之外,官方在local.yaml还有一个方案,但我认为这个方案放在公网上非常不安全,建议大家不要使用。官方的说明是:

# Hardcoded verification codes, useful for logging in when developing.
#
# Uncomment this and set these to your email ID or domain so that you don't
# need to peek into the server logs for obtaining the OTP when trying to log
# into an instance you're developing on.
# hardcoded-ott:
#     emails:
#         - "example@example.org,123456"
#     # When running in a local environment, hardcode the verification code to
#     # 123456 for email addresses ending with @example.org
#     local-domain-suffix: "@example.org"
#     local-domain-value: 123456

意思就是,对特定邮箱采取返回固定验证码的方式。建议不要这么玩咯。

客户端的教程

web客户端的部署教程:https://www.evlit.com/67228.html

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 共3条
头像
说说你的看法!
提交
头像

昵称

取消
昵称表情代码图片
    • 头像chu0
    • 头像ken0
    • 头像删除记忆0