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 创建的图像解决了这个问题。

【讨论】:

请注意,如果您更改了 ADDed 脚本,则在运行 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 rmdocker 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.shdump.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 导入转储

Postgresql容器未在docker-compose文件中运行-这是为什么?

docker-compose 安装postgres(设置默认用户名,密码,暴露端口)