跳转到内容

Docker 部署 Immich:自建 Google Photos 替代方案,私有相册全流程教程(2026版)

Docker 部署 Immich

智能手机时代,我们每天都在拍摄海量的照片和视频。然而,这些珍贵的记忆却被「关押」在各种云服务中:Google Photos 的免费无限存储已于 2021 年结束,iCloud 每年数百元订阅费,百度云限速严重……

如果你想:

  • 📸 完全掌控 自己的照片数据
  • 🤖 AI 智能识别 物体、场景、人脸
  • 🗺️ 地图视图 查看拍摄地点
  • 📱 手机自动备份 随时随地上传
  • 👨‍👩‍👧‍👦 家庭共享 多账号共用
  • 💰 零订阅费 一次部署终身使用

那么 Immich(发音类似 "Image")就是为你量身定做的解决方案。

Immich 是一个开源的照片和视频管理与备份系统,功能对标 Google Photos。它由社区驱动,开发非常活跃,在 2025-2026 年持续高速迭代,已成为最受欢迎的自建相册方案。

本文将带你从零开始,用 Docker Compose 部署属于你自己的 Immich 私有相册。


目录

  1. Immich 是什么?核心功能一览
  2. 硬件与资源需求
  3. Immich 架构组件解析
  4. Docker Compose 完整部署
  5. Nginx / Caddy 反向代理配置
  6. 初始化设置与管理员账号
  7. 手机端 App 安装与自动备份
  8. AI 智能识别与人脸识别配置
  9. 相册管理、共享与协作
  10. 数据备份与恢复策略
  11. 性能优化与资源调整
  12. 常见问题与故障排查

1. Immich 是什么?核心功能一览

1.1 核心功能矩阵

功能模块功能详情实现状态
自动备份手机端 App 自动备份照片、视频✅ 完整
Web 界面网页端浏览、管理、上传照片✅ 完整
AI 识别物体识别、场景识别、CLIP 语义搜索✅ 完整
人脸识别自动识别人物、分类命名✅ 完整
地图视图根据 EXIF GPS 信息显示照片位置✅ 完整
相册管理创建相册、收藏夹、智能相册✅ 完整
共享相册创建共享链接、家庭相册、密码保护✅ 完整
多用户支持多账号、配额管理、家庭共享✅ 完整
视频支持视频上传、播放、缩略图生成✅ 完整
Live PhotosiOS Live Photos 支持✅ 完整
桌面客户端Windows / macOS 客户端上传✅ 可用
API 支持完整的 RESTful API✅ 完整

1.2 与 Google Photos 功能对比

特性ImmichGoogle Photos
照片/视频备份
AI 图片搜索
人脸识别
地图视图
相册管理
共享链接
免费存储✅(取决于你的服务器容量)❌(15GB 后需付费)
数据隐私✅(完全私有)❌(被 Google 分析用于广告)
多用户
原画质✅(超出 15GB 需付费)
RAW 格式支持⚠️
视频转码✅(硬件加速可选)
地图热图❌(仅 Google Maps 集成)

1.3 Immich 的核心技术栈

后端:
• Node.js(API 服务器)
• PostgreSQL(主数据库)
• Redis(缓存和任务队列)
• Python(机器学习微服务)

AI/ML:
• CLIP(语义搜索 - Contrastive Language-Image Pre-training)
• face-api.js(人脸识别)
• TensorFlow.js 或 ONNX(模型推理)

前端:
• Web: Svelte(响应式界面)
• Mobile: Flutter(iOS / Android 原生 App)
• Desktop: Electron(Windows / macOS)

2. 硬件与资源需求

2.1 服务器配置推荐

Immich 对资源的需求比 Vaultwarden 高得多,尤其是 AI 识别功能会消耗大量 CPU 和内存。

规模CPU内存存储推荐用户数
最小配置2 核4 GB50 GB SSD1 人
标准配置4 核8 GB500 GB SSD1-3 人
推荐配置6 核以上16 GB1-4 TB SSD2-5 人
家庭使用8 核以上32 GB4-8 TB SSD5-10 人

2.2 详细说明

CPU:
• 照片上传和处理主要靠 CPU
• AI 识别(人脸识别、CLIP)最耗 CPU
• 建议 4 核以上,越多越好
• 如开启 GPU 加速,CPU 压力会大幅降低

内存:
• PostgreSQL 数据库占用 ~512MB-2GB
• AI 微服务启动后占用 2-4GB
• 每个用户会话占用少量内存
• 推荐 8GB 起步,多用户建议 16GB+

存储:
• 原始照片文件:根据用户上传量估算
• 缩略图和缓存:约为原始文件的 15-25%
• 数据库:每 1 万张照片约 100-200MB
• 经验值:1 万张照片约需 20-40GB 存储
• 建议使用 SSD,小文件读写速度很重要

GPU(可选):
• 支持 NVIDIA GPU 加速 AI 识别
• 需安装 NVIDIA Container Toolkit
• 大幅提升人脸和物体识别速度
• 预算充足时推荐:RTX 3050/3060 或更高

2.3 部署地点选择

方案一:家用服务器(推荐)
• 优点:存储成本低、网络免费、数据最安全
• 缺点:需要内网穿透才能在外访问、需要公网 IP 或 DDNS
• 硬件:群晖 / 威联通 NAS、台式机、树莓派 4(8GB)、小主机

方案二:VPS(云服务器)
• 优点:部署简单、公网 IP 稳定、无需操心硬件
• 缺点:大容量存储成本高、数据上传下载成本高
• 推荐:Contabo、Hetzner(大硬盘、性价比高)

方案三:混合方案
• VPS 运行 Web 和数据库,照片存储在本地 NAS(通过 NFS)
• 兼顾便捷性和经济性

3. Immich 架构组件解析

Immich 由多个 Docker 容器协同工作:

immich-server(主 API 服务器)

immich-microservices(后台任务处理)

immich-machine-learning(AI / ML 微服务)

immich-postgres(主数据库)

immich-redis(缓存 / 任务队列)

immich-web(前端 Web 界面)

immich-proxy(统一入口 / Nginx 反代,可选)

immich-typesense(搜索引擎,用于 CLIP 语义搜索)

immich-upload(上传处理服务)

各组件职责

组件职责资源占用
immich-server处理 API 请求、用户认证、相册管理中 ~ 高
immich-microservices缩略图生成、视频转码、EXIF 提取、任务队列高(CPU 密集)
immich-machine-learning人脸识别、CLIP 语义搜索、物体识别非常高(CPU/GPU 密集)
immich-postgres主数据库、存储所有元数据低 ~ 中
immich-redis缓存、会话管理、任务队列极低
immich-webWeb 前端界面(静态资源)极低
immich-typesense搜索引擎,支持文本搜索、向量搜索
immich-upload上传服务,处理照片/视频上传低 ~ 中

4. Docker Compose 完整部署

4.1 创建项目目录

bash
# 创建项目目录
mkdir -p ~/immich/{app,database,upload,thumbs,profile,logs}

# 进入目录
cd ~/immich

4.2 创建环境变量文件 .env

bash
# ~/immich/.env

# ======== 基本配置 ========
# 域名(必须是 https)
EXTERNAL_DOMAIN=https://photos.yourdomain.com

# 数据库密码(自行设置,务必复杂)
DB_PASSWORD=your-complex-db-password-here
DB_USERNAME=immich
DB_DATABASE_NAME=immich
DB_HOSTNAME=postgres

# Redis 配置
REDIS_HOSTNAME=redis

# ======== 上传与存储 ========
# 上传文件大小限制(单位:字节)
# 建议设置为较大值,如 4GB = 4294967296
UPLOAD_LOCATION=/path/to/your/upload/storage
MAX_FILE_SIZE=4294967296

# ======== 数据库配置 ========
# PostgreSQL 数据目录
DB_DATA_LOCATION=/path/to/your/postgres/data

# ======== AI/ML 配置 ========
# 是否启用机器学习(人脸识别、CLIP)
MACHINE_LEARNING_ENABLED=true

# 启用的模型(越多功能越强,但越耗资源)
MACHINE_LEARNING_WORKERS=2

# CLIP 模型选择(影响搜索效果)
# 可选:ViT-B-32__openai(快速)| ViT-L-14__openai(更准,更慢)
CLIP_MODEL=ViT-B-32__openai

# ======== 时区设置 ========
TZ=Asia/Shanghai

# ======== 可选配置 ========
# 启用/禁用图片地理信息显示
MAP_ENABLED=true

# 地图服务选择(可选:maptiler | google | none)
MAP_PROVIDER=maptiler
MAP_KEY=your-maptiler-api-key-here

# 用户注册控制(默认允许,部署后可改为 false)
ALLOW_SIGNUP=true

# 管理员邮箱(首次启动后可在管理面板设置)
# IMMICH_ADMIN_EMAIL=your@email.com
# IMMICH_ADMIN_PASSWORD=your-admin-password

4.3 创建 docker-compose.yml

yaml
# ~/immich/docker-compose.yml

version: "3.8"

# ======== 网络配置 ========
networks:
  immich-network:
    name: immich-network
    driver: bridge

# ======== 数据卷(自动管理存储位置) ========
volumes:
  pgdata:
    driver: local
  model-cache:
    driver: local

services:

  # ======== PostgreSQL 数据库 ========
  postgres:
    image: tensorchord/pgvecto-rs:pg16-v0.3.0
    container_name: immich-postgres
    hostname: postgres
    restart: unless-stopped
    volumes:
      - ./postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      TZ: ${TZ}
    networks:
      - immich-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      interval: 15s
      timeout: 5s
      retries: 10

  # ======== Redis 缓存 ========
  redis:
    image: redis:7.4-alpine
    container_name: immich-redis
    hostname: redis
    restart: unless-stopped
    volumes:
      - ./redis:/data
    environment:
      TZ: ${TZ}
    networks:
      - immich-network
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping || exit 1"]
      interval: 15s
      timeout: 5s
      retries: 10

  # ======== Immich Server(主 API) ========
  immich-server:
    image: ghcr.io/immich-app/immich-server:release
    container_name: immich-server
    restart: unless-stopped
    volumes:
      - ./upload:/usr/src/app/upload
      - ./thumbs:/usr/src/app/thumbs
      - ./encoded-video:/usr/src/app/encoded-video
    environment:
      DB_HOSTNAME: ${DB_HOSTNAME}
      DB_USERNAME: ${DB_USERNAME}
      DB_PASSWORD: ${DB_PASSWORD}
      DB_DATABASE_NAME: ${DB_DATABASE_NAME}
      REDIS_HOSTNAME: ${REDIS_HOSTNAME}
      TYPESENSE_ENABLED: true
      TZ: ${TZ}
      # === 可选:GPU 加速(需要 NVIDIA Container Toolkit) ===
      # NVIDIA_VISIBLE_DEVICES: all
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - immich-network
    ports:
      - "127.0.0.1:2283:2283"  # 仅本地监听,通过 Nginx/Caddy 暴露
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:2283/server-info/ping"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s

  # ======== Immich Microservices(后台任务) ========
  immich-microservices:
    image: ghcr.io/immich-app/immich-microservices:release
    container_name: immich-microservices
    restart: unless-stopped
    volumes:
      - ./upload:/usr/src/app/upload
      - ./thumbs:/usr/src/app/thumbs
      - ./encoded-video:/usr/src/app/encoded-video
      - ./model-cache:/cache
    environment:
      DB_HOSTNAME: ${DB_HOSTNAME}
      DB_USERNAME: ${DB_USERNAME}
      DB_PASSWORD: ${DB_PASSWORD}
      DB_DATABASE_NAME: ${DB_DATABASE_NAME}
      REDIS_HOSTNAME: ${REDIS_HOSTNAME}
      TZ: ${TZ}
      # === 可选:GPU 加速 ===
      # NVIDIA_VISIBLE_DEVICES: all
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - immich-network

  # ======== Immich Machine Learning(AI 微服务) ========
  immich-machine-learning:
    image: ghcr.io/immich-app/immich-machine-learning:release
    container_name: immich-machine-learning
    restart: unless-stopped
    volumes:
      - ./model-cache:/cache
      - ./upload:/usr/src/app/upload
    environment:
      DB_HOSTNAME: ${DB_HOSTNAME}
      DB_USERNAME: ${DB_USERNAME}
      DB_PASSWORD: ${DB_PASSWORD}
      DB_DATABASE_NAME: ${DB_DATABASE_NAME}
      REDIS_HOSTNAME: ${REDIS_HOSTNAME}
      TZ: ${TZ}
      # === 资源限制(防止 AI 服务占用过多资源) ===
      MACHINE_LEARNING_WORKERS: ${MACHINE_LEARNING_WORKERS}
      # === 可选:GPU 加速 ===
      # NVIDIA_VISIBLE_DEVICES: all
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - immich-network
    # === CPU 资源限制(根据你的服务器调整) ===
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G

  # ======== Typesense(搜索引擎) ========
  typesense:
    image: typesense/typesense:27.0.rc1
    container_name: immich-typesense
    restart: unless-stopped
    volumes:
      - ./typesense:/data
    environment:
      TYPESENSE_API_KEY: ${TYPESENSE_API_KEY:-your-typesense-api-key}
      TYPESENSE_DATA_DIR: /data
      TZ: ${TZ}
    command: ["--enable-cors"]
    networks:
      - immich-network
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8108/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3

  # ======== Immich Web(前端界面) ========
  immich-web:
    image: ghcr.io/immich-app/immich-web:release
    container_name: immich-web
    restart: unless-stopped
    environment:
      TZ: ${TZ}
    networks:
      - immich-network
    ports:
      - "127.0.0.1:3000:3000"  # 仅本地监听
    depends_on:
      - immich-server

📌 说明

4.4 使用官方推荐的最简配置

官方提供了一个更简洁、更易维护的配置(推荐初学者使用):

bash
# 从官方获取最新的配置文件
cd ~/immich
wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

# 编辑 .env 文件,修改以下内容:
# 1. EXTERNAL_DOMAIN=https://photos.yourdomain.com
# 2. DB_PASSWORD=你的数据库密码
# 3. UPLOAD_LOCATION=./upload
# 4. TZ=Asia/Shanghai
nano .env

4.5 启动 Immich

bash
# 创建必要目录
mkdir -p ~/immich/upload
mkdir -p ~/immich/postgres
mkdir -p ~/immich/model-cache
mkdir -p ~/immich/thumbs
mkdir -p ~/immich/encoded-video

# 启动服务(首次会拉取所有镜像,较慢)
cd ~/immich
docker compose up -d

# 查看容器状态
docker compose ps

# 查看所有容器日志(前 50 行,了解启动情况)
docker compose logs --tail=50

# 查看特定容器日志(查看主服务器)
docker compose logs -f immich-server

# 等待所有容器状态变为 healthy
# 首次启动可能需要 3-5 分钟(模型文件需要下载)

4.6 验证本地访问

bash
# 测试 Web 界面是否响应
curl -I http://127.0.0.1:3000

# 测试 API 是否响应
curl -I http://127.0.0.1:2283

# 正常输出应该是 HTTP/1.1 200 OK

5. Nginx / Caddy 反向代理配置

5.1 方案一:Caddy(推荐,自动 HTTPS)

caddyfile
# /etc/caddy/Caddyfile(或 ~/immich/Caddyfile)

photos.yourdomain.com {
    # 主 Web 界面反代到 immich-web
    reverse_proxy 127.0.0.1:3000

    # API 请求反代到 immich-server
    # /api/* / /auth/* / /oauth/* / /user/* / /mobile/* / /share/*
    @api_paths {
        path /api/* /auth/* /oauth/* /user/* /mobile/* /share/*
    }
    reverse_proxy @api_paths 127.0.0.1:2283

    # 大文件上传超时设置
    reverse_proxy {
        to 127.0.0.1:3000
        transport http {
            read_timeout 300s
            write_timeout 300s
        }
    }

    # 文件上传大小限制(10GB)
    request_body {
        max_size 10GB
    }

    # 安全头
    header Strict-Transport-Security "max-age=31536000; includeSubDomains"
    header X-Content-Type-Options nosniff

    # Gzip 压缩
    encode gzip

    # 日志
    log
}

5.2 方案二:Nginx + Certbot

nginx
# /etc/nginx/sites-available/immich

server {
    # HTTP 跳转到 HTTPS
    listen 80;
    listen [::]:80;
    server_name photos.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    # HTTPS 配置
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name photos.yourdomain.com;

    # SSL 证书(Certbot 自动配置)
    ssl_certificate /etc/letsencrypt/live/photos.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/photos.yourdomain.com/privkey.pem;

    # SSL 安全配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # 大文件上传支持
    client_max_body_size 10G;
    client_body_timeout 300s;
    proxy_connect_timeout 300;
    proxy_send_timeout 300;
    proxy_read_timeout 300;

    # Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
    gzip_min_length 1024;

    # 日志
    access_log /var/log/nginx/immich_access.log;
    error_log /var/log/nginx/immich_error.log;

    # 主应用反代
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $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;
    }

    # API 和认证路径反代到 API 服务器
    location /api/ {
        proxy_pass http://127.0.0.1:2283;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $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;
    }

    location /auth/ {
        proxy_pass http://127.0.0.1:2283;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $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;
    }

    location /oauth/ {
        proxy_pass http://127.0.0.1:2283;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $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;
    }

    # WebSocket 支持(实时通知)
    location /socket.io/ {
        proxy_pass http://127.0.0.1:2283;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 安全头
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
}
bash
# 启用 Nginx 配置
sudo ln -s /etc/nginx/sites-available/immich /etc/nginx/sites-enabled/

# 申请证书(如果还没有)
sudo certbot --nginx -d photos.yourdomain.com --email your@email.com

# 测试配置
sudo nginx -t

# 重启 Nginx
sudo systemctl restart nginx

6. 初始化设置与管理员账号

6.1 首次访问 Web 界面

部署完成后,在浏览器中访问:

https://photos.yourdomain.com

你会看到 Immich 欢迎界面。

6.2 创建管理员账号

1. 点击「注册」或「Sign up」
2. 输入邮箱和密码
3. 点击「创建账号」
4. 登录后进入主界面
5. 第一个注册的用户会自动成为管理员

⚠️ 部署完成后,建议先创建自己的账号,然后关闭注册功能:
   管理面板 → 设置 → 服务器设置 → 关闭「Allow signup」

6.3 管理面板

访问:https://photos.yourdomain.com/admin
或点击右上角头像 → 「管理」/「Administration」

在管理面板中可以:
• 查看和管理所有用户
• 设置用户配额(存储配额)
• 禁用 / 删除用户
• 查看系统状态
• 修改服务器设置(注册、上传限制等)
• 查看存储使用统计
• 管理后台任务和作业

7. 手机端 App 安装与自动备份

7.1 下载 App

iOS(iPhone / iPad):
  App Store → 搜索 "Immich" → 下载安装

Android:
  Google Play → 搜索 "Immich" → 下载安装
  或 F-Droid(开源商店)搜索下载

iOS 快捷方式(官方推荐):
  App Store → 搜索 "Immich Mobile App"

7.2 App 配置连接自建服务器

1. 打开 Immich App
2. 首次打开会提示输入服务器地址:
   https://photos.yourdomain.com
3. 输入邮箱和密码登录
4. 授予照片访问权限(iOS 需在系统设置中授权)
5. 授予位置访问权限(可选,用于上传 GPS 信息)
6. 完成配置!

7.3 配置自动备份

在 App 中设置:
1. 点击「设置」或「Settings」
2. 选择「备份」或「Backup」
3. 开启「自动备份」
4. 选择要备份的相册:
   • 相机胶卷(Camera Roll)
   • 所有相册
   • 指定相册
5. 选择备份条件:
   • 仅 Wi-Fi(推荐,节省流量)
   • Wi-Fi 和移动数据
   • 电量充足时(仅当电量 > 20%)
6. 选择是否备份视频
7. 选择是否删除已备份的本地照片(谨慎选择)
8. 启动首次备份

💡 提示:首次备份如果照片较多(数千张),可能需要较长时间
   建议在 Wi-Fi 环境、充电状态下启动

7.4 后台自动上传

iOS 特性:
• iOS 由于系统限制,后台上传时间有限(约 10-30 分钟)
• 建议每天打开一次 App 以触发后台备份
• 可使用「快捷指令」自动化(如充电时自动打开 Immich)

Android 特性:
• Android 后台限制相对宽松
• 可以设置 App 始终在后台运行
• 支持充电时自动备份、夜间自动备份

通用建议:
• 首次备份完成后,后续增量备份很快(只需上传新照片)
• 建议每天至少打开 App 一次确保触发备份
• 在充电时打开 App 可加速备份过程

8. AI 智能识别与人脸识别配置

8.1 启用 AI 功能

AI 功能默认在标准配置中启用,但需要以下条件:

1. immich-machine-learning 容器运行正常
2. 模型文件已下载(首次启动会自动下载)
3. 服务器有足够 CPU / 内存资源

验证 AI 服务:
管理面板 → 系统状态 → 检查 Machine Learning 状态

8.2 人脸识别

功能说明:
• 上传照片后,系统会自动检测照片中的人脸
• 相同人物的照片会被归为一组
• 用户可以为人物命名、合并/拆分人物

首次使用:
1. 等待系统处理所有照片(可能需要几个小时)
2. 在 Web 界面点击「人物」或「People」查看识别结果
3. 为每个识别到的人物命名(如「爸爸」「妈妈」「孩子」)
4. 系统会持续学习,识别效果越来越好

手动触发处理:
如果某些照片未被自动处理,可以在管理面板手动触发:
管理面板 → 作业 → 运行「人脸检测」或「CLIP 编码」

8.3 CLIP 语义搜索

CLIP(Contrastive Language-Image Pre-training)是 Immich 的核心 AI 功能之一:
它让你能用「文字描述」来搜索图片,而不需要依赖标签和文件名。

示例搜索:
• "日落" → 返回所有日落照片
• "海滩" → 返回海滩场景
• "狗" → 返回有狗的照片
• "生日蛋糕" → 返回生日聚会照片
• "全家福" → 返回多人合照
• "冬天" → 返回雪景/冬装照片

使用方法:
Web 界面顶部搜索框 → 输入文字描述 → 系统智能匹配

⚠️ 首次搜索可能需要等待 CLIP 模型处理所有照片(几小时到几天)
   取决于你的服务器性能和照片数量

8.4 智能相册(Smart Albums)

基于条件自动创建相册:
1. 点击「相册」→「创建智能相册」
2. 设置筛选条件:
   • 拍摄日期范围(如「2024 年之后」)
   • 拍摄地点(如「北京」)
   • 特定人物(如「宝宝」)
   • 特定标签(如「美食」)
   • 相机型号
   • 文件大小
3. 命名相册
4. 系统会自动将符合条件的照片加入相册
5. 新上传的符合条件的照片会自动加入

8.5 地图视图

Immich 会读取照片的 EXIF GPS 信息,在地图上展示照片:

1. 点击左侧菜单「地图」或「Map」
2. 可以看到所有带 GPS 信息的照片
3. 支持缩放、拖动、按时间筛选
4. 支持热力图模式(展示拍摄热点)

⚠️ 如果照片没有 GPS 信息,不会显示在地图上
   在手机相机设置中启用「保存位置信息」
   或使用后期处理工具添加 GPS 信息

9. 相册管理、共享与协作

9.1 创建相册

1. 登录 Web 界面
2. 点击左侧「相册」
3. 点击「创建相册」
4. 选择照片(可多选、批量选择)
5. 为相册命名(如「2025 年春节」「孩子成长」)
6. 可选:设置共享、设置封面
7. 完成创建

9.2 收藏夹

• 点击照片右上角的「❤」可收藏
• 收藏的照片出现在「收藏夹」中
• 常用于快速标记珍贵照片

9.3 共享相册

创建共享链接:
1. 在相册页面点击「共享」
2. 选择「创建共享链接」
3. 可选设置:
   • 是否允许他人上传(协作模式)
   • 是否允许下载
   • 是否显示 EXIF 信息
   • 密码保护(可选)
   • 有效期(可选)
4. 复制链接发送给家人/朋友

多人共享(家庭模式):
1. 管理面板 → 用户 → 邀请家庭成员注册
2. 每个成员有自己的独立空间
3. 可以创建「共享相册」(所有成员可查看/上传)
4. 管理员可设置每个用户的存储配额

9.4 从其他平台迁移

从 Google Photos 迁移:
1. 访问 Google Takeout: https://takeout.google.com
2. 选择 Google Photos,导出为 zip 文件
3. 下载导出文件到本地电脑
4. 使用 Immich CLI 工具上传:
   npm install -g @immich/cli
   immich login https://photos.yourdomain.com <你的API Key>
   immich upload --recursive /path/to/takeout/photos

从 iCloud 迁移:
1. Mac 电脑:照片 App → 文件 → 导出 → 导出原片
2. 将导出的照片上传到 Immich
3. iOS 设备:直接用 Immich App 备份所有相册

从百度网盘/OneDrive/其他云存储:
1. 下载所有照片到本地
2. 使用 Immich CLI 或 Web 界面批量上传

10. 数据备份与恢复策略

10.1 需要备份的内容

📁 ~/immich/upload/          → 原始照片和视频(核心!)
📁 ~/immich/postgres/        → PostgreSQL 数据库(核心!)
📁 ~/immich/model-cache/     → ML 模型缓存(可重下载,可选)
📁 ~/immich/thumbs/          → 缩略图(可重新生成,可选)
📁 ~/immich/encoded-video/   → 转码后的视频(可重新生成,可选)

10.2 备份方案一:手动备份(简单)

bash
# 1. 停止 Immich(防止数据库写入冲突)
cd ~/immich
docker compose down

# 2. 创建备份(带时间戳)
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=~/backups/immich_$BACKUP_DATE
mkdir -p $BACKUP_DIR

# 3. 压缩核心数据
cd ~/immich
sudo tar -czf $BACKUP_DIR/upload.tar.gz ./upload/
sudo tar -czf $BACKUP_DIR/postgres.tar.gz ./postgres/
sudo cp .env $BACKUP_DIR/.env
sudo cp docker-compose.yml $BACKUP_DIR/docker-compose.yml

# 4. 重启 Immich
docker compose up -d

# 5. 查看备份
ls -lh $BACKUP_DIR/

10.3 备份方案二:自动备份脚本

创建自动备份脚本:

bash
# ~/immich/backup.sh

#!/bin/bash
# Immich 自动备份脚本

BACKUP_DIR="/home/yourusername/backups"
IMMICH_DIR="/home/yourusername/immich"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="immich_$DATE"
RETENTION_DAYS=14

# 创建备份目录
mkdir -p $BACKUP_DIR/$BACKUP_NAME

# 停止 Immich
cd $IMMICH_DIR
docker compose down

# 备份核心数据
cd $IMMICH_DIR
tar -czf $BACKUP_DIR/$BACKUP_NAME/upload.tar.gz ./upload/
tar -czf $BACKUP_DIR/$BACKUP_NAME/postgres.tar.gz ./postgres/

# 备份配置文件
cp .env $BACKUP_DIR/$BACKUP_NAME/
cp docker-compose.yml $BACKUP_DIR/$BACKUP_NAME/

# 重启 Immich
docker compose up -d

# 删除 14 天前的旧备份
find $BACKUP_DIR -name "immich_*" -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;

# 日志
echo "[$DATE] 备份完成: $BACKUP_NAME" >> $BACKUP_DIR/backup.log
bash
# 设置可执行权限
chmod +x ~/immich/backup.sh

# 测试运行
cd ~/immich
./backup.sh

10.4 设置定时任务

bash
# 编辑 crontab
crontab -e

# 添加(每周日凌晨 3 点备份)
0 3 * * 0 /home/yourusername/immich/backup.sh

# 保存退出
# 查看当前任务
crontab -l

10.5 数据恢复

bash
# 1. 停止当前 Immich
cd ~/immich
docker compose down

# 2. 备份当前数据(以防恢复失败)
mv ./upload ./upload_backup_$(date +%Y%m%d)
mv ./postgres ./postgres_backup_$(date +%Y%m%d)

# 3. 从备份恢复
BACKUP_FILE="/path/to/backups/immich_20260612_030000"
tar -xzf $BACKUP_FILE/upload.tar.gz
tar -xzf $BACKUP_FILE/postgres.tar.gz

# 4. 重启 Immich
docker compose up -d

# 5. 检查数据是否恢复
# 等待容器启动后,访问 Web 界面,检查照片是否可用
# 首次恢复后,缩略图可能需要重新生成(需要时间)

11. 性能优化与资源调整

11.1 根据硬件调整配置

低配服务器(2 核 4GB):
• MACHINE_LEARNING_WORKERS=1
• 关闭视频转码(如视频上传量不大)
• CLIP_MODEL=ViT-B-32__openai(最快的模型)

标准服务器(4 核 8GB):
• MACHINE_LEARNING_WORKERS=2
• 开启视频转码(但限制并发)
• CLIP_MODEL=ViT-B-32__openai

高配服务器(8 核 32GB+):
• MACHINE_LEARNING_WORKERS=4
• 开启所有 AI 功能
• CLIP_MODEL=ViT-L-14__openai(最准确的模型)
• 考虑添加 GPU 加速

11.2 视频转码优化

视频转码是 Immich 中最耗时的操作之一:

优化方法:
1. 在手机端预先压缩(部分 Android 手机可设置)
2. 在 App 设置中调整「视频上传质量」
3. 在服务器端启用硬件加速(VA-API / NVENC)

启用 NVENC(NVIDIA GPU 加速):
在 docker-compose.yml 中为 immich-microservices 添加:
environment:
  NVIDIA_VISIBLE_DEVICES: all
runtime: nvidia

需要先在服务器上安装 NVIDIA Container Toolkit

11.3 存储扩展

方法一:移动到更大的磁盘
1. 停止 Immich
2. 将 upload 目录复制到新位置
3. 修改 .env 中的 UPLOAD_LOCATION
4. 重启 Immich

方法二:使用网络存储(NFS)
1. 挂载 NFS 共享到本地目录
2. 将 UPLOAD_LOCATION 指向该目录
3. 注意:NFS 会影响上传速度,建议局域网内使用

方法三:使用对象存储(S3)
Immich 支持 S3 兼容存储(MinIO、AWS S3)
适合大容量、高可用的部署场景

11.4 定期清理

清理临时文件和缓存:
docker system prune -af
docker volume prune -f

清理日志:
docker compose logs immich-server --tail=1000 > logs-$(date +%Y%m%d).txt
docker compose logs immich-server --tail=100  # 只保留最近 100 行

12. 常见问题与故障排查

12.1 启动失败 / 容器无法启动

排查步骤:
1. 查看容器日志:docker compose logs
2. 检查数据库密码是否正确(.env 中的 DB_PASSWORD)
3. 检查磁盘空间:df -h
4. 检查权限问题:目录读写权限
5. 检查 Docker 网络:docker network ls

常见原因:
• PostgreSQL 数据库损坏(断电、强制关机导致)
• 磁盘空间不足
• 目录权限错误(使用 sudo 创建的目录可能属主为 root)
• 端口被占用(2283、3000、5432 等)

12.2 AI 识别不工作

排查步骤:
1. 检查 immich-machine-learning 容器是否在运行:
   docker compose ps | grep machine-learning
2. 查看容器日志:
   docker compose logs -f immich-machine-learning
3. 常见错误:
   • 模型下载失败(网络问题)→ 手动下载模型文件到 model-cache 目录
   • 内存不足 → 增加服务器内存或减少 workers
   • CPU 资源不足 → 升级服务器或增加 worker 数量

手动触发 AI 处理:
管理面板 → 作业 → 运行「人脸检测」「CLIP 编码」

12.3 照片上传失败

排查步骤:
1. 检查文件大小是否超过限制(默认最大 4GB)
2. 检查反向代理中的 client_max_body_size 配置
3. 检查磁盘空间是否充足
4. 检查容器日志查看具体错误
5. 检查上传目录权限:ls -la ~/immich/upload/

常见原因:
• 反向代理限制了文件大小 → 修改 Nginx/Caddy 配置
• 磁盘满 → df -h 检查
• 单个视频文件过大 → 压缩后上传
• 上传目录权限错误 → chown -R 你的用户:你的用户 ~/immich/upload

12.4 人脸识别人物混乱

问题表现:
• 同一个人被识别为多个不同的人物
• 多个人物被识别为同一个人

解决方法:
1. 在 Web 界面手动合并/拆分人物
2. 系统会根据你的操作持续学习
3. 照片越多,识别效果越好
4. 可在管理面板触发「重新检测人脸」作业

12.5 手机 App 无法连接

排查步骤:
1. 检查服务器是否可以从手机访问(浏览器访问 https://photos.yourdomain.com)
2. 检查域名证书是否有效(不要使用自签名证书)
3. 检查是否在同一 Wi-Fi 网络下的局域网问题
4. 检查是否有 DNS 解析问题
5. 在 App 中点击「测试连接」

常见原因:
• 手机网络无法访问服务器(服务器仅在局域网部署)
• SSL 证书问题 → 使用 Let's Encrypt 等受信任证书
• 域名解析错误 → 检查 DNS 设置
• 防火墙阻止了 443 端口 → 开放端口

12.6 照片无法在地图上显示

排查步骤:
1. 检查照片是否有 GPS EXIF 信息(右键属性查看)
2. 确认 Immich 已启用地图功能
3. 检查地图服务 API Key 是否正确(Maptiler)
4. 检查手机相机是否开启 GPS 保存

解决方法:
• 无 GPS 的照片:使用 ExifTool 手动添加 GPS 信息
• 使用手机 App:在照片查看器中手动设置地理位置
• 批量处理:使用 GPS 工具软件(如 GeoSetter)为照片添加 GPS 信息

总结

恭喜!你现在拥有了一个完全由自己掌控的私有照片管理系统:

✅ 手机自动备份:所有照片自动上传到服务器
✅ AI 智能识别:人脸识别、场景识别、CLIP 语义搜索
✅ 地图视图:在地图上查看照片拍摄地点
✅ 完全隐私:照片数据完全在你的服务器上
✅ 零订阅费:除了服务器成本,无任何额外费用
✅ 家庭共享:多人共用,可设置存储配额
✅ Web 访问:随时随地通过浏览器查看照片

Immich 是一个非常活跃的开源项目,每周都会有功能更新和改进。作为自部署用户,建议:

📌 每月执行一次:
• 检查 Immich 更新:docker compose pull && docker compose up -d
• 验证数据备份是否正常
• 查看磁盘空间

📌 每季度执行一次:
• 查看 Immich 发行说明(Release Notes)
• 测试恢复最近的备份(验证备份有效性)
• 检查服务器资源使用情况:CPU、内存、磁盘

📌 每年执行一次:
• 评估是否需要升级服务器硬件(存储空间、CPU、内存)
• 全面检查系统健康状态

📖 延伸阅读



延伸阅读

免责声明

本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。