Ente 和 Immich 都是知名的开源 Google Photos 替代品,可以进行自托管个人相册服务,将数据掌握在自己手中。
我选择 Ente 的原因:
- 端到端加密,有效保护数据隐私
- 移动端 APP 没有烦人的服务端升级提示
- 可以接入 S3 存储
本文记录如何自托管 Ente Photos 个人相册服务
一、安装
这里使用 Docker Compose 来安装 Ente,其他安装方式可以参考官方文档
1.1 克隆仓库
git clone https://github.com/ente-io/ente1.2 配置文件
创建配置文件
cd ente/server/configcp example.env .envcp example.yaml museum.yaml相应地更改 .env 文件和 museum.yaml 文件中的值
1.3 启动服务
compose.yaml 是容器编排文件,可以按需修改。
docker compose up --build二、反向代理
在手机端登录时,连点 Ente Logo 就可以出现自托管配置,然后输入后端服务地址即可。
我这里使用 Nginx 的配置样例
Ente 后端服务
server { listen 443 ssl; listen [::]:443 ssl; server_name ente.example.com; root /var/www/example.com/public;
# SSL ssl_certificate /opt/cert/*.example.com.crt; ssl_certificate_key /opt/cert/*.example.com.key;
# security include nginxconfig.io/security.conf;
# logging access_log /var/log/nginx/access.log combined buffer=512k flush=1m; error_log /var/log/nginx/error.log warn;
# reverse proxy location / { proxy_pass http://127.0.0.1:8080; client_max_body_size 10240M; include nginxconfig.io/proxy.conf; }
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|svg|webp|avif)$ { proxy_pass http://127.0.0.1:8080; expires 30d; }
location ~ .*\.(js|css)?$ { proxy_pass http://127.0.0.1:8080; expires 12h; }
# additional config include nginxconfig.io/general.conf;}
# HTTP redirectserver { listen 80; listen [::]:80; server_name ente.example.com; return 301 https://ente.example.com$request_uri;}Ente 前端服务
server { listen 443 ssl; listen [::]:443 ssl; server_name enteweb.example.com; root /var/www/example.com/public;
# SSL ssl_certificate /opt/cert/*.example.com.crt; ssl_certificate_key /opt/cert/*.example.com.key;
# security include nginxconfig.io/security.conf;
# logging access_log /var/log/nginx/access.log combined buffer=512k flush=1m; error_log /var/log/nginx/error.log warn;
# reverse proxy location / { proxy_pass http://127.0.0.1:3000; client_max_body_size 3072M; include nginxconfig.io/proxy.conf;
add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; script-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline' 'unsafe-eval';";
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|svg|webp|avif|woff2)$ { proxy_pass http://127.0.0.1:3000; expires 30d;
add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; script-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline' 'unsafe-eval';"; }
location ~ .*\.(html|js|css)?$ { proxy_pass http://127.0.0.1:3000; expires 12h;
add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; script-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline' 'unsafe-eval';"; }
# additional config include nginxconfig.io/general.conf;}
# HTTP redirectserver { listen 80; listen [::]:80; server_name enteweb.example.com; return 301 https://enteweb.example.com$request_uri;}三、给自托管用户配置容量
自托管用户默认初始容量是 10G,需要通过 CLI 工具进行给指定用户增加容量
3.1 安装 Ente CLI
从 GitHub releases 下载 CLI
定义 config.yaml 并将其放置在 ~/.ente/ 或 ENTE_CLI_CONFIG_DIR 指定的目录,或 Ente CLI 所在的目录。
# Set the API endpoint to your domain where Museum is being served.endpoint: api: https://ente.example.com3.2 配置管理员
查询数据库需要设置为管理员的 user ID
SELECT * from users;增加 museum.yaml 文件的配置:
- 多个管理员:
internal: admins: - <user_id>- 单个管理员:
internal: admin: <user_id>然后重启服务
docker compose down && docker compose up -d3.3 在 CLI 登录账户
这将提示输入身份验证详细信息和导出目录
ente account add3.4 配置容量
设置无限存储和有效期
<admin-user-mail>管理员邮箱<user-email-to-update>用户邮箱
ente admin update-subscription -a <admin-user-mail> -u <user-email-to-update> --no-limit四、Backblaze B2 配置
如果是你使用 Backblaze B2 作为 S3 来给 Ente 存储照片,那么还需要进行一些设置,否则在 Ente 网页端无法显示照片。
4.1 命令行工具
首先安装 b2 命令行工具,这里以 Linux 操作系统为例,其他操作系统可以参考官方文档: Install the Backblaze B2 Command-Line Tool
wget https://github.com/Backblaze/B2_Command_Line_Tool/releases/latest/download/b2-linux -O b2 && chmod +x b2配置 b2 密钥,这里的密钥需要是 Master Application Key 才能操作 bucket
b2 account authorize [applicationKeyId] [applicationKey]4.2 CORS 配置
在当前目录新建一个 CORS 配置:rules.json
配置说明可参考官方文档: Enable CORS with the CLI
[ { "corsRuleName": "entephotos", "allowedOrigins": [ "*" ], "allowedHeaders": [ "*" ], "allowedOperations": [ "b2_download_file_by_id", "b2_download_file_by_name", "b2_upload_file", "b2_upload_part", "s3_get", "s3_post", "s3_put", "s3_head" ], "exposeHeaders": [ "X-Amz-Request-Id", "X-Amz-Id-2", "ETag" ], "maxAgeSeconds": 3600 }]将 CORS 配置更新到 bucket
b2 bucket update --cors-rules "$(<./rules.json)" [bucketName] allPrivateallPrivate 是指设置为私有 bucket,allPublic 则是公开 bucket
参考资料