🚀 Immich Docker部署(Esxi和群晖混合架构版)

🧩 混合架构示意

📱手机拍照
⬇️
通过 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 中打开共享文件夹(如 photosimmich)→ 点“编辑”→ 切换到【NFS 权限】→ 点“创建” → 出现以下选项:

设置项建议配置说明
服务器名称或 IP 地址10.10.10.88填你的 Ubuntu 虚拟机 IP(可用* 测试)
权限✅ 可读写Immich 会写缩略图/数据库,必须选“可读写”
Squash✅ 无映射允许 root 用户访问,不映射为匿名用户
安全性✅ sys默认 NFS 权限控制方式,别选 krb5
启动异步✅ 打开提高性能,推荐打开
允许来自非特权端口的连接✅ 勾选Ubuntu mount 时会用 >1024 端口,必须开启
允许用户访问已装载的子文件夹✅ 勾选避免子文件夹访问失败(推荐)

三、拉取 Immich 模型

一键拉取指定 Immich 模型 的 Bash 脚本

  • buffalo_l
  • antelopev2
  • XLM-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 "🎉 所有模型下载完成!"
  1. 保存脚本
nano download_models.sh
# 粘贴上方内容,保存退出
  1. 赋予执行权限并运行
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显卡直通

  1. 确保 ESXi 虚拟机禁用了默认 SVGA

编辑 .vmx 文件(不要加 svga.vgaOnly,那会禁用显卡):

svga.present = "FALSE"
svga.enableScreenDMA = "FALSE"

并确保核显的 PCI 设备是通过直通设置添加的(非虚拟硬件)。

  1. 给 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
  1. 重启后再执行:
LIBVA_DRIVER_NAME=iHD DRI_DEVICE=/dev/dri/card0 vainfo

如果这一步显示出解码器/编码器能力(如 H264, HEVC, VP9, AV1),就说明你的 VAAPI + iGPU 成功了。

  1. Immich docker-compose.yml 添加 iGPU 硬件支持:
services:
  immich-machine-learning:
    ...
    devices:
      - /dev/dri/card0:/dev/dri/card0
    environment:
      - LIBVA_DRIVER_NAME=iHD
  1. 重启所有服务(顺带清掉缓存)
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文件

  1. docker-compose.yml文件
services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:release
    volumes:
      - /mnt/immich/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:3001/server-info || exit 1
      interval: 30s
      timeout: 10s
      retries: 3

  immich-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: curl -f http://localhost:3003/info || exit 1
      interval: 30s
      timeout: 10s
      retries: 3
    devices:
      - /dev/dri/card0:/dev/dri/card0
    environment:
      - LIBVA_DRIVER_NAME=iHD

  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
  1. .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

🧪 使用方法:

  1. 保存为 immich_db_backup.sh
  2. 赋予执行权限:
chmod +x immich_db_backup.sh
  1. 执行备份:
./immich_db_backup.sh

📅 设置定时任务(每天凌晨 3 点)

编辑 crontab:

crontab -e

添加一行:

0 3 * * * /root/scripts/immich_db_backup.sh >> /var/log/immich_backup.log 2>&1
如果觉得我的文章对你有用,请随意赞赏