Courses
在不同会话间来回切换、死记硬背语法、还得祈祷没有把破坏性查询打错,这些很快就会让人厌倦。没有可视化查询计划、没有架构浏览器、也没有简单的数据库备份方式。它能用,但离理想还差得远。
pgAdmin 4 用专为 PostgreSQL 打造的基于浏览器的 GUI 解决了这些问题。把它跑在 Docker 里意味着本地零安装——您只需启动容器即可。
本文将演示如何使用 Docker Compose 设置 PostgreSQL 和 pgAdmin 4,连接这两个容器,并使用 pgAdmin 的 Query Tool、架构浏览器和备份功能。
要跟着操作,您需要在机器上安装并运行 Docker。如果您是 Docker Compose 新手,请阅读我们的指南,了解它如何简化多容器开发。
什么是 pgAdmin 4?
pgAdmin 4 是一款开源、基于浏览器的 PostgreSQL 管理与开发平台。通过浏览器访问,无需安装桌面应用。它提供 GUI 来管理数据库、运行查询、检查架构并处理备份——无需接触命令行。
官方 Docker 镜像是 dpage/pgadmin4,由 pgAdmin 开发团队维护。
在 Docker 中运行 pgAdmin 4 相比本地安装有几个实际优势。首先是可移植性——您的整个数据库环境都在一个可与团队共享的 docker-compose.yml 文件中。其次是没有版本冲突——pgAdmin 在其独立容器中运行,完全与您机器上的其他内容隔离。完成后,执行 docker compose down 即可清理干净。
pgAdmin 4 与其他 PostgreSQL GUI 的对比
数据库管理 GUI 工具并不稀缺。下面是 pgAdmin 4 与两款常见替代品的对比。

pgAdmin 4 与流行替代品对比
DBeaver 和 TablePlus 都是不错的工具,但两者都没有官方 Docker 镜像。如果您的 PostgreSQL 实例已经在 Docker 中运行,那么 pgAdmin 4 非常契合——您只需在 docker-compose.yml 中添加一个服务,所有组件即可在同一网络中一起运行。
使用 Docker Compose 搭建环境
让 PostgreSQL 与 pgAdmin 4 一起运行的最快方式是使用单个 docker-compose.yml 文件。如果您不熟悉该主题,我们的 Docker Compose 指南涵盖了基础知识。这里我将重点介绍 pgAdmin 的特定配置。
以下是可直接复制粘贴的完整文件:
services:
postgres:
image: postgres:18
container_name: postgres
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql
networks:
- pgnetwork
pgadmin:
image: dpage/pgadmin4:9.13
container_name: pgadmin
environment:
PGADMIN_DEFAULT_EMAIL: you@yourdomain.com
PGADMIN_DEFAULT_PASSWORD: password
PGADMIN_LISTEN_PORT: 5050
ports:
- "5050:5050"
volumes:
- pgadmin_data:/var/lib/pgadmin
depends_on:
- postgres
networks:
- pgnetwork
volumes:
postgres_data:
pgadmin_data:
networks:
pgnetwork:
depends_on 字段告诉 Docker Compose 先启动 postgres 容器再启动 pgadmin。否则,pgAdmin 可能会在 PostgreSQL 尚未就绪时启动并连接失败。它并不会等待 PostgreSQL 完全健康——只会等待容器启动。但这已足以避免大多数竞态条件。
pgAdmin 4 环境变量
需要两个环境变量:
PGADMIN_DEFAULT_EMAIL- 您用于登录 pgAdmin Web 界面的邮箱地址PGADMIN_DEFAULT_PASSWORD- 该账户的密码
第三个可选,但建议指定:
PGADMIN_LISTEN_PORT- pgAdmin 在容器内监听的端口。默认是 80,但将其设为5050可以在映射端口时更清晰。
不过,把凭据硬编码在 Compose 文件中并非好主意,尤其当该文件会进入版本控制时。请将它们放入 .env 文件。
在与 docker-compose.yml 相同的目录下创建一个 .env 文件:
POSTGRES_USER=admin
POSTGRES_PASSWORD=secret
POSTGRES_DB=mydb
PGADMIN_DEFAULT_EMAIL=admin@example.com
PGADMIN_DEFAULT_PASSWORD=secret
然后在 Compose 文件中引用这些变量:
# postgres
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
# pgadmin
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
运行命令时,Docker Compose 会自动读取 .env 文件,因此无需额外配置。只要记得把 .env 加入 .gitignore,您的凭据就不会进入仓库。
卷与数据持久化
映射到 /var/lib/pgadmin 的卷是 pgAdmin 存储数据的位置,例如会话数据、已保存的服务器连接和配置。如果在 compose 文件中去掉它,每次容器重启都会丢失所有这些数据。
在当前的 compose 文件中,您使用了一个由 Docker 在主机上管理的命名卷。数据会在容器重启、重建和镜像更新后继续保留——只要您不使用 docker volume rm 显式删除该卷。
启动栈并访问 pgAdmin 4
准备好 docker-compose.yml 后,启动整个栈只需一条命令:
docker compose up -d
-d 标志会以分离模式运行两个容器——它们在后台启动,您的终端保持可用。要验证两个容器是否都在运行:
docker ps
您应能看到 postgres 和 pgadmin,其状态为 Up。

容器状态
如果有异常,请检查 pgAdmin 日志:
docker logs pgadmin
正常启动看起来类似这样:

pgAdmin 启动日志
如果看到错误,通常是以下三种之一:
-
密码验证失败:您的
PGADMIN_DEFAULT_PASSWORD在.env文件中缺失或格式不正确 -
端口已被占用:已有其他程序占用了 5050 端口;请在 Compose 文件中更改宿主机端口
-
没有该文件或目录:卷路径错误,或容器无权写入该路径
当两个容器都已启动且日志正常后,打开浏览器并访问 http://localhost:5050:

pgAdmin 登录页
使用您在 PGADMIN_DEFAULT_EMAIL 和 PGADMIN_DEFAULT_PASSWORD 中设置的邮箱与密码登录。随后您会进入 pgAdmin 仪表板,准备注册您的 PostgreSQL 服务器:

pgAdmin 主页
将 pgAdmin 4 连接到您的 PostgreSQL 容器
在 pgAdmin 侧边栏中,右键单击 Servers - Register - Server。会弹出一个对话框,包含两个需要填写的选项卡:General 和 Connection。
General 选项卡
给您的服务器起个有意义的名字——比如 local-dev-postgres。这只是 pgAdmin 内部的标签,选择对您环境有意义的名称即可。

服务器注册 - General 选项卡
Connection 选项卡
这里不要使用 localhost。
在 Docker 网络内,localhost 指的是容器本身——不是您的宿主机,也不是 PostgreSQL 容器。Docker 有自己的内部 DNS,会用 docker-compose.yml 中定义的服务名来解析容器名。因此,如果您的 PostgreSQL 服务名是 postgres,这就是您要使用的主机名。
按如下填写字段:
-
Host name/address:
postgres(来自docker-compose.yml的服务名) -
Port:
5432 -
Maintenance database:来自 Compose 文件的
POSTGRES_DB值(例如mydb) -
Username:
POSTGRES_USER的值(例如admin) -
Password:
POSTGRES_PASSWORD的值
单击 Save。

服务器注册 - Connection 选项卡
如果一切正确,服务器会出现在侧边栏,您可以展开并查看数据库:

服务器注册成功
这表示您已经连接成功。
使用 Query Tool
既然已连接,我将向您展示 pgAdmin 4 和 Postgres 的基础用法。
通过点击顶部菜单的 Tools - Query Tool 打开 Query Tool。界面包含三个面板:
- Editor:编写 SQL 的位置
- Data Output:运行查询后显示结果
- Messages:PostgreSQL 发送状态消息、错误和执行信息的地方

查询工具
编写并运行 SQL
我们来创建一个简单的 orders 表并插入一些数据。您可以点击播放按钮逐块运行,或按 F5(快捷键)。
运行以下语句创建表:
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_name VARCHAR(100) NOT NULL,
product VARCHAR(100) NOT NULL,
quantity INT NOT NULL,
order_date DATE DEFAULT CURRENT_DATE
);
插入几行数据:
INSERT INTO orders (customer_name, product, quantity)
VALUES
('Alice Johnson', 'Wireless Keyboard', 2),
('Bob Smith', 'USB-C Hub', 1),
('Carol White', 'Mechanical Keyboard', 3);
然后查询数据:
SELECT * FROM orders;

查询数据
结果会以表格形式显示在 Data Output 面板。您可以对列进行排序、调整列宽,并直接从网格复制行。
读取可视化查询计划
要了解运行查询时幕后发生了什么,请对 SELECT 语句运行 EXPLAIN ANALYZE:
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_name = 'Alice Johnson';

Explain Analyze 结果
Data Output 面板会显示原始输出。但 pgAdmin 提供了更好的方式。点击工具栏中的 Explain 按钮,pgAdmin 会将查询计划渲染为交互式图形。

图形化查询计划
对于这个查询来说还很简单,但在进行表连接或更复杂的数据聚合时,您将获得更多信息。
这很重要,因为阅读原始的 EXPLAIN 输出既慢又容易出错。可视化计划可以清楚地显示 PostgreSQL 是否在大型表上进行全表扫描,或某个索引存在却未被使用。
管理数据库架构
pgAdmin 的侧边栏为您提供数据库结构的全景视图——并允许通过 GUI 进行修改。
侧边栏树结构为:Servers - 您的服务器名 - Databases - 您的数据库 - Schemas - public - Tables。展开任意表,您会看到其 Columns、Indexes 和 Constraints 作为子节点列出。点击任意项即可在右侧面板查看详细信息。
创建与修改表
要创建新表,在架构下的 Tables 上右键,选择 Create - Table。会打开一个带有多个选项卡的对话框。

创建表
General 选项卡用于设置表名。切换到 Columns 选项卡以添加列——每一行可设置列名、数据类型、长度以及是否可为空。Constraints 选项卡用于设置主键、外键和唯一性约束。
要为现有表添加索引,在侧边栏展开该表,右键 Indexes,选择 Create - Index。选择要索引的列并选择索引类型——btree 是默认值,适用于大多数场景。

创建索引
备份与恢复
要备份数据库,前往 Tools - Backup。您需要选择一种格式:
- Custom:压缩的二进制格式;最灵活,通常是最佳选择,因为您可以从中恢复单个表
- Plain:可读的 SQL 脚本,您可以用任意文本编辑器打开并阅读
- Tar:未压缩归档;较少见,但在某些恢复流程中有用
选择格式和目标路径后,pgAdmin 会在后台运行 pg_dump 并将文件保存到您的本地机器。

创建备份
要恢复,前往 Tools - Restore,选择备份文件,并指定目标数据库。

从备份恢复
如果您在想这有何用处,设想一下在开发数据库上测试破坏性迁移。先做一次备份,然后运行迁移;如果出现问题,恢复备份即可回到已知状态。
在 Docker 中运行 pgAdmin 4 的最佳实践
让 pgAdmin 4 跑起来是一回事,让它长期稳定运行还需要了解一些额外事项。以下是一些实用建议。
不要在 Compose 文件中存放凭据
如果您的 docker-compose.yml 最终会进入版本控制(通常如此),硬编码的密码也会随之进入。请使用 .env 文件存放凭据,并将其加入 .gitignore。在生产环境中,更进一步使用 Docker secrets,它会将敏感值以文件而非环境变量的形式挂载。
切勿将 pgAdmin 端口公开
默认情况下,Docker 会将端口绑定到 0.0.0.0,即所有网络接口——包括公共接口。在远程服务器上,这会让您的 pgAdmin 实例可从互联网访问。请显式绑定到 127.0.0.1:
ports:
- "127.0.0.1:5050:5050"
这将使 pgAdmin 仅能从服务器本机访问。如果需要远程访问,请使用 SSH 隧道或带认证的反向代理。
固定镜像标签
使用 dpage/pgadmin4:latest 会导致下次有人运行 docker compose pull 时拉取新版本。新版本可能表现不同、破坏您的配置或引入意外更改。请使用特定标签,如 dpage/pgadmin4:9.13,以确保每位同事运行完全相同的版本。
使用 servers.json 预加载服务器连接
如果整个团队共用同一套 Compose 配置,不要让每个人在启动栈后都手动注册 PostgreSQL 服务器。pgAdmin 支持使用 servers.json 在启动时预填连接。像这样将其挂载进容器:
volumes:
- ./servers.json:/pgadmin4/servers.json
下面是一个最小化的 servers.json 示例:
{
"Servers": {
"1": {
"Name": "local-dev-postgres",
"Group": "Servers",
"Host": "postgres",
"Port": 5432,
"MaintenanceDB": "mydb",
"Username": "admin",
"SSLMode": "prefer"
}
}
}
pgAdmin 启动时会显示该服务器——无需手动设置。
结语
本文带您从零开始在 Docker 中设置 pgAdmin 4。您编写了一个 Docker Compose 文件,让 PostgreSQL 与 pgAdmin 4 一同启动,通过 Docker 的内部 DNS 连接了两个容器,并使用了 pgAdmin 的核心功能——Query Tool、架构浏览器以及备份/恢复流程。
这里的核心原则是可复现性。
一个 docker-compose.yml 文件、一个 servers.json 和一个 .env 文件,就足以让同事拿到一个完整配置好的数据库环境。这样就能彻底避免“只在我机器上能跑”的问题。
想更深入了解 Docker 与容器技术,请查看我们的 Intermediate Docker 课程。课程涵盖多阶段构建、网络,以及对 Compose 的深入讲解,包含大量实用技巧。
Docker pgAdmin 常见问题解答
我能在 Windows 和 macOS 上通过 Docker 运行 pgAdmin 4 吗?
可以。dpage/pgadmin4 镜像可在任何支持 Docker 的操作系统上运行,包括 Windows 和 macOS。其设置流程与 docker-compose.yml 文件在不同平台上完全一致。
每次更新 Docker 镜像都需要重新安装 pgAdmin 4 吗?
不需要。只要将 /var/lib/pgadmin 映射到命名卷,拉取新镜像版本不会影响您保存的数据。您的服务器连接、会话数据和配置会在镜像更新与容器重启后保持不变。
在生产数据库中通过 Docker 使用 pgAdmin 4 是否安全?
在 Docker 中运行的 pgAdmin 4 适用于开发与内部工具,但在指向生产数据库之前必须加固安全。切勿公开暴露 pgAdmin 端口,始终使用 .env 文件或 Docker secrets 管理凭据;如需远程访问,考虑将 pgAdmin 放在带认证的反向代理之后。
为什么在将 pgAdmin 连接到 PostgreSQL 时不能使用 `localhost` 作为主机名?
在 Docker 网络内,localhost 解析为容器本身——不是宿主机,也不是其他容器。Docker 有自己的内部 DNS,会用 docker-compose.yml 中定义的服务名解析容器名。请使用 PostgreSQL 的服务名——通常是 postgres——作为主机名。
pgAdmin 中的 Custom、Plain 与 Tar 备份格式有何区别?
Custom 是压缩的二进制格式,灵活性最高——您可以从中仅恢复单个表,而非整个数据库。Plain 会输出可读的 SQL 脚本,可用任意文本编辑器打开,便于在恢复前审阅或编辑。Tar 是未压缩归档,较少使用,但 pg_restore 支持基于它进行选择性恢复。