Immich 数据库迁移到统一 PostgreSQL 容器(完整流程 + 脚本)
本文记录了将 Immich 从原本独立的 immich-postgres 数据库迁移到新的统一 PostgreSQL 数据库容器的完整步骤。迁移目标是让多个项目共享同一个公用数据库容器,以简
本文记录了将 Immich 从原本独立的 immich-postgres 数据库迁移到新的统一 PostgreSQL 数据库容器的完整步骤。迁移目标是让多个项目共享同一个公用数据库容器,以简化维护、提高性能并统一备份策略。
以下流程适用于基于 Docker + Portainer 环境的部署。
📌 目录
- 创建新的 PostgreSQL 公用容器
- 从旧的
immich-postgres中导出数据 - 在新库中创建用户与数据库(空库)
- 为新数据库安装扩展、配置权限
- 恢复数据到新库(必须使用超级用户)
- 验证恢复结果
- 修改 Immich 服务配置,使其使用新的数据库(基于 URL 连接方式)
- 迁移检查与收尾
1. 创建新的 PostgreSQL 公用容器(global-postgres)
1.1 创建共享网络(global-net)
docker network create global-net或在 Portainer:
Networks → Add network → Name: global-net → Create
1.2 在 Portainer 中创建新的 PostgreSQL Stack
这里使用 Immich 官方镜像的 PostgreSQL 扩展版(包含 pgvector、vchord、cube 等)。
docker-compose.yml:
version: "3.9"
services:
postgres:
container_name: global-postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: super_strong_password
volumes:
- /opt/global-postgres/data:/var/lib/postgresql/data
networks:
- global-net
networks:
global-net:
external: true
在 Portainer 中:
Stacks → Add Stack → 粘贴上方 compose → Deploy
2. 从旧的 immich-postgres 中导出数据库备份
假设旧容器名为:immich_postgres
以下命令在宿主机执行。
docker exec immich_postgres \
pg_dump -U postgres immich > /root/immich_backup.sql
根据你的实际用户/数据库名调整 postgres 和 immich。
3. 在新 PostgreSQL 中创建用户与数据库(空库)
3.1 创建需要的用户
docker exec -it global-postgres \
psql -U postgres -c "CREATE USER immich_user WITH PASSWORD 'immich_password';"
3.2 创建空库(暂由 postgres 拥有)
docker exec -it global-postgres \
psql -U postgres -c "CREATE DATABASE immich;"
4. 在空库中安装 Immich 所需扩展
进入新数据库:
docker exec -it global-postgres psql -U postgres -d immich
安装扩展(按 Immich 官方要求):
CREATE EXTENSION cube;
CREATE EXTENSION earthdistance;
CREATE EXTENSION vector;
CREATE EXTENSION vchord;
\q5. 恢复备份文件到新数据库(必须使用 postgres)
5.1 将备份复制到容器
docker cp /root/immich_backup.sql global-postgres:/tmp/immich_backup.sql
5.2 用超级用户恢复(不可用 immich_user)
docker exec -it global-postgres \
psql -U postgres -d immich -f /tmp/immich_backup.sql
⚠️ 注意:
如果恢复过程中大量 ERROR 提示“某类型不存在”,说明扩展未成功安装,需要返回「步骤 4」重新执行。
6. 数据恢复后验证内容是否正确导入
6.1 查看所有扩展
docker exec -it global-postgres \
psql -U postgres -d immich -c "\dx"
应至少看到:
vector
vchord
cube
earthdistance6.2 查看表数量
docker exec -it global-postgres \
psql -U postgres -d immich -c "\dt"
应看到大量表,例如:
assets
albums
users
face_search
smart_search
...
6.3 检查表数量是否合理
docker exec -it global-postgres \
psql -U postgres -d immich -c "SELECT COUNT(*) FROM pg_tables WHERE schemaname='public';"
7. 修改 Immich 服务器,使其使用新的 PostgreSQL
⚠️ Immich 官方文档要求使用 DB_URL,而非 DB_HOST。
示例配置:
7.1 修改 immich-server 的环境变量
将:
DB_HOST=immich_postgres
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=password
DB_DATABASE_NAME=immich
改为:
DB_URL=postgresql://immich_user:immich_password@global-postgres:5432/immich
7.2 让 Immich 容器加入 global-net
在 docker-compose 或 Portainer stack 中添加:
networks:
- global-net
确保:
networks:
global-net:
external: true
7.3 最终示例(immich-server 部分)
services:
immich-server:
...
environment:
DB_URL: postgresql://immich_user:immich_password@global-postgres:5432/immich
networks:
- default
- global-net
然后在 Portainer 中:
Update Stack → Immich 自动重建
8. 启动 Immich 并验证
进入 Immich Web:
- 能看到全部照片
- 用户账户存在
- 地图功能正常(earthdistance)
- 人脸识别功能正常(vector + vchord)
- 搜索功能可正常使用
说明迁移成功。
确认无误后,可删除旧容器:
docker stop immich_postgres
docker rm immich_postgres
📦 完整流程来源说明(可用于 Blog 注脚)
迁移流程参考了以下来源与最佳实践:
- Immich 官方文档数据库配置章节
- PostgreSQL 官方扩展安装文档
- Docker 官方文档关于容器数据迁移方法
- pg_dump/psql 官方备份恢复流程
- 社区在 Immich + pgvector 场景下的迁移案例
🎉 结语
通过以上流程,你已经成功实现:
✔ 把 Immich 数据库迁移到统一 PostgreSQL 服务
✔ 实现多个项目共享数据库容器
✔ 清晰控制用户权限
✔ 正确处理扩展,包括 vector、vchord、cube、earthdistance
✔ 使用官方推荐的 URL 连接方式配置 Immich
✔ 未来可以轻松扩展到 Plausible、Paperless 等项目
相关代码:
CREATE USER immich_user WITH PASSWORD 'immich_password';
CREATE DATABASE immich OWNER immich_user;
GRANT ALL PRIVILEGES ON DATABASE immich TO immich_user;
\c immich
GRANT ALL ON SCHEMA public TO immich_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT ALL ON TABLES TO immich_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT ALL ON SEQUENCES TO immich_user;
SELECT datname, datdba::regrole FROM pg_database WHERE datname='immich';
CREATE EXTENSION IF NOT EXISTS cube;
CREATE EXTENSION IF NOT EXISTS earthdistance;
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS vchord;
\q
docker exec immich_postgres \
pg_dump -U postgres immich > immich_backup.sql
docker cp immich_backup.sql global-postgres:/tmp/immich_backup.sql
docker exec -it global-postgres \
psql -U immich_user -d immich -f /tmp/immich_backup.sql
docker exec -it global-postgres \
psql -U postgres -d immich -f /tmp/immich_backup.sql