Docker-Compose Postgresql 导入转储
Posted
技术标签:
【中文标题】Docker-Compose Postgresql 导入转储【英文标题】:Docker-Compose Postgresql import dump 【发布时间】:2016-10-16 12:13:46 【问题描述】:我有一个关于 docker 和 postgres 的问题。每次 docker 启动并想要导入给定的转储时,我都会设置一个新的 postgres 数据库。
我的问题是这样的,但答案对我来说还不够:Docker postgres does not run init file in docker-entrypoint-initdb.d
Docker 编写:
postgres:
environment:
- POSTGRES_USER=****
- POSTGRES_PASSWORD=****
- POSTGRES_DB=****
build:
context: .
dockerfile: dockerfile-postgres
我的 Dockerfile:(我已经用 .sh 结尾的脚本尝试过)
FROM postgres
ADD dump.sql /docker-entrypoint-initdb.d/
根据https://hub.docker.com/_/postgres/dump.sql 必须使用导入数据库。
使用 docker 启动应用程序只会给出:
postgres_1 | LOG: invalid record length at 0/1708600
postgres_1 | LOG: redo is not required
postgres_1 | LOG: MultiXact member wraparound protections are now enabled
postgres_1 | LOG: database system is ready to accept connections
postgres_1 | LOG: autovacuum launcher started
除了我测试了我的数据库是否已经导入之外,我的数据库中没有表。我在做什么错(文件在目标系统上是读取和可执行的)?用psql导入没问题,所以我的dump是正确的。
我希望你能帮助我,我想提前感谢你。
【问题讨论】:
希望没记错,但ADD
仅在作为Docker COPY vs ADD 中讨论的 URL 时发挥作用。您不想运行pr_restore
并将其提供到您的dump.sql
副本的路径吗? ...但也许 pg_restore
不适用于容器化变体(正如评论 - 18 天前 - 在 postgres docker hub 页面上所暗示的那样)
是的,我考虑过复制到并尝试过,结果相同。该文件在目标中正确。我已经尝试在此文件夹中使用 pqdump 和 sh 脚本。该脚本应该只调用:pg_restore -d databasename /tmp/dump.backup。 pg_restore 本身在目标机器上工作,但脚本没有被执行
我猜这是你想要的 pg_restore - 不要转储数据库中的内容而是填写回来,对吗?
sql 文件或导入转储没有问题,如果手动执行,我的脚本正确导入了它。我的问题是 docker 不会执行它
抱歉,提出以下建议,但是...您是否尝试将其命名为 init.sql
而不是 dump.sql
已经...?那可能是魔术的级别,可能会导致在这样一个魔术文件夹中执行。
【参考方案1】:
好的,我找到了窍门,我必须执行“docker-compose rm”才能执行此文件夹中的脚本和 sql 文件。一旦构建并且未删除,init 文件夹将被忽略。
更新 我又遇到了这个问题,这次删除 docker 创建的图像解决了这个问题。
【讨论】:
请注意,如果您更改了ADD
ed 脚本,则在运行 docker-compose rm
后可能还需要执行 docker-compose build
。
救生员...即使清理所有 docker 图像和图层也不起作用,但这样做了。
因为这似乎是一个常见问题或研究,如果这个答案能更详细一点,将不胜感激【参考方案2】:
这很可能是因为
initdb 脚本docker-entryfile.sh
然后负责按字母顺序运行/docker-entrypoint-initdb.d/*
文件,仅在创建卷时才第一次运行。
你可以看到一些细节here。
解决方案(适用于我) 这是我的 docker-compose 文件中的 sn-p
postgres_service:
build:
context : docker-postgres
dockerfile: Dockerfile-base
image: 'datahub/postgres:development'
user: postgres
ports:
- "5432:5432"
env_file:
- credentials/postgres/development.env
volumes:
- /Users/yogesh.yadav/DockerData/datahub/postgresql/data:/var/lib/postgresql/data
restart: unless-stopped
networks:
- datahubnetwork
步骤 -
1)docker-compose -f docker-compose-filename.yml down
或
docker-compose -f docker-compose-filename.yml stop postgres_service
2) 删除 postgres_service docker 服务附加的卷/卷 ( /Users/yogesh.yadav/DockerData/datahub/postgresql/data )。您可以手动或通过docker-compose rm
或docker volume rm
执行此操作。请在删除之前确定附加到该 postgres 服务的卷。 More info here
3) Docker 通过构建镜像并运行它们来使用非常好的缓存管理。如果您没有修改您的 Dockerfile
,docker 将从缓存中运行已经构建的映像并运行它。所以我建议也删除 postgres_service 的图像。
列出图像
docker images -a
输出 -
REPOSITORY TAG IMAGE ID CREATED SIZE
datahub/postgres development e7707e670ad4 35 minutes ago 265 MB
删除该图像(如果需要,使用 -f)
docker rmi IMAGE_ID_HERE
4) 再次重启服务
docker-compose -f docker-compose-filename.yml up --build postgres_service
这次你可以看到你的docker-entrypoint.sh
和dump.sql
会执行。
【讨论】:
【参考方案3】:这里的答案在一定程度上解决了我的问题,但让docker-entrypoint-initdb/*.sql
脚本正常工作的最后一步是确保 sql 脚本本身没有语法问题(我遇到问题是因为我在 Dockerfile 中更改了 SQL 版本)。
如果有的话,docker-entrypoint-initdb/*.sql
脚本中的所有内容似乎都会回滚。
要检查是否存在任何语法脚本问题(或其他问题),您可能会发现查看 docker 日志很有用:
$ docker ps -all
注意:-all
确保它列出那些可能也无法启动的图像。
找到您刚刚创建的图像并查找应该是 12 个字符哈希的容器 id:
$ docker logs baf32ff7ec03
请记住,您仍然需要遵循此处的其他答案 - 即 rm 先前构建的图像并删除您的数据文件夹(如果需要,请备份它)。
【讨论】:
以上是关于Docker-Compose Postgresql 导入转储的主要内容,如果未能解决你的问题,请参考以下文章
如何从 docker-compose 连接到 Host PostgreSQL?
如何访问使用 docker-compose 设置的 postgresql 数据库?
docker-compose.yml文件中postgresql的连接字符串
Docker-Compose Postgresql 导入转储