docker-postgres/README.md
2025-11-04 16:09:35 +08:00

250 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PostgreSQL数据库服务
本目录提供了基于Docker的PostgreSQL数据库服务使用direnv和OpenSSL实现安全的密码管理避免在配置文件中硬编码敏感信息。系统采用交互式初始化脚本和统一的服务管理脚本简化了部署和维护流程。
## 目录结构及文件说明
```
├── .envrc # 环境变量配置文件使用direnv管理
├── .gitignore # Git忽略文件配置
├── README.md # 本文档
├── clear # 清理数据库数据的脚本
├── conf/ # PostgreSQL配置文件目录
├── data/ # PostgreSQL数据存储目录
├── docker-compose.yml # Docker Compose配置文件
├── fulldump # 数据库完全备份脚本(支持多数据库备份)
├── init # 交互式初始化配置脚本
├── postgres_password.enc # 加密的数据库密码文件
├── restore # 数据库恢复脚本(支持智能备份选择)
└── service # 统一的服务管理脚本替代原start/stop脚本
```
## 环境要求
### 开发环境
- macOS
- Docker 和 Docker Compose
- direnv (`brew install direnv`)
- OpenSSL
### 生产环境
- 支持主流Linux发行版包括但不限于银河麒麟服务器系统v10、Debian 12等
- Docker 和 Docker Compose自动处理架构兼容性
- direnv (`apt-get install direnv` 或发行版对应包管理器)
- OpenSSL
> **注意**Docker会自动处理ARM和x64架构的兼容性本方案不区分硬件架构
## 使用方法
### 首次使用配置
1. **安装依赖**
macOS:
```bash
# 使用Homebrew
brew install direnv openssl
```
Linux:
```bash
apt-get update
apt-get install direnv openssl
```
2. **执行交互式初始化**
```bash
cd /path/to/server/database
chmod +x init service
./init
```
初始化过程会引导您设置:
- 数据库密码PostgreSQL root密码
- 加密主密钥(用于加密/解密密码文件)
- 服务端口默认为25001
- 容器名称默认为guarddoc-server-postgres
3. **设置文件权限**
```bash
chmod 600 .envrc postgres_password.enc
chmod +x clear fulldump
```
> **注意**:初始化脚本会自动执行`direnv allow`,无需手动操作。如果初始化过程中密码验证失败,脚本会立即停止执行。
### 服务管理命令
使用统一的`service`脚本来管理PostgreSQL服务
```bash
cd /path/to/server/database
# 启动服务
./service start
# 停止服务
./service stop
# 检查服务状态
./service status
# 重启服务
./service restart
# 查看帮助信息
./service help
```
> **注意**:所有命令执行前都需要输入加密主密钥进行验证。如果密码验证失败,命令会立即停止执行。
### 连接数据库
数据库服务使用在初始化过程中指定的端口默认为5432
```bash
# 使用psql客户端连接
psql -h localhost -p 5432 -U postgres
# 输入初始化过程中设置的数据库密码
```
## 安全注意事项
1. **密码管理**
- 数据库密码使用AES-256-CBC加密存储采用PBKDF2密钥派生函数增强安全性
- 主密钥仅保存在用户记忆中,不存储在任何文件中
- 环境变量在离开工作目录时自动清除direnv特性
- 所有服务管理命令都需要密码验证才能执行
2. **文件权限**
- 敏感文件(.envrc, postgres_password.enc)设置严格的600权限
- 容器内数据目录使用PostgreSQL用户权限(700)
3. **注意事项**
- 请妥善保管主密钥,丢失后无法恢复数据库密码
- 定期备份数据库,避免数据丢失
- 不要将.envrc和postgres_password.enc提交到版本控制系统已在.gitignore中配置
## 自定义配置
### 修改现有配置
如果需要修改已初始化的配置:
1. 停止服务:
```bash
./service stop
```
2. 删除现有的配置文件:
```bash
rm -f .envrc postgres_password.enc
```
3. 重新运行初始化脚本:
```bash
./init
```
4. 重新启动服务:
```bash
./service start
```
### 添加自定义PostgreSQL配置
在`conf/`目录下添加配置文件,服务启动时会自动复制到容器内并应用:
```bash
# 示例:修改最大连接数
cat > conf/postgresql.conf << EOF
max_connections = 200
EOF
# 重启服务以应用配置
./service restart
```
## 备份与恢复
### 执行数据库备份
使用`fulldump`脚本进行数据库备份:
```bash
# 备份所有用户数据库排除系统数据库默认清除15天前的备份
./fulldump
# 备份指定数据库默认清除15天前的备份
./fulldump <database_name>
# 备份指定数据库,并清除指定天数前的备份
./fulldump <database_name> <days>
```
备份文件将保存在`data/backup/`目录中,命名格式为`<database_name>_full_<timestamp>`。
### 数据库恢复
使用`restore`脚本从备份恢复数据库:
```bash
# 恢复最新备份到原始数据库(根据备份文件名自动确定目标数据库)
./restore
# 恢复指定数据库的最新备份(优先查找与数据库名匹配的备份)
./restore <database_name>
```
脚本会选择与目标数据库匹配的最新备份文件(如果指定了数据库名),并在恢复前提供确认提示,避免误操作。
### 定时备份
将`fulldump`脚本加入到系统crontab定时任务中实现定时备份
```bash
# 编辑crontab
crontab -e
# 添加以下行每天1点备份所有用户数据库并清除15天前的备份
0 1 * * * bash /path/to/server/database/fulldump 15
# 或者只备份特定数据库
0 1 * * * bash /path/to/server/database/fulldump <database_name> 15
```
## 故障排除
### 常见问题
1. **密码验证失败**
- 错误提示:"错误: POSTGRES_PASSWORD环境变量未设置"
- 解决方案:确保输入正确的加密主密钥
2. **direnv未安装**
- 错误提示:"警告: direnv未安装"
- 解决方案按照环境要求部分安装direnv
- macOS: `brew install direnv`
- Linux: `apt-get install direnv`
3. **容器名称冲突**
- 错误提示:"Error response from daemon: Conflict. The container name ... is already in use"
- 解决方案:使用不同的容器名称重新初始化
4. **端口冲突**
- 错误提示:"Error starting userland proxy: listen tcp4 0.0.0.0:25001: bind: address already in use"
- 解决方案:使用不同的端口重新初始化
## 脚本工具详情
|脚本|作用|用法|
|---|---|---|
|init|交互式初始化数据库配置|./init|
|service|统一服务管理支持start/stop/status/restart|./service [command]|
|fulldump|数据库全量备份|./fulldump [<database>] [<days>]|
|restore|数据库恢复|./restore [<database>]|
|clear|清空所有数据(保留备份目录)|./clear|