如何在Docker容器中通过Bash脚本启动PostgreSQL实例并导入数据
解决方案:PostgreSQL容器启动脚本错误修复
你的问题根源有两个:
su - postgres会启动新的交互式Shell,后续的psql命令仍以root身份执行,且此时PostgreSQL服务并未启动- 未正确启动PostgreSQL服务就尝试用
psql连接
以下是两种可行的修复方案:
方案一:修复启动脚本,手动管理服务生命周期
修改start.sh,确保在postgres用户下启动服务并等待就绪,再执行数据导入:
#!/bin/sh # 复制共享卷文件到当前目录(确保路径正确,注意环境变量的拼接) cp "${SHARED_VOL_SAVE_PATH}/${FILE_NAME}" ./ || exit 1 # 以postgres用户后台启动PostgreSQL服务 su - postgres -c "postgres -D /var/lib/postgresql/data &" # 等待服务就绪(轮询直到能连接) until su - postgres -c "psql -c '\q'"; do echo "等待PostgreSQL服务启动..." sleep 2 done # 执行数据库初始化和数据导入 su - postgres -c "psql -c 'CREATE DATABASE IF NOT EXISTS postgres'" su - postgres -c "psql postgres < ${FILE_NAME}" # 保持容器运行:等待后台postgres进程 wait
方案二:利用官方镜像的初始化机制(推荐)
官方PostgreSQL镜像会自动执行/docker-entrypoint-initdb.d/目录下的脚本,且会自动处理服务启动、用户权限等问题,更符合最佳实践:
1. 修改Dockerfile
FROM postgres:latest # 复制数据导入脚本到官方指定的初始化目录 COPY ./init-db.sh /docker-entrypoint-initdb.d/ # 复制文件复制脚本(如果需要提前处理文件) COPY ./copy-files.sh /db/copy-files.sh EXPOSE 5432 # 使用官方默认CMD启动服务,自动触发初始化脚本 CMD ["postgres"]
2. 新增copy-files.sh(可选,若需提前复制文件)
如果需要在服务启动前先复制共享卷文件,可设置为entrypoint:
#!/bin/sh # 复制文件到postgres可访问的临时目录 cp "${SHARED_VOL_SAVE_PATH}/${FILE_NAME}" /tmp/ || exit 1 # 调用官方入口脚本,继续执行服务启动流程 exec /docker-entrypoint.sh "$@"
此时需要在Dockerfile中替换ENTRYPOINT:
ENTRYPOINT ["bash", "/db/copy-files.sh"]
3. 新增init-db.sh(数据导入逻辑)
#!/bin/sh # 执行数据库创建和数据导入(自动以postgres用户运行) psql -c "CREATE DATABASE IF NOT EXISTS postgres" psql postgres < /tmp/${FILE_NAME}
关键注意事项
- 确保
SHARED_VOL_SAVE_PATH和FILE_NAME环境变量通过.env正确注入容器 - 共享卷文件权限:确保postgres用户(UID 999)能读取文件,可在
fetch服务中设置文件权限为chown 999:999 /data_dumps/${FILE_NAME} - 方案二无需手动处理服务启动和等待逻辑,稳定性更高,推荐使用
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

