我有一个Docker容器包含我的Postgres数据库,它使用的是官方的Postgres image,它有一个CMD条目,在主线程上启动服务器。
我想在数据库开始侦听查询之前运行RUN psql –U postgres postgres < /dump/dump.sql
来填充数据库。
我不明白Docker怎么可能做到这一点。如果我把RUN
命令放在CMD之后,它当然永远不会被执行,因为Docker已经完成了对Docker文件的阅读。但是如果我把它放在CMD
之前,它甚至会在psql作为一个进程存在之前运行。
如何在Docker中预填充Postgres数据库?
9条答案
按热度按时间bq9c1y661#
经过大量的斗争,我已经找到了解决办法;-)
对我来说是非常有用的评论张贴在这里:来自"刚刚动摇"
不管怎样,我是这样做的:
db/structure.sql
是一个sql转储,用于初始化第一个表空间。然后,
init_docker_postgres.sh
最后:
希望能有所帮助!
wf82jlnq2#
对于那些希望在第一次运行时使用数百万条记录初始化PostgreSQL DB的用户。
使用 *. sql转储导入
您可以执行简单的sql转储并将
dump.sql
文件复制到/docker-entrypoint-initdb.d/
中。问题是速度。我的dump.sql
脚本大约是17MB(小型DB-10表,其中只有一个表中有100k行),并且初始化需要一分钟(!)。这对于本地开发/单元测试等来说是不可接受的。使用二进制转储导入
解决方案是创建一个二进制PostgreSQL转储文件,并使用shell脚本初始化支持。然后相同的数据库在大约500ms内初始化,而不是1分钟。
dump.pgdata
二进制转储或从主机运行容器(* postgres-container *)
一个一个二个一个一个一个三个一个一个一个一个一个一个四个一个一个一个一个一个五个一个
svmlkihl3#
或者,您可以将一个卷装载到包含所有DDL脚本的/docker-entrypoint-initdb.d/中,您可以将其放入***.sh、*.sql或 *.sql.gz**文件中,它将负责在启动时执行这些文件。
例如(假设您的脚本位于/tmp/my_scripts中)
kiayqfof4#
utilises Flocker还有另一个可用选项:
Flocker是一个容器数据卷管理器,旨在允许PostgreSQL等数据库在生产环境中的容器中轻松运行。在生产环境中运行数据库时,您必须考虑从主机故障中恢复等问题。Flocker提供了跨计算机群集管理数据卷的工具,就像您在生产环境中一样。例如,当Postgres容器在主机之间调度以响应服务器故障时,Flocker可以同时在主机之间自动移动其关联的数据卷。2这意味着当您的Postgres容器在新主机上启动时,该操作可以使用Flocker API或CLI手动完成,也可以通过与Flocker集成的容器编排工具(例如Docker Swarm、Kubernetes或Mesos)自动完成。
e5nszbig5#
我遵循相同的解决方案@damoiser,唯一不同的情况是我想导入所有转储数据.
请按照下面的解决方案操作。(我没有做任何检查)
Dockerfile
那么
init_docker_postgres.sh
脚本然后你就可以把你的形象
mnowg1ta6#
我的解决方案灵感来自亚历克斯·德格兹的答案,不幸的是不工作,因为我:
1.我使用pg-9.6基础映像,
RUN /docker-entrypoint.sh --help
对我来说从来没有跑过,这总是抱怨与The command '/bin/sh -c /docker-entrypoint.sh -' returned a non-zero code: 1
1.我不想污染
/docker-entrypoint-initdb.d
目录下面的答案来自我在另一篇文章中的回复:https://stackoverflow.com/a/59303962/4440427。应该注意,该解决方案用于从二进制转储中恢复,而不是从OP要求的纯SQL中恢复。但是,可以稍微修改该解决方案以适应纯SQL情况
停靠文件:
其中
wait-for-pg-isready.sh
为:上述脚本以及更详细的自述文件可在https://github.com/cobrainer/pg-docker-with-restored-db上获得
gzszwxb47#
我可以通过在docker文件中使用/etc/init.d/postgresql预挂起run命令来加载数据。我的docker文件包含以下行,这对我来说是有效的:
xbp102n08#
对于E2E测试,我们需要一个结构和数据已保存在Docker映像中的数据库,我们已执行以下操作:
停靠文件:
数据库_恢复. sh:
要创建映像:
要启动容器:
这不会在每次启动container时恢复数据库。数据库的结构和数据已包含在创建的Docker映像中。
我们已经在此基础上进行了文章,但剔除了多阶段:Creating Fast, Lightweight Testing Databases in Docker
yhuiod9q9#
我的目标是拥有一个包含数据库的映像--也就是说,节省每次执行
docker run
命令时重建数据库的时间。我们只需要设法从
docker-entrypoint.sh
中取出exec "$@"
行,所以我在Dockerfile
中添加了: