You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Docker容器中通过Bash脚本启动PostgreSQL实例并导入数据

解决方案:PostgreSQL容器启动脚本错误修复

你的问题根源有两个:

  1. su - postgres 会启动新的交互式Shell,后续的psql命令仍以root身份执行,且此时PostgreSQL服务并未启动
  2. 未正确启动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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:03:21