🧩 混合架构示意
📱手机拍照
⬇️
通过 Immich Web/APP 上传
⬇️
存储在 /volume1/photos(或其他路径)
⬇️
Immich 挂载该目录,自动扫描并进行 AI 处理
⬇️
Web / App 使用 Immich 查看智能标签、人脸、地图等
一、在 Ubuntu 安装依赖
sudo apt update
sudo apt install docker.io docker-compose nfs-common -y
sudo systemctl enable docker
二、创建挂载目录 & 挂载群晖共享目录
创建挂载点
sudo mkdir -p /mnt/immich/photos
sudo mkdir -p /mnt/immich/cache
sudo mkdir -p /mnt/immich/ml-cache
sudo mkdir -p /mnt/immich/pgdata
群晖目录挂载如下
| 用途 | 群晖路径 | Ubuntu 挂载路径 |
|---|---|---|
| 📷 原图 | /volume1/photos |
/mnt/immich/photos |
| 📂 缩略图/缓存 | /volume1/immich/cache |
/mnt/immich/cache |
| 🧠 AI 模型 | /volume1/immich/ml-cache |
/mnt/immich/ml-cache |
| 🗃️ 数据库 | /volume1/immich/pgdata |
/mnt/immich/pgdata |
编辑挂载配置 /etc/fstab
sudo nano /etc/fstab
添加以下内容(请确保 DSM IP 和共享路径正确)
10.10.10.39:/volume1/photos /mnt/immich/photos nfs defaults,_netdev 0 0
10.10.10.39:/volume1/immich/cache /mnt/immich/cache nfs defaults,_netdev 0 0
10.10.10.39:/volume1/immich/ml-cache /mnt/immich/ml-cache nfs defaults,_netdev 0 0
10.10.10.39:/volume1/immich/pgdata /mnt/immich/pgdata nfs defaults,_netdev 0 0
🎯 挂载
sudo mount -a
测试确保群晖文件夹都能读/写(photos 是只读):
touch /mnt/immich/cache/test.txt
ls /mnt/immich/photos
群晖 NFS 权限设置推荐
在 DSM 中打开共享文件夹(如 photos 或 immich)→ 点“编辑”→ 切换到【NFS 权限】→ 点“创建” → 出现以下选项:
| 设置项 | 建议配置 | 说明 |
|---|---|---|
| 服务器名称或 IP 地址 | 10.10.10.88 |
填你的 Ubuntu 虚拟机 IP(可用* 测试) |
| 权限 | ✅ 可读写 | Immich 会写缩略图/数据库,必须选“可读写” |
| Squash | ✅ 无映射 | 允许 root 用户访问,不映射为匿名用户 |
| 安全性 | ✅ sys | 默认 NFS 权限控制方式,别选 krb5 |
| 启动异步 | ✅ 打开 | 提高性能,推荐打开 |
| 允许来自非特权端口的连接 | ✅ 勾选 | Ubuntu mount 时会用 >1024 端口,必须开启 |
| 允许用户访问已装载的子文件夹 | ✅ 勾选 | 避免子文件夹访问失败(推荐) |
三、拉取 Immich 模型
一键拉取指定 Immich 模型 的 Bash 脚本
buffalo_lantelopev2XLM-Roberta-Large-Vit-B-16Plus
脚本内容:download_models.sh
#!/bin/bash模型仓库和目标路径的映射
declare -A MODELS MODELS[“immich-app/buffalo_l”]=“/mnt/immich/ml-cache/facial-recognition/buffalo_l” MODELS[“immich-app/antelopev2”]=“/mnt/immich/ml-cache/facial-recognition/antelopev2” MODELS[“immich-app/XLM-Roberta-Large-Vit-B-16Plus”]=“/mnt/immich/ml-cache/clip/XLM-Roberta-Large-Vit-B-16Plus”
检查 git-lfs 是否安装
if ! command -v git-lfs &> /dev/null; then echo “
git-lfs 未安装,请先安装:apt install git-lfs” exit 1 fi
git lfs install
拉取模型
for repo in “${!MODELS[@]}”; do target_dir=“${MODELS[$repo]}” echo “
拉取模型:$repo” echo “
目标路径:$target_dir”
if [ -d “$target_dir/.git” ]; then echo “
目录已存在,跳过克隆:$target_dir” else mkdir -p “$(dirname “$target_dir”)” git clone “https://huggingface.co/$repo” “$target_dir” fi
echo “
拉取 LFS 模型文件…” cd “$target_dir” && git lfs pull && cd - > /dev/null echo “
$repo 下载完成” echo “----------------------------------” done
echo “所有模型下载完成!”
- 保存脚本
nano download_models.sh
# 粘贴上方内容,保存退出
- 赋予执行权限并运行
chmod +x download_models.sh
./download_models.sh
模型对应文件夹
| 模型名 | 对应路径应为 |
|---|---|
XLM-Roberta-Large-Vit-B-16Plus |
/mnt/immich/ml-cache/clip/XLM-Roberta-Large-Vit-B-16Plus |
buffalo_l |
/mnt/immich/ml-cache/facial-recognition/buffalo_l |
antelopev2 |
/mnt/immich/ml-cache/facial-recognition/antelopev2 |
目录结构:
/mnt/immich/ml-cache/
├── clip/
│ └── XLM-Roberta-Large-Vit-B-16Plus/
├── facial-recognition/
│ ├── antelopev2/
│ └── buffalo_l/
三、Esxi ubuntu显卡直通
- 确保 ESXi 虚拟机禁用了默认 SVGA
编辑 .vmx 文件(不要加 svga.vgaOnly,那会禁用显卡):
svga.present = "FALSE"
svga.enableScreenDMA = "FALSE"
并确保核显的 PCI 设备是通过直通设置添加的(非虚拟硬件)。
- 给 Ubuntu 添加
/etc/modprobe.d/i915.conf强制启用核显模块:
echo "options i915 enable_guc=3" | sudo tee /etc/modprobe.d/i915.conf
sudo update-initramfs -u
然后重启:
sudo reboot
- 重启后再执行:
LIBVA_DRIVER_NAME=iHD DRI_DEVICE=/dev/dri/card0 vainfo
如果这一步显示出解码器/编码器能力(如 H264, HEVC, VP9, AV1),就说明你的 VAAPI + iGPU 成功了。
- Immich
docker-compose.yml添加 iGPU 硬件支持:
services:
immich-machine-learning:
...
devices:
- /dev/dri/card0:/dev/dri/card0
environment:
- LIBVA_DRIVER_NAME=iHD
- 重启所有服务(顺带清掉缓存)
docker-compose down -v
docker-compose pull
docker-compose up -d
加上 -v 是为了清除挂载卷缓存问题。
删除旧的数据库数据
sudo rm -rf /mnt/immich/pgdata/*
查看是否加载指定的模型
docker logs -f immich_ml
四、Docker部署docker-compose.yml文件
- docker-compose.yml文件
services: immich-server: container_name: immich_server image: ghcr.io/immich-app/immich-server:release volumes: - /mnt/photos:/usr/src/app/upload - /mnt/immich/cache:/usr/src/app/cache - /etc/localtime:/etc/localtime:ro - /mnt/immich/geodata:/build/geodata - /mnt/immich/i18n-iso-countries/langs:/usr/src/app/node_modules/i18n-iso-countries/langs env_file: - .env ports: - "2283:2283" depends_on: - redis - database restart: always healthcheck: test: curl -f http://localhost:2283/server-info || exit 1 interval: 30s timeout: 10s retries: 3immich-machine-learning: container_name: immich_ml image: ghcr.io/immich-app/immich-machine-learning:release volumes: - /mnt/immich/ml-cache:/cache env_file: - .env restart: always healthcheck: test: [“CMD”, “python”, “-c”, “import urllib.request,sys;import urllib.error;paths=[‘/healthz’,‘/health’,‘/info’,‘/’];\nok=False\n\nimport socket\nfor p in paths:\n try:\n r=urllib.request.urlopen(‘http://127.0.0.1:3003’+p,timeout=5)\n ok=r.status<400\n if ok: break\n except Exception:\n pass\nsys.exit(0 if ok else 1)”] interval: 30s timeout: 10s retries: 5 start_period: 60s
redis: container_name: immich_redis image: redis:6.2-alpine restart: always healthcheck: test: redis-cli ping || exit 1 interval: 30s timeout: 5s retries: 3
database: container_name: immich_db image: tensorchord/pgvecto-rs:pg15-v0.2.0 environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: ${DB_USERNAME} POSTGRES_DB: ${DB_DATABASE_NAME} POSTGRES_INITDB_ARGS: ‘–data-checksums’ volumes: - /mnt/immich/pgdata:/var/lib/postgresql/data restart: always healthcheck: test: pg_isready -U ${DB_USERNAME} -d ${DB_DATABASE_NAME} interval: 30s timeout: 5s retries: 5 command: >- postgres -c shared_preload_libraries=vectors.so -c ‘search_path=“$$user”, public, vectors’ -c logging_collector=on -c max_wal_size=2GB -c shared_buffers=512MB -c wal_compression=on
-
.env文件# Immich 配置:使用你群晖挂载的实际目录图片原图存储路径(你的群晖挂载路径)
UPLOAD_LOCATION=/mnt/immich/photos
PostgreSQL 数据存储路径(你的群晖挂载路径)
DB_DATA_LOCATION=/mnt/immich/pgdata
可选时区设置(建议设置为你当前时区)
TZ=Asia/Shanghai
使用 Immich 发布版本(release 代表最新稳定版)
IMMICH_VERSION=release
数据库密码(不能有 @#$% 等特殊字符)
DB_PASSWORD=immich
以下保持默认即可
DB_USERNAME=postgres DB_DATABASE_NAME=immich
MACHINE_LEARNING_CLIP_MODEL=XLM-Roberta-Large-Vit-B-16Plus MACHINE_LEARNING_FACE_RECOGNITION_MODEL=buffalo_l
五、其他——上传文件
方式一:通过 Immich Web/APP 上传
- 最推荐,照片上传后自动:
- 入库、生成缩略图
- 分析 EXIF 数据
- 加入 AI 处理队列(人脸识别、标签等)
方式二:通过 immich-cli import 或容器命令导入
- 如果你已有大量老照片存于 NAS,可以用这方法导入:
示例:导入已有图片目录
docker exec -it immich_server node ./apps/immich/src/main.ts import /usr/src/app/upload
或使用 官方 CLI 工具:
immich-cli import /path/to/photos
这个命令会递归扫描指定目录,将符合条件的照片导入 Immich 数据库,和正常上传等效,也会启动 AI 分析流程。
🚫 不推荐:直接复制文件到 /mnt/immich/photos
- 这样照片不会被 Immich 识别和处理,只是文件存在,Immich 的 UI、搜索、AI 也不会看到它们。
- 你仍然需要手动导入才能生效。
六、定时备份数据库
Immich PostgreSQL 数据库自动备份脚本,支持定期备份并保存在你指定的目录,比如群晖挂载的 /mnt/immich/backup 下。
脚本内容:immich_db_backup.sh
#!/bin/bash=== Immich PostgreSQL 数据库备份脚本 ===
建议保存在 /usr/local/bin 或 ~/scripts 下,并赋予执行权限
配置项(按需修改)
CONTAINER_NAME=“immich_db” BACKUP_DIR=“/mnt/immich/backup/db” DATE=$(date +“%Y-%m-%d_%H-%M-%S”) FILENAME=“immich_db_backup_$DATE.sql”
确保备份目录存在
mkdir -p “$BACKUP_DIR”
从容器中导出 PostgreSQL 数据库(使用 docker exec)
echo “
正在备份 Immich 数据库到 $BACKUP_DIR/$FILENAME …” docker exec -t $CONTAINER_NAME pg_dump -U postgres -d immich > “$BACKUP_DIR/$FILENAME”
结果提示
if [ $? -eq 0 ]; then echo “
备份完成:$FILENAME” else echo “
备份失败,请检查容器状态或权限。” fi
删除 7 天前的备份
find “$BACKUP_DIR” -type f -name “*.sql” -mtime +7 -delete
🧪 使用方法:
- 保存为
immich_db_backup.sh - 赋予执行权限:
chmod +x immich_db_backup.sh
- 执行备份:
./immich_db_backup.sh
📅 设置定时任务(每天凌晨 3 点)
编辑 crontab:
crontab -e
添加一行:
0 3 * * * /root/scripts/immich_db_backup.sh >> /var/log/immich_backup.log 2>&1