Docker运行PostgreSQL时init.sql初始化脚本未执行如何解决
问题原因
PostgreSQL官方Docker镜像的初始化逻辑有固定规则:/docker-entrypoint-initdb.d/目录下的所有脚本(支持.sql/.sh/.sql.gz格式),仅在数据目录/var/lib/postgresql/data完全为空、数据库首次初始化时执行一次。只要该目录下存在已初始化完成的数据库文件,后续不管是重启容器还是重新创建容器,都不会再次触发这些初始化脚本,这是你todos表未创建、插入报错的核心原因。
解决步骤
- 清理旧持久化数据
先停止并删除当前运行的容器,删除本地挂载的数据库数据目录(操作前如果目录内有重要业务数据请先备份):docker compose down rm -rf ./db_data - 校验配置与脚本权限
- 确认
./app/config/init.sql本地路径正确,Linux环境下建议给文件加读权限,避免容器内postgres用户无权限读取导致脚本跳过:chmod +r ./app/config/init.sql - 检查
./app/config/.env文件内的POSTGRES_DB配置值,必须和你healthcheck、业务代码里连接的devdb库名一致。如果未配置该变量,镜像会默认创建名为postgres的库,初始化脚本会默认连到这个库建表,你业务连devdb时自然查不到表。 - 你的compose文件顶层声明的
db_data命名卷未被实际使用,postgres服务当前用的是./db_data绑定挂载,该冗余配置不影响运行,可以删除避免混淆。
- 确认
- 重新启动验证
前台启动容器观察初始化日志,确认脚本执行无报错:
启动完成后新开终端执行命令查表,确认docker compose uptodos表存在:
返回结果中能看到docker compose exec postgres psql -U postgres -d devdb -c "\dt"public.todos表即说明初始化成功,后续业务插入逻辑可正常运行。
补充方案
如果不想清空现有数据库数据重新初始化,可以直接手动执行建表语句补建表结构,不需要删除已有数据:
cat ./app/config/init.sql | docker compose exec -T postgres psql -U postgres -d devdb
执行完成后再查确认表存在即可,你的Go代码里pgx连接、时间参数传递逻辑没有问题,表创建完成后插入不会再报错。
内容的提问来源于stack exchange,提问作者Alpharius
相关产品推荐
相关产品推荐

