CentOS 7 (arm) Docker 下 PostgreSQL 14 + PostGIS 3.2.3 安装、备份
·
1. 说明
- 之前使用的是 CentOS 7 和 Ubuntu,架构都是 x86_64。采用 本机安装 + 打快照 的方式来部署 PostgreSQL + PostGIS,用起来一直挺稳定。
- 这次换成了 CentOS 7 AltArch 架构,本来以为照旧从 PostgreSQL 官网安装就行,结果在装 PostGIS 的时候遇到了很多依赖缺失的问题。查了一圈资料后才发现,是因为 ARM 架构的依赖包更新不太及时。折腾了好一阵子还是没解决,最后干脆改成 容器化安装 PostgreSQL + PostGIS,也避免了依赖问题。
2. 介绍
- 镜像网址: 渡渡鸟


3. 启动脚本
启动脚本
/home/startup.sh
启动后,如果镜像不存在他会先进行拉取镜像,再进行程序的启动
启动镜像如果权限不够,可以执行chmod给启动脚本修改权限
#!/bin/bash
# Docker 镜像和容器名称
PROJECT_NAME=postgresql-14
DOCKER_IMAGE="swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/kartoza/postgis:14-3.3-linuxarm64"
CONTAINER_NAME="postgresql-14"
PROJECT_LOGS="docker_logs.txt"
# 判断容器是否正在运行
isExist(){
# 查找容器是否正在运行
container_id=$(docker ps -q -f name=${CONTAINER_NAME})
if [ -z "$container_id" ]; then
return 0 # 不存在
else
return 1 # 存在
fi
}
# 获取容器的状态
get_status(){
container_status=$(docker inspect --format '{{.State.Status}}' ${CONTAINER_NAME})
echo "Container ${CONTAINER_NAME} status: ${container_status}"
}
# 删除日志文件
deletelog(){
echo "日志文件:${PROJECT_LOGS}"
if [ -f "${PROJECT_LOGS}" ]; then
echo "日志文件存在, 删除日志文件"
# rm -f ${PROJECT_LOGS}
else
echo "日志文件不存在"
fi
}
# 启动 Docker 容器
start(){
# 检查容器是否已经在运行
isExist
if [ $? -eq "0" ]; then
echo "启动 ${CONTAINER_NAME} 容器..."
docker run -d --name ${CONTAINER_NAME} \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASS=postgres \
-e ALLOW_IP_RANGE=0.0.0.0/0 \
-v /home/docker:/var/lib/postgresql \
-p 5432:5432 \
--restart=always \
${DOCKER_IMAGE}
echo "${CONTAINER_NAME} 启动成功"
else
echo "${CONTAINER_NAME} 容器已经在运行"
fi
}
# 停止 Docker 容器
stop(){
# 检查容器是否在运行
isExist
if [ $? -eq "0" ]; then
echo "${CONTAINER_NAME} 容器未运行"
else
echo "停止 ${CONTAINER_NAME} 容器..."
docker stop ${CONTAINER_NAME}
docker rm ${CONTAINER_NAME}
echo "${CONTAINER_NAME} 容器停止并删除成功"
fi
}
# 重启 Docker 容器
restart(){
stop
start
}
# 查看容器状态
status(){
get_status
}
# 查看容器日志
logs(){
echo "查看容器日志"
docker logs -f ${CONTAINER_NAME}
}
# 设置容器自启动
set_autostart(){
# 检查容器是否已经存在
isExist
if [ $? -eq "0" ]; then
echo "容器 ${CONTAINER_NAME} 尚未启动,无法设置自启动"
start
fi
# 获取容器的当前重启策略
current_restart_policy=$(docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' ${CONTAINER_NAME})
# 判断是否已设置为 'always'
if [ "$current_restart_policy" == "always" ]; then
echo "${CONTAINER_NAME} 已经设置为自启动,取消自启动..."
docker update --restart=no ${CONTAINER_NAME}
echo "${CONTAINER_NAME} 已取消自启动"
else
echo "容器 ${CONTAINER_NAME} 没有自启动设置,设置为自启动..."
docker update --restart=always ${CONTAINER_NAME}
echo "${CONTAINER_NAME} 自启动设置成功"
fi
}
# 全部操作(停止 + 删除日志文件 + 启动容器)
all(){
stop
deletelog
start
}
# 帮助信息
help(){
echo "
====================================================================================================
## Postres 容器操作脚本
脚本输入格式为
bash> ./startup.sh [command]
command 的命令 start | stop | restart | status | logs | all | deletelog | set_autostart
1. start 启动 PostGres 容器
2. stop 停止 PostGres 容器
3. restart 重启 PostGres 容器
4. status 查看 PostGres 容器状态
5. logs 查看 PostGres 容器日志
6. all stop + deletelog + start
7. deletelog 删除日志文件
8. set_autostart 设置容器自启动(启用或取消)
========================================================================================================="
}
# 根据用户输入执行对应操作
case "$1" in
"start")
start
;;
"stop")
stop
;;
"restart")
restart
;;
"status")
status
;;
"logs")
logs
;;
"all")
all
;;
"deletelog")
deletelog
;;
"set_autostart")
set_autostart
;;
"help")
help
;;
*)
echo "请使用正确的命令: start | stop | restart | status | logs | all | deletelog | set_autostart"
;;
esac
- 启动后

4. 备份
- 为了保证数据安装性,对数据进行备份
- 这边采用的是
crontab+备份脚本+定时推送+定期清除数据进行数据的冗余备份- 本地保存
7天,历史数据库备份默认是30天,- 这里只对
crontab和备份脚本进行展开说明,另外两个是通过程序进行动态控制的,这样可以记录系统操作定时推送和定期清除数据也可以采用脚本的方式进行实现,替代如下
- 定时推送 => [
scp|ftp|rsync] +crontab实现- 定期清除数据 =>
rm+crontab实现
- 备份脚本
#!/bin/bash
# PostgreSQL Docker 容器数据库备份与还原脚本
# 使用方式:
# ./pg_backup.sh backup <数据库名>
# ./pg_backup.sh restore <数据库名> [备份文件名]
# ===== 配置区 =====
CONTAINER_NAME="postgresql-14" # 容器名
PGUSER="postgres" # 用户
PGHOST="127.0.0.1" # 主机
PGPASSWORD="postgres" # 密码
PGDATA_DIR="/var/lib/postgresql/dump" # 容器内目录(映射到宿主机 /home/docker)
LOCAL_DIR="/home/docker/dump" # 宿主机目录
# ==================
ACTION=$1
DBNAME=$2
FILENAME=$3
# 备份
backup(){
if [ -z "$DBNAME" ]; then
echo "❌ 缺少数据库名"
echo "用法: $0 backup <数据库名>"
exit 1
fi
FILE="${DBNAME}_$(date +%Y%m%d_%H%M%S).dump"
echo "开始备份数据库 ${DBNAME} 到 ${LOCAL_DIR}/${FILE} ..."
docker exec -e PGPASSWORD=$PGPASSWORD -i $CONTAINER_NAME \
pg_dump -h $PGHOST -U $PGUSER -F c -d $DBNAME \
-f $PGDATA_DIR/$FILE
if [ $? -eq 0 ]; then
echo "✅ 备份成功: ${LOCAL_DIR}/${FILE}"
else
echo "❌ 备份失败"
fi
}
# 还原
restore(){
if [ -z "$DBNAME" ]; then
echo "❌ 缺少数据库名"
echo "用法: $0 restore <数据库名> [备份文件名]"
exit 1
fi
if [ -z "$FILENAME" ]; then
FILE=$(ls -t ${LOCAL_DIR}/${DBNAME}_*.dump 2>/dev/null | head -1)
if [ -z "$FILE" ]; then
echo "❌ 未找到 ${LOCAL_DIR}/${DBNAME}_*.dump 文件"
exit 1
fi
else
FILE="${LOCAL_DIR}/${FILENAME}"
if [ ! -f "$FILE" ]; then
echo "❌ 指定的文件不存在: $FILE"
exit 1
fi
fi
BASENAME=$(basename $FILE)
echo "开始将 ${FILE} 还原到数据库 ${DBNAME} ..."
# 创建数据库(已存在忽略错误)
docker exec -e PGPASSWORD=$PGPASSWORD -i $CONTAINER_NAME \
createdb -h $PGHOST -U $PGUSER $DBNAME 2>/dev/null || true
# 执行还原
docker exec -e PGPASSWORD=$PGPASSWORD -i $CONTAINER_NAME \
pg_restore -h $PGHOST -U $PGUSER -d $DBNAME -v $PGDATA_DIR/$BASENAME
if [ $? -eq 0 ]; then
echo "✅ 还原成功: ${DBNAME}"
else
echo "❌ 还原失败"
fi
}
# 帮助信息
help(){
echo "
====================================================================================================
## PostgreSQL 备份还原脚本
用法:
./pg_backup.sh backup <数据库名>
→ 备份指定数据库到 ${LOCAL_DIR}/下
./pg_backup.sh restore <数据库名> [备份文件名]
→ 还原到指定数据库
→ 如果不指定文件名,则自动选择最新的备份
命令说明:
1. backup 备份数据库
2. restore 还原数据库
3. help 显示帮助
===================================================================================================="
}
# 根据用户输入执行对应操作
case "$ACTION" in
"backup")
backup
;;
"restore")
restore
;;
"help")
help
;;
*)
echo "请使用正确的命令: backup | restore | help"
;;
esac
- crontab
## 执行这一句进入定时任务
crontab -e
两种备份方式
##第一种: 每天 1点的进行 备份
0 1 * * * /bin/bash /home/backup_restore.sh backup database
##第二种: 每天 1点的进行 备份 + 传输 + 日志记录
## 0 1 * * * /bin/bash /home/backup_restore.sh backup database && /bin/bash /home/backup_scp.sh >> /home/backup_scp_cron.log 2>&1

5. 问题
在测试容器化安装是否有无问题的时候,查询当前时间,服务器 和 容器内 的时间不一致,存在 8 小时时差
解决方法如下
## 先进入容器,再进入数据库,
## 指定数据库:命令行执行下面两行指令
## 退出容器,重启容器 就可以解决时差问题
ALTER SYSTEM SET timezone = 'Asia/Shanghai';
ALTER SYSTEM SET log_timezone = 'Asia/Shanghai';
更多推荐
所有评论(0)