【保姆级教程】Docker部署PostgreSQL + pgAdmin,支持远程连接+数据持久化(docker-compose版)
大家好,我是Goya!
今天是Docker部署系列的第四篇文章:用Docker部署PostgreSQL。
PostgreSQL(简称Postgres)被誉为"开发者最爱的数据库",它以功能强大、标准兼容性好著称,是许多大厂的首选。很多开发者说:“用MySQL会了,用Postgres才是真的懂数据库”。
本篇要点:
-
✅ 一分钟启动PostgreSQL容器
-
✅ 设置用户名密码和数据持久化
-
✅ 使用docker-compose一键部署PostgreSQL + pgAdmin
-
✅ 初始化脚本自动创建表和数据
-
✅ 支持远程客户端连接
-
✅ pgAdmin图形化管理界面
-
✅ PostgreSQL vs MySQL核心区别
一、为什么选择PostgreSQL?
| 特性 | PostgreSQL | MySQL |
|---|---|---|
| SQL标准兼容 | ⭐⭐⭐⭐⭐ 高度兼容 | ⭐⭐⭐ 部分扩展 |
| JSON支持 | ⭐⭐⭐⭐⭐ JSONB类型强大 | ⭐⭐ 基础JSON |
| 并发性能 | ⭐⭐⭐⭐⭐ MVCC实现优秀 | ⭐⭐⭐⭐ 还行 |
| GIS地理信息 | ⭐⭐⭐⭐⭐ PostGIS扩展 | ⭐ 需要第三方 |
| 全文检索 | 内置强大 | 需要插件 |
| 适合场景 | 复杂查询、数据分析 | 简单读写、Web应用 |
**一句话总结:**MySQL简单易用,适合CRUD为主的Web应用;PostgreSQL功能强大,适合复杂业务和数据分析。
二、准备工作
2.1 检查Docker环境
docker --version
docker-compose --version
如果没有docker-compose,先安装:
# Ubuntu/Debian系统
apt update
apt install docker-compose -y
2.2 拉取PostgreSQL镜像
docker pull postgres:16
docker pull dpage/pgadmin4
查看镜像:
docker images | grep -E "postgres|pgadmin"
三、创建项目目录
# 创建项目目录
mkdir -p ~/docker/postgres-project
cd ~/docker/postgres-project
# 创建数据目录和初始化脚本目录
mkdir -p postgres/{data,init}
mkdir -p pgadmin
# 设置权限
chmod -R 777 pgadmin
目录结构说明:
~/docker/postgres-project/
├── docker-compose.yml
├── postgres/
│ ├── data/ # 数据库数据文件
│ └── init/ # 初始化脚本
└── pgadmin/ # pgadmin配置文件
四、创建初始化脚本(可选,但推荐)
初始化脚本会在数据库第一次启动时自动执行,非常方便。
vim postgres/init/01-init.sql
粘贴以下内容:
-- 创建UUID扩展(用于生成唯一ID)
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- 创建products表
CREATE TABLE IF NOT EXISTS products (
id SERIAL PRIMARY KEY,
name VARCHAR(200) NOT NULL,
price DECIMAL(10,2),
stock INTEGER DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- 插入测试数据
INSERT INTO products (name, price, stock) VALUES
('手机', 2999.00, 100),
('电脑', 5999.00, 50),
('耳机', 299.00, 200),
('键盘', 199.00, 150),
('鼠标', 89.00, 300);
-- 创建users表(使用UUID)
CREATE TABLE IF NOT EXISTS users (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- 插入测试用户
INSERT INTO users (username, email) VALUES
('zhangsan', 'zhangsan@example.com'),
('lisi', 'lisi@example.com'),
('wangwu', 'wangwu@example.com')
ON CONFLICT (username) DO NOTHING;
-- 创建索引
CREATE INDEX idx_products_name ON products(name);
CREATE INDEX idx_users_username ON users(username);
-- 创建orders表(关联查询示例)
CREATE TABLE IF NOT EXISTS orders (
id SERIAL PRIMARY KEY,
user_id UUID REFERENCES users(id),
product_id INTEGER REFERENCES products(id),
quantity INTEGER NOT NULL,
total_price DECIMAL(10,2),
order_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- 插入一些订单数据
INSERT INTO orders (user_id, product_id, quantity, total_price)
SELECT
u.id,
p.id,
1,
p.price
FROM users u, products p
WHERE u.username = 'zhangsan' AND p.name = '手机'
LIMIT 1;
保存退出(:wq)。
五、编写docker-compose.yml
这是本文的核心!一条命令启动两个服务。
vim docker-compose.yml
粘贴以下内容:
version: '3.8'
services:
# PostgreSQL服务
postgres:
image: postgres:16
container_name: postgres16
restart: always
ports:
- "5432:5432"
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: 123456
POSTGRES_DB: myapp
# 时区设置
TZ: Asia/Shanghai
volumes:
# 数据持久化
- ./postgres/data:/var/lib/postgresql/data
# 初始化脚本
- ./postgres/init:/docker-entrypoint-initdb.d
networks:
- postgres-network
# pgAdmin管理界面
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin
restart: always
ports:
- "5050:80"
environment:
PGADMIN_DEFAULT_EMAIL: admin@admin.com
PGADMIN_DEFAULT_PASSWORD: 123456
# 中文界面
PGADMIN_CONFIG_LANGUAGE: 'zh_CN'
volumes:
- ./pgadmin:/var/lib/pgadmin
depends_on:
- postgres
networks:
- postgres-network
# 定义网络,让容器可以互相通信
networks:
postgres-network:
driver: bridge
配置详解:
| 参数 | 说明 |
|---|---|
ports: - "5432:5432" | 映射PostgreSQL端口 |
POSTGRES_PASSWORD | 设置超级用户密码(必须) |
POSTGRES_USER | 设置超级用户名(默认postgres) |
POSTGRES_DB | 初始化时创建的数据库 |
volumes | 挂载数据目录和初始化脚本 |
depends_on | pgAdmin依赖postgres,会等它启动后再启动 |
六、启动所有服务
cd ~/docker/postgres-project
docker-compose up -d
看到类似输出就成功了:
Creating postgres16 ... done
Creating pgadmin ... done
查看运行状态:
docker-compose ps
应该两个都是Up状态。
查看日志:
docker-compose logs -f
看到database system is ready to accept connections说明PostgreSQL启动成功。
七、验证PostgreSQL
7.1 进入容器连接数据库
# 直接连接
docker-compose exec postgres psql -U admin -d myapp
或者:
docker exec -it postgres16 psql -U admin -d myapp
7.2 验证初始化脚本
看到myapp=#提示符后,执行:
-- 查看所有表
\dt
-- 查询products表
SELECT * FROM products;
-- 查询users表
SELECT * FROM users;
-- 查看关联查询
SELECT
u.username,
p.name as product,
o.quantity,
o.total_price,
o.order_date
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id;
-- 退出
\q
如果能查到数据,说明初始化脚本执行成功!
7.3 测试数据持久化
# 重启容器
docker-compose restart
# 再次连接查看数据
docker-compose exec postgres psql -U admin -d myapp -c "SELECT COUNT(*) FROM products;"
数据应该还在,说明持久化生效。
八、配置pgAdmin图形化管理界面
8.1 访问pgAdmin
打开浏览器,访问:
http://你的服务器IP:5050
登录信息:
-
邮箱:admin@admin.com
-
密码:123456
8.2 添加PostgreSQL服务器
登录后点击 “Add New Server”:
General标签页:
-
Name: 我的PostgreSQL(随便写)
-
Connection标签页(重要):
-
Host name/address:postgres(注意:不是IP,是服务名!)
-
Port:5432
-
Maintenance database: myapp
-
Username:admin
-
Password: 123456
-
Save password: ✅ 勾选
点击 “Save”。
8.3 验证连接成功
如果一切正常,左侧会展开数据库树形结构:
Servers (1)
└── 我的PostgreSQL
├── Databases
│ └── myapp
│ ├── Schemas
│ │ └── public
│ │ ├── Tables
│ │ │ ├── orders
│ │ │ ├── products
│ │ │ └── users
8.4 执行SQL查询
右键点击myapp数据库 → “Query Tool”,执行:
SELECT * FROM products;
就能看到我们初始化插入的数据了!
九、配置远程连接(客户端连接)
9.1 查看服务器IP
curl ifconfig.me
9.2 配置防火墙/安全组
Ubuntu系统(UFW):
ufw allow 5432/tcp
ufw status
云服务器:在安全组中开放5432端口。
9.3 使用客户端连接
推荐客户端:
-
DBeaver(免费,全功能)
-
Navicat(付费,好用)
-
DataGrip(JetBrains出品)
连接信息:
-
**主机:**你的服务器公网IP
-
端口: 5432
-
数据库: myapp
-
用户: admin
-
密码:123456
十、docker-compose常用命令
# 启动所有服务
docker-compose up -d
# 停止所有服务
docker-compose down
# 重启所有服务
docker-compose restart
# 查看实时日志
docker-compose logs -f
# 查看某个服务的日志
docker-compose logs postgres
# 进入容器
docker-compose exec postgres bash
# 执行SQL
docker-compose exec postgres psql -U admin -d myapp -c "SELECT * FROM users;"
# 查看容器状态
docker-compose ps
# 停止并删除容器(数据还在)
docker-compose down
# 停止并删除容器+删除数据卷(谨慎!数据会丢)
docker-compose down -v
十一、备份与恢复
11.1 备份数据库
# 备份整个数据库
docker-compose exec postgres pg_dump -U admin myapp > backup.sql
# 只备份数据(不备份表结构)
docker-compose exec postgres pg_dump -U admin --data-only myapp > data.sql
# 压缩备份
docker-compose exec postgres pg_dump -U admin myapp | gzip > backup.sql.gz
11.2 恢复数据库
# 恢复备份
cat backup.sql | docker-compose exec -T postgres psql -U admin myapp
# 从压缩文件恢复
gunzip -c backup.sql.gz | docker-compose exec -T postgres psql -U admin myapp
十二、常见问题排查
Q1:容器启动失败
# 查看错误日志
docker-compose logs postgres
Q2:pgAdmin连不上postgres
# 测试网络连通性
docker exec -it pgadmin sh
ping postgres
# 按Ctrl+C停止
exit
如果ping不通,检查docker-compose.yml中的网络配置。
Q3:远程连接不上
# 检查端口监听
netstat -tlnp | grep 5432
# 检查防火墙
ufw status
# 进入容器查看PostgreSQL配置
docker exec -it postgres16 bash
cat /var/lib/postgresql/data/postgresql.conf | grep listen
# 应该看到 listen_addresses = '*'
Q4:"关系不存在"错误
表名大小写问题。PostgreSQL对表名大小写敏感:
-- 如果创建时用"Users",查询时必须加引号
SELECT * FROM "Users";
-- 推荐都用小写
SELECT * FROM users;
Q5:容器名冲突
# 查看冲突的容器
docker ps -a | grep postgres16
# 删除旧容器
docker rm -f postgres16
# 重新启动
docker-compose up -d
十三、总结
通过本文,我们成功实现了:
| 功能 | 实现方式 | 验证方法 |
|---|---|---|
| ✅ Docker部署PostgreSQL | docker-compose | docker-compose ps |
| ✅ 设置用户名密码 | 环境变量 | psql登录 |
| ✅ 初始化数据库和表 | 初始化脚本 | SELECT * FROM products; |
| ✅ 数据持久化 | 数据卷挂载 | 重启后数据还在 |
| ✅ pgAdmin图形界面 | docker-compose | 浏览器访问5050端口 |
| ✅ 远程连接 | 端口映射 | DBeaver/Navicat连接 |
| ✅ 备份恢复 | pg_dump命令 | 导出导入测试 |
现在你的服务器上已经有了一整套PostgreSQL数据库环境,既可以命令行操作,也可以用pgAdmin图形化管理!
搞定! 🎯 现在你的服务器上有了:
-
✅ MySQL(关系型数据库)
-
✅ Redis(缓存)
-
✅ Nginx(Web服务器)
-
✅ PostgreSQL(另一个关系型数据库)+ pgAdmin
如果本文对你有帮助,欢迎点赞、收藏、评论!
更多推荐
所有评论(0)