Immich 数据库图形化接入指南:用 pgAdmin 连接并探索 Immich 的 Postgres 数据库
Immich 的全部核心数据(资产元数据、人脸与向量索引、标签、相册、用户等)都存储在一个专用 Postgres 容器中。本篇基于仓库内 database-gui 指南 展开,教你通过 Docker 叠加层方式安装 pgAdmin,将其注册为 Immich 的图形化数据库客户端,并结合 docker-compose.yml、example.env 与服务器源码,逐项解释每个连接参数的来源、数据库内部实际包含的扩展与表结构,以及连接后常用的查询与备份操作。
为什么选择 pgAdmin,以及它如何触达 Immich 数据库
Immich 默认的部署形态中,Postgres 运行在独立的 Docker 容器里。查看 docker/docker-compose.yml 可以看到 database 服务的定义:
database:
container_name: immich_postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:...
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: '--data-checksums'
# DB_STORAGE_TYPE: 'HDD' # 数据库不在 SSD 上时取消注释
volumes:
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
shm_size: 128mb
restart: always
由此可以得到三个关键事实,它们直接决定了后文连接参数怎么填:
- 容器名固定为
immich_postgres:container_name: immich_postgres。由于 pgAdmin 与它运行在同一个 Compose 网络中,可以通过 Docker 内置 DNS 直接用这个容器名作为主机名访问,而该服务并没有向宿主机发布 5432 端口(compose 文件中没有ports段),所以从宿主机用localhost:5432是连不通的。 - 凭据与库名全部由
.env注入:POSTGRES_PASSWORD、POSTGRES_USER、POSTGRES_DB分别映射自环境变量DB_PASSWORD、DB_USERNAME、DB_DATABASE_NAME。示例值见 docker/example.env:DB_PASSWORD=postgres、DB_USERNAME=postgres、DB_DATABASE_NAME=immich。 - 数据库启用了数据校验和:
POSTGRES_INITDB_ARGS: '--data-checksums'在初始化时打开 checksum,这是官方 FAQ 中排查数据损坏问题的基础(可在 pgAdmin 的查询窗口里执行SHOW data_checksums验证)。
服务器端对这些变量也有兜底默认值。从源码 config.repository.ts 可以看到:
username: dto.DB_USERNAME || 'postgres',
password: dto.DB_PASSWORD || 'postgres',
database: dto.DB_DATABASE_NAME || 'immich',
也就是说,如果你从未改过 .env,默认连接参数就是 postgres / postgres / immich,与后文 pgAdmin 注册表的默认值完全一致。
第一步:以 Compose 叠加层方式安装 pgAdmin
官方指南给出的方式是:在与 docker-compose.yml 同级目录新建一个文件 docker-compose-pgadmin.yml,内容如下(这是官方指南的完整原文配置,可直接复制):
name: immich
services:
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin4_container
restart: always
ports:
- "8888:80"
environment:
PGADMIN_DEFAULT_EMAIL: admin@example.com
PGADMIN_DEFAULT_PASSWORD: strong-password
volumes:
- pgadmin-data:/var/lib/pgadmin
volumes:
pgadmin-data:
各配置项说明:
| 配置项 | 作用与注意事项 |
|---|---|
image: dpage/pgadmin4 |
pgAdmin 官方镜像,无版本锁定时拉取 latest |
ports: "8888:80" |
将宿主机 8888 映射到容器内 Web 服务的 80 端口。若 8888 被占用,可改为其他宿主机端口(如 "9999:80"),只需记住访问时用哪个端口 |
PGADMIN_DEFAULT_EMAIL |
首次登录 pgAdmin 使用的邮箱账号,必须改成你自己的值 |
PGADMIN_DEFAULT_PASSWORD |
首次登录密码,必须改成强密码(示例中的 strong-password 仅为占位) |
volumes: pgadmin-data:/var/lib/pgadmin |
命名卷,持久化保存你注册的服务器、查询历史等 pgAdmin 自身数据,与 Immich 数据完全隔离 |
name: immich |
与主 compose 文件顶层的 name: immich 保持一致,确保叠加后仍合并在名为 immich 的网络中——这是 pgAdmin 能用容器名 immich_postgres 解析数据库的前提 |
写好后,执行叠加启动命令(注意 -f 的顺序,主文件在前、叠加文件在后):
docker compose -f docker-compose.yml -f docker-compose-pgadmin.yml up
该命令会同时启动 Immich 全家桶与 pgadmin4_container。由于顶层 name 相同,Compose 会把两个文件的服务合并进同一个项目与网络,pgAdmin 由此获得对 immich_postgres 的内网访问能力。
第二步:在 pgAdmin 中注册 Immich 数据库服务器
- 浏览器打开
http://localhost:8888(如果改了端口映射则用你的端口),用上一步设置好的PGADMIN_DEFAULT_EMAIL/PGADMIN_DEFAULT_PASSWORD登录。 - 在左侧导航树右键
Servers,选择Register >> Server..。 - 在弹出的注册向导中,切换到
Connection选项卡,按下表填写:
| Name | Value | 来源 |
|---|---|---|
| Host name/address | immich_postgres |
数据库服务的 container_name(见 docker/docker-compose.yml) |
| Port | 5432 |
Postgres 默认端口;服务未发布端口,仅内网可达 |
| Maintenance database | immich |
即 .env 中的 DB_DATABASE_NAME |
| Username | postgres |
即 .env 中的 DB_USERNAME |
| Password | postgres |
即 .env 中的 DB_PASSWORD |
注意:上表取值与 example.env 中的默认参数一致。官方指南特别提醒——如果你修改过
.env文件,必须按实际值相应调整。例如你把DB_PASSWORD改成了随机字符串,那么这里 Username/Password 就要填.env中的新值,而不是上表默认值。
- 点击 Save 完成连接。之后展开
Servers节点即可看到immich库。
一个实用的技巧:注册向导的 Maintenance database 填的是 Immich 主库,pgAdmin 会用它建立初始会话;连上后你仍可切换查看该 Postgres 实例上的其他数据库(如 postgres、template1)。
连上之后能看到什么:Immich 数据库的内部结构
Immich 使用的并不是裸 Postgres。从 compose 中的镜像标签 14-vectorchord0.4.3-pgvectors0.2.0 可知,当前发行版基于 Postgres 14,并预装了 VectorChord 与 pgvector 扩展。根据 postgres-standalone 指南,Immich 兼容的 Postgres 版本范围是 >= 14, < 20,VectorChord 用于加速智能搜索(CLIP 向量检索)与人脸识别的最近邻查询,服务器启动时会校验 VectorChord 版本兼容性(接受范围 >= 0.3, < 2.0)。
在 pgAdmin 中展开 immich 库的 Schemas -> public,你会发现与服务器源码 server/src/schema/tables/ 目录一一对应的表,几个核心表包括:
asset/asset_exif/asset_file:媒体资产主表、EXIF 元数据、文件实体(含缩略图路径与类型);smart_search/face_search:分别存储 CLIP 与人脸检测的向量嵌入,是"以文搜图"和人脸识别的物理基础;person/asset_face:人脸聚类结果与每张图中人脸的边界框;tag/tag_asset/tag_closure:标签体系及其层级闭包;album/album_user/album_asset:相册及成员、资产关联;user/session/api_key:用户、登录会话与 API 凭据;library/system_metadata/workflow_log:外部库配置、系统设置(key = 'system-config'行存放自定义设置)、导入工作流日志等。
服务器端通过 Kysely 类型化访问这些表,实体与列的权威定义在 server/src/database.ts(如 Asset、User、Person 等类型与 columns 列清单),因此你在 pgAdmin 中看到的表名、列名可以直接与源码对照。
在 pgAdmin 中执行查询与常用语句
pgAdmin 内置 SQL 编辑器(Query Tool),打开后即可执行 database-queries 指南 中收录的常用语句,例如:
-- 按原始文件名查找资产
SELECT * FROM "asset" WHERE "originalFileName" = 'PXL_20230903_232542848.jpg';
-- 按部分 ID 查找
SELECT * FROM "asset" WHERE "id"::text LIKE '%ab431d3a%';
-- 查找 checksum 完全相同的重复资产(排除已进回收站的)
SELECT T1."checksum", array_agg(T2."id") ids FROM "asset" T1
INNER JOIN "asset" T2 ON T1."checksum" = T2."checksum" AND T1."id" != T2."id" AND T2."deletedAt" IS NULL
WHERE T1."deletedAt" IS NULL GROUP BY T1."checksum";
-- 按类型统计数量
SELECT "asset"."type", COUNT(*) FROM "asset" GROUP BY "asset"."type";
官方文档对此有一则必须强调的危险提示:直接修改数据库可能引发不可预期的问题,请尽量避免手动改动数据,并且操作前务必先做好最新备份。备份命令参考 backup-and-restore 指南:
docker exec -t immich_postgres pg_dump --clean --if-exists --dbname=<DB_DATABASE_NAME> --username=<DB_USERNAME> | gzip > "/path/to/backup/dump.sql.gz"
如果你在 pgAdmin 中维护的是自行修改过密码的实例,密码变更操作同样是 SQL 语句(ALTER USER <DB_USERNAME> WITH ENCRYPTED PASSWORD 'newpassword';),改完记得同步更新 .env 中的 DB_PASSWORD。
常见问题与替代方案
连不上或认证失败:绝大多数情况是 .env 中的 DB_USERNAME / DB_PASSWORD / DB_DATABASE_NAME 与你在 pgAdmin 填的不一致。逐项对照 example.env 与你的实际配置即可。另一种特殊场景是采用了外部 Postgres(通过 .env 中的 DB_URL 连接已有数据库,见 postgres-standalone 指南),此时 Host name、端口、库名与凭据应填 DB_URL 中对应的值,而不是 immich_postgres。
pgAdmin 端口冲突:把叠加文件中的 "8888:80" 改为空闲端口,重启后从新端口访问即可,不影响对数据库的连接参数。
不想装 GUI 的替代方式:官方同样提供了命令行直连方式,在宿主机执行
docker exec -it immich_postgres psql --dbname=<DB_DATABASE_NAME> --username=<DB_USERNAME>
即可进入 psql 交互终端,适合习惯命令行或脚本化操作的用户;pgAdmin 的价值则在于可视化的表结构浏览、查询编辑器与结果导出,二者可配合使用。
小结
整条链路可以概括为:.env 提供凭据(DB_USERNAME / DB_PASSWORD / DB_DATABASE_NAME),docker/docker-compose.yml 将其注入 immich_postgres 容器且不对外发布端口,pgAdmin 通过 Compose 叠加层加入同一网络、以容器名为主机名完成内网连接,随后即可图形化地浏览 VectorChord 向量索引、资产/人脸/标签等表结构并执行查询。所有默认值均可在仓库源码与示例配置中逐一核对,连接参数如有疑义,以你实际部署目录中的 .env 为准。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
