作为一个萌新小白也想搭个内网照片站,转了一圈,也挑花了眼,最终还是选则了 Immich ,各种踩坑之后,算是基本跑起来了,贴一下我的部署方案吧,也算是做个笔记,刚入坑,非科班专家,求大佬们多多指点,轻喷 [Grin]
设备:
- J4105 4G 一个( Debian 12 ),角色定位:AIO ,计算
- 威联通 TS216 一台,角色定位:存储+数据
思路:本着分散计算和存储的 Old-School 传统,没把 Immich 直接扔到威联通的 Container Station 里面,而是把 Server 端,Maching-Learning ,Redis 这些都放到 AIO 上了,威联通上仅仅跑了 PostgreSQL 一个容器,然后为了方便查看,我还在 AIO 上启了 pgadmin4 这个 Container ,Immich 和 pgadmin4 都用 Nginx 做了反代,基本这样。
流程:
-
AIO 里面安装 Docker (按官方教程装的,需要配置 apt 源)
-
AIO 里面 apt 安装 Redis
-
AIO 里面 Redis 配置文件修改,绑定 docker 桥接网卡地址,并开启密码模式( Redis 非 lo 接口连接都需要密码)
-
AIO 里面 apt 安装 Nginx
-
TS216 装载 M2 Nvme SSD 并新建静态卷,静态卷里面创建名为 Container 的共享文件夹( PostgreSQL 数据库会放到这里)
-
TS216 里面安装 Container Station ,指定容器卷存储位置为上一步静态卷上的 Container 文件夹
-
TS216 Container Station 里面部署 Immich 要求的加了 vector extention 的 PostgreSQL
-
AIO Docker 启动 pgadmin4 Container (方便随后建库给 Immich 用,账号密码用上一步 compose 里面的,下面有贴出来)
-
AIO 登录 pgadmin4 web 界面,连接上 TS216 的 PG 后建库
immich, 配置用默认的,我还 grant all 权限了 -
AIO 里面新建用户 immich:immich (记下 uid 和 gid ,通常一样的)
-
TS216 里面 ssh 登录,sudo 模式指定 uid 新建完全一致用户 immich:immich (重点是 uid 和 gid 与 AIO 上完全一致,否则后面 nfs 挂载会对不上权限)
-
TS216 QFirewall 防火墙里面新建规则,放行内网网段 5432/TCP 入站
-
TS216 新建 Shared Folder 名称为
/Immich,导出为 NFS ,NFS 权限选 all squash 到 immich:immich 这个用户 -
AIO 里面递归创建目录 /var/lib/immich-app/library
-
把 immich 官方文档里面的 docker-compose.yml 和 example.env 下载下来到 immich-app 目录,example.env 重命名为 .env
-
用 chmod -R 模式把 library 目录变更用户为 immich:immich
-
编辑 /etc/fstab 并挂载从 TS216 导出的 NFS 目录到 /mnt/Immich
-
执行 systemctl daemon-reload 重新挂载 fstab
-
执行 mount -a 测试是否成功挂载
/Immichnfs 文件夹(没报错表示成功) -
把 library 目录移入 /mnt/Immich
注意此时 /mnt/Immich 在 TS216 上是指定的 immich:immich 用户,所以不能放其他用户的文件进去,我没试过,但应该是有权限问题的
-
Nginx 添加 /etc/nginx/conf.d/immich.conf 反代 Immich 到 80 端口(我还有其他的服务都部署的 80 ,而且也不想用端口访问 Immich )
大体上就是这些了,然后就是一些关键配置:
一、TS216 上的 compose 配置,只启了 PG
version: '3'
services:
postgres:
image: tensorchord/pgvecto-rs:pg16-v0.1.11
restart: unless-stopped
ports:
- 5432:5432
volumes:
- postgres_db:/var/lib/postgresql/data
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
postgres_db:
这里面重要的点主要是三个:
- image 必须选
tensorchord/pgvecto-rs:pg16-v0.1.11这个,用 PG 官方镜像的话不支持,因为 Immich 用到了 PG 的 vector 特性 - 端口映射,不能绑定 docker0 的地址,因为需要让 AIO 从内网连进来,绑定 docker0 接口的话就连不了了,防火墙开了也没用
- PG 的账号密码,这个随便填,但是后面部署到 AIO 上面的 pgadmin4 里面要用到
二、AIO 上的 /var/lib/immich-app/docker-compose.yml 配置,用于 Immich server 端
version: "3.8"
name: immich
services:
immich-server:
container_name: immich_server
user: "${UID}:${GID}"
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
command: [ "start.sh", "immich" ]
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
ports:
- 127.0.0.1:2283:3001
restart: unless-stopped
immich-microservices:
container_name: immich_microservices
user: "${UID}:${GID}"
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
# extends:
# file: hwaccel.yml
# service: hwaccel
command: [ "start.sh", "microservices" ]
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
restart: unless-stopped
immich-machine-learning:
container_name: immich_machine_learning
user: "${UID}:${GID}"
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
volumes:
- model-cache:/cache
env_file:
- .env
restart: unless-stopped
volumes:
model-cache:
这里注意的点主要是:
- 从 compose 里面删除 Redis 和 PG 部分,因为 Redis 已经部署到宿主环境了,而 PG 部署到 TS216 上面了
- 端口映射的话我绑定了 lo 接口,因为我不想暴露带端口的服务,而是随后统一用 Nginx 反代到 80 上去
三、AIO 上的 /var/lib/immich-app/.env 环境配置文件
# Immich 照片和视频上传的物理存放位置,这里指到 nfs 文件夹了
UPLOAD_LOCATION=/mnt/Immich/library
# Immich 部署的版本,我用了部署时候的最新版本
IMMICH_VERSION=v1.93.3
# 这里是我的 TS216 在内网环境的域名,换成 ip 也行
DB_HOSTNAME=nas.home
# PG 的用户名和密码,这个在 TS216 compose 文件里面就可以指定
DB_USERNAME=postgres
DB_PASSWORD=postgres
# 这个库名就是前面 AIO 部署好 pgadmin4 之后在 web 界面里建好的
DB_DATABASE_NAME=immich
# AIO 宿主环境部署好的 Redis
# 重点,这里要写 docker 桥接网卡的地址,否则 docker 内部连不上宿主环境的 Redis
REDIS_HOSTNAME=172.17.0.1
# 这个是前面 Redis 配置里就改好的
REDIS_PASSWORD=redis
# 这个是 AIO 里面 Immich compose 运行的所有容器里面使用的用户,就是 immich:immich, id 查出来我的是 1003
UID=1003
GID=1003
四、AIO 上 /etc/redis/redis.conf 重点修改
...其他默认配置
# 重点是后面的 docker 桥接网卡地址,如果不 bind ,docker 内部连不到宿主环境的 6379
# bind 之后,内部连接 6379 就等于连接宿主环境的 6379 了
bind 127.0.0.1 172.17.0.1
# 这个是开启 Redis 密码连接模式,密码为 redis ,随便写,docker env 里面填这个
requirepass redis
五、AIO 上的 /etc/nginc/conf.d/immich.conf Immich 反代配置
server {
listen 80;
server_name immich.aio.home;
# logging
access_log /var/log/nginx/immich.access.log;
error_log /var/log/nginx/immich.error.log error;
# https://github.com/immich-app/immich/blob/main/nginx/templates/default.conf.template#L28
client_max_body_size 50000M;
location / {
proxy_pass http://localhost:2283/;
proxy_set_header Host $http_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-Proto $scheme;
# http://nginx.org/en/docs/http/websocket.html
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
}
}
六、AIO 上的 /etc/nginx/conf.d/pgadmin4.conf pgadmin4 反代配置
server {
listen 80;
server_name pgadmin4.aio.home;
# logging
access_log /var/log/nginx/pgadmin4.access.log;
error_log /var/log/nginx/pgadmin4.error.log error;
location / {
proxy_set_header Host $host;
proxy_pass http://localhost:5050/;
proxy_redirect off;
}
}
嗯,基本上就这些了。