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

## 🚀 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 “:cross_mark: git-lfs 未安装,请先安装:apt install git-lfs” exit 1 fi

git lfs install

拉取模型

for repo in “${!MODELS[@]}”; do target_dir=“${MODELS[$repo]}” echo “:package: 拉取模型:$repo” echo “:right_arrow: 目标路径:$target_dir”

if [ -d “$target_dir/.git” ]; then echo “:warning: 目录已存在,跳过克隆:$target_dir” else mkdir -p “$(dirname “$target_dir”)” git clone “https://huggingface.co/$repo” “$target_dir” fi

echo “:down_arrow: 拉取 LFS 模型文件…” cd “$target_dir” && git lfs pull && cd - > /dev/null echo “:white_check_mark: $repo 下载完成” echo “----------------------------------” done

echo “:tada: 所有模型下载完成!”

  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/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: 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: [“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

  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 下,并赋予执行权限

    :pushpin: 配置项(按需修改)

    CONTAINER_NAME=“immich_db” BACKUP_DIR=“/mnt/immich/backup/db” DATE=$(date +“%Y-%m-%d_%H-%M-%S”) FILENAME=“immich_db_backup_$DATE.sql”

    :card_index_dividers: 确保备份目录存在

    mkdir -p “$BACKUP_DIR”

    :locked_with_key: 从容器中导出 PostgreSQL 数据库(使用 docker exec)

    echo “:package: 正在备份 Immich 数据库到 $BACKUP_DIR/$FILENAME …” docker exec -t $CONTAINER_NAME pg_dump -U postgres -d immich > “$BACKUP_DIR/$FILENAME”

    :white_check_mark: 结果提示

    if [ $? -eq 0 ]; then echo “:white_check_mark: 备份完成:$FILENAME” else echo “:cross_mark: 备份失败,请检查容器状态或权限。” fi

    :litter_in_bin_sign: 删除 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