Immich 3.3.3 备份与迁移:原图、相册和数据库一起恢复
针对已有 Immich 3.3.3 实例,停写后保存数据库、完整图库与配置,在独立空目标恢复,再核对旧账号、原图、单照片相册和新增上传。
迁移 Immich 时,要一起带走原图、用户和相册关系。先在空环境恢复一份完整备份,用旧账号找到旧照片和相册,再上传新照片,能把“文件已经复制”和“服务可以继续使用”分开核对。
以下处理 Immich 3.3.3 的同版本冷恢复,前提是已有按官方 Compose 配置运行的实例。操作期间暂停上传,保留原实例和原盘;恢复目标使用另一套空目录与数据库。其他版本应查对应版本的恢复文档。
先确定资源和恢复目标
官方要求至少 6GB 内存、2 核 CPU,建议 8GB、4 核;4GB 运行有关闭机器学习的条件。如果为容器设置内存上限,官方还要求 PostgreSQL 至少 2GB。数据库目录应放在本地 SSD,不能放在网络共享上。照片空间还要容纳缩略图、转码和备份,不能只按原图总量准备。
准备迁移机器时,可先对照 Docker VPS 的资源清单检查内存、本地磁盘和备份空间。恢复前应已有可用的 Docker 与 Compose 环境。
如果确实需要另租一台恢复机,先按上述内存、本地 SSD 和图库容量核对实例与磁盘,再从 阿里云ECS选购入口 查看可用规格。已有满足条件的空闲机器,可以直接用于恢复,不必另买服务器。
下面的读者命令按官方默认值写:DB_USERNAME=postgres、DB_DATABASE_NAME=immich、UPLOAD_LOCATION=./library、DB_DATA_LOCATION=./postgres。改过用户名、数据库名或路径的实例,要把命令中的对应值换成实际配置。
恢复示例使用与原实例分开的空 Linux 环境,目标不能已有同名 Immich 容器。官方 Compose 有固定的 container_name 和项目名;在同一个 Docker 守护进程里只换一个目录,不能保证得到独立实例。若要同机并存,需先单独处理项目名、容器名、端口和挂载路径,不能直接套用本段命令。
固定与备份一致的版本
保存现用的 .env、docker-compose.yml 和镜像记录,恢复时不要下载 latest。需要核对原始配置时,可对照 3.3.3 的 Compose 文件与 example.env,不要覆盖正在使用的配置。
本例 .env 的 IMMICH_VERSION 为 v3.3.3,数据库密码沿用原实例。保留该版官方 PostgreSQL 镜像及必需扩展,不换成普通 PostgreSQL 镜像。数据库与 Valkey 的固定镜像摘要也随 Compose 一起保存。
如果使用 IMMICH_CONFIG_FILE、外部图库或其他额外挂载,另外保存对应文件和容器内路径;后面的命令只直接覆盖官方默认的 .env、Compose 与 library。
留一组能核对的数据
在暂停服务前,用普通账号准备一张可识别的照片,建一个只放这张照片的相册。记录账号、相册名,以及下载所得原图的 SHA-256:
sha256sum "原图文件.png"
恢复后继续用同一个账号和同一张原图核对。只比较图片文件数量,不能确认账号、相册关系或后续写入是否正常。
停写后备份数据库和整个文件库
以下命令在原实例目录运行。library 是本例的完整 UPLOAD_LOCATION,不要只挑其中的原图目录。执行账户须能读取整个图库,并保留文件与目录的属主、权限;遇到权限错误先核对已有授权,不放宽受保护目录。复制失败时停止,不能继续恢复。停服务后也要确认其他同步程序没有继续写入同一图库。
set -euo pipefail
umask 077
cd "$HOME/immich-app"
BACKUP_DIR="$HOME/immich-backups/$(date -u +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
chmod 700 "$BACKUP_DIR"
docker compose stop immich-server
docker compose exec -T database pg_dump \
--clean --if-exists --dbname=immich --username=postgres \
> "$BACKUP_DIR/database.sql"
cp -a ./library "$BACKUP_DIR/library"
cp .env docker-compose.yml "$BACKUP_DIR/"
chmod 600 "$BACKUP_DIR/.env" "$BACKUP_DIR/database.sql"
(
cd "$BACKUP_DIR"
sha256sum database.sql .env docker-compose.yml > checksums.sha256
find library -type f -print0 | sort -z | xargs -0 -r sha256sum > media.sha256
)
docker compose images > "$BACKUP_DIR/images.txt"
docker compose stop
先停 immich-server,数据库仍运行,才能执行这份逻辑备份;完成后再停原项目的其余容器。不要用删除卷或清空原目录代替停机。
数据库保存用户、文件和相册等关系,自动数据库备份不包含照片和视频。完整副本还要有整个 UPLOAD_LOCATION、Compose 和环境配置。使用外部图库时,另外保存原图库,并记录它在容器内的挂载路径。把整份备份复制到原盘之外的独立存储,并限制可读取它的账户;其中含环境配置和用户数据。仅在原机多留一个文件夹,不能应对原盘损坏。
在空目标里先恢复数据库
将完整备份复制到恢复目标。下面的 BACKUP_DIR 要改成目标机上实际的备份目录;RESTORE_DIR 必须不存在。示例保留默认数据库名和相对目录,先复制文件并验证校验和:
set -euo pipefail
umask 077
BACKUP_DIR="/srv/immich-backups/待恢复的备份目录"
RESTORE_DIR="$HOME/immich-restore-333"
test -d "$BACKUP_DIR"
test ! -e "$RESTORE_DIR"
(
cd "$BACKUP_DIR"
sha256sum -c checksums.sha256
sha256sum -c media.sha256
)
mkdir -m 700 "$RESTORE_DIR"
cp "$BACKUP_DIR/.env" "$BACKUP_DIR/docker-compose.yml" "$RESTORE_DIR/"
cp -a "$BACKUP_DIR/library" "$RESTORE_DIR/library"
mkdir -m 700 "$RESTORE_DIR/postgres"
chmod 600 "$RESTORE_DIR/.env"
cd "$RESTORE_DIR"
sha256sum -c "$BACKUP_DIR/media.sha256"
创建容器前,检查目标 .env:UPLOAD_LOCATION=./library、DB_DATA_LOCATION=./postgres、IMMICH_VERSION=v3.3.3,数据库密码与备份保持一致。绝对路径和外部挂载也要改到恢复目标,不能指回原实例。
数据库必须是全新的,immich-server 还没在它上面运行。先只启动数据库与缓存,等待 PostgreSQL 的 TCP 服务就绪:
docker compose config --quiet
docker compose create
docker compose up -d database redis
ready=0
for attempt in $(seq 1 60); do
if docker compose exec -T database pg_isready \
-h 127.0.0.1 -U postgres -d immich; then
ready=1
break
fi
sleep 2
done
test "$ready" -eq 1
接着按官方命令行恢复流程导入 SQL。下面只在导入流中调整 search_path,原备份文件保持不变:
set -euo pipefail
sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" \
"$BACKUP_DIR/database.sql" \
| docker compose exec -T database psql \
--dbname=immich --username=postgres \
--single-transaction --set ON_ERROR_STOP=on
导入成功后才启动其余服务:
docker compose up -d
docker compose ps
docker compose logs --tail=100 immich-server
导入出错时保留目标和日志,不继续启动应用,也不要把同一份 SQL 反复导入半完成的数据库。先确认版本、空库和报错位置,再决定如何处理这份恢复目标。
用旧数据和新写入一起验收
先用旧普通账号登录,找回原相册,下载旧原图并重新计算 SHA-256。再上传一张不同的照片,下载它并核对哈希。入口是否切换,要等这些数据核对通过后再决定;在此之前不要让自动上传的手机同时连接两个实例。
2026 年 10 月 15 日,在 ARM64 Docker Desktop 中用一张合成 PNG 和一个单照片相册,通过正常应用 API 核对了同版恢复:
| 核对对象 | 实际结果 |
|---|---|
| 旧普通账号 | 恢复后重新登录,用户 ID 保持一致 |
| 旧原图 | 重新下载,SHA-256 与恢复前一致 |
| 单照片相册 | 名称相同,assetCount 为 1,albumThumbnailAssetId 对应原照片 |
| 新增照片 | 恢复后上传另一张合成 PNG,再下载,SHA-256 一致 |
| 备份原件 | SQL 和完整媒体副本保持原有哈希,没有被恢复过程覆盖 |
实验关闭了机器学习,数据库配额未满足官方在 Docker 限额下至少 2GB 的条件,这个小样本结果不能作为生产配置或容量依据。网页入口、TLS、手机客户端、AMD64 和跨版本升级未在本次验证。




